summaryrefslogtreecommitdiffstats
path: root/remoting/client/plugin
diff options
context:
space:
mode:
authorgarykac@chromium.org <garykac@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-08 17:51:47 +0000
committergarykac@chromium.org <garykac@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-08 17:51:47 +0000
commit376dea2176504ad886c68110aff882a113807467 (patch)
tree3d835427a52ee536c72ae6fbe74124dec38c6a9c /remoting/client/plugin
parent02d08e07d137b394792d15b712d029455713b195 (diff)
downloadchromium_src-376dea2176504ad886c68110aff882a113807467.zip
chromium_src-376dea2176504ad886c68110aff882a113807467.tar.gz
chromium_src-376dea2176504ad886c68110aff882a113807467.tar.bz2
Hook up communication between Chromoting plugin and JS so that it can notify the JS UI of status changes.
Push SetState handling down ChromotingView so that UI changes are contained in the View. BUG=54855 TEST=chromoting unittests Review URL: http://codereview.chromium.org/3446020 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@61977 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'remoting/client/plugin')
-rw-r--r--remoting/client/plugin/chromoting_instance.cc28
-rw-r--r--remoting/client/plugin/chromoting_instance.h10
-rw-r--r--remoting/client/plugin/chromoting_scriptable_object.cc75
-rw-r--r--remoting/client/plugin/chromoting_scriptable_object.h63
-rw-r--r--remoting/client/plugin/pepper_view.cc31
-rw-r--r--remoting/client/plugin/pepper_view.h1
6 files changed, 180 insertions, 28 deletions
diff --git a/remoting/client/plugin/chromoting_instance.cc b/remoting/client/plugin/chromoting_instance.cc
index 142d9d5..2f61c92 100644
--- a/remoting/client/plugin/chromoting_instance.cc
+++ b/remoting/client/plugin/chromoting_instance.cc
@@ -93,10 +93,23 @@ void ChromotingInstance::Connect(const ClientConfig& config) {
// Kick off the connection.
client_->Start();
+
+ GetScriptableObject()->SetConnectionInfo(STATUS_INITIALIZING,
+ QUALITY_UNKNOWN);
+}
+
+void ChromotingInstance::Disconnect() {
+ DCHECK(CurrentlyOnPluginThread());
+
+ if (client_.get()) {
+ client_->Stop();
+ }
+
+ GetScriptableObject()->SetConnectionInfo(STATUS_CLOSED, QUALITY_UNKNOWN);
}
void ChromotingInstance::ViewChanged(const pp::Rect& position,
- const pp::Rect& clip) {
+ const pp::Rect& clip) {
DCHECK(CurrentlyOnPluginThread());
// TODO(ajwong): This is going to be a race condition when the view changes
@@ -154,13 +167,22 @@ bool ChromotingInstance::HandleInputEvent(const PP_InputEvent& event) {
return false;
}
+ChromotingScriptableObject* ChromotingInstance::GetScriptableObject() {
+ pp::Var object = GetInstanceObject();
+ if (!object.is_undefined()) {
+ pp::deprecated::ScriptableObject* so = object.AsScriptableObject();
+ DCHECK(so != NULL);
+ return static_cast<ChromotingScriptableObject*>(so);
+ }
+ LOG(ERROR) << "Unable to get ScriptableObject for Chromoting plugin.";
+ return NULL;
+}
+
pp::Var ChromotingInstance::GetInstanceObject() {
- LOG(ERROR) << "Getting instance object.";
if (instance_object_.is_undefined()) {
ChromotingScriptableObject* object = new ChromotingScriptableObject(this);
object->Init();
- LOG(ERROR) << "Object initted.";
// The pp::Var takes ownership of object here.
instance_object_ = pp::Var(object);
}
diff --git a/remoting/client/plugin/chromoting_instance.h b/remoting/client/plugin/chromoting_instance.h
index 6c9d7c0..df1db9f 100644
--- a/remoting/client/plugin/chromoting_instance.h
+++ b/remoting/client/plugin/chromoting_instance.h
@@ -14,6 +14,7 @@
#include "base/scoped_ptr.h"
#include "remoting/client/client_context.h"
#include "remoting/client/host_connection.h"
+#include "remoting/client/plugin/chromoting_scriptable_object.h"
#include "third_party/ppapi/c/pp_instance.h"
#include "third_party/ppapi/c/pp_rect.h"
#include "third_party/ppapi/c/pp_resource.h"
@@ -52,11 +53,15 @@ class ChromotingInstance : public pp::Instance {
virtual bool Init(uint32_t argc, const char* argn[], const char* argv[]);
virtual void Connect(const ClientConfig& config);
virtual bool HandleInputEvent(const PP_InputEvent& event);
+ virtual void Disconnect();
virtual pp::Var GetInstanceObject();
virtual void ViewChanged(const pp::Rect& position, const pp::Rect& clip);
virtual bool CurrentlyOnPluginThread() const;
+ // Convenience wrapper to get the ChromotingScriptableObject.
+ ChromotingScriptableObject* GetScriptableObject();
+
private:
FRIEND_TEST_ALL_PREFIXES(ChromotingInstanceTest, TestCaseSetup);
@@ -74,7 +79,10 @@ class ChromotingInstance : public pp::Instance {
scoped_ptr<RectangleUpdateDecoder> rectangle_decoder_;
scoped_ptr<InputHandler> input_handler_;
scoped_ptr<ChromotingClient> client_;
- pp::Var instance_object_; // JavaScript interface to control this instance.
+
+ // JavaScript interface to control this instance.
+ // This wraps a ChromotingScriptableObject in a pp::Var.
+ pp::Var instance_object_;
DISALLOW_COPY_AND_ASSIGN(ChromotingInstance);
};
diff --git a/remoting/client/plugin/chromoting_scriptable_object.cc b/remoting/client/plugin/chromoting_scriptable_object.cc
index a54b39a..1bc909b 100644
--- a/remoting/client/plugin/chromoting_scriptable_object.cc
+++ b/remoting/client/plugin/chromoting_scriptable_object.cc
@@ -12,6 +12,10 @@
using pp::Var;
namespace remoting {
+
+const char kStatusAttribute[] = "status";
+const char kQualityAttribute[] = "quality";
+
ChromotingScriptableObject::ChromotingScriptableObject(
ChromotingInstance* instance)
: instance_(instance) {
@@ -23,15 +27,27 @@ ChromotingScriptableObject::~ChromotingScriptableObject() {
void ChromotingScriptableObject::Init() {
// Property addition order should match the interface description at the
// top of chromoting_scriptable_object.h.
- AddAttribute("onreadystatechange", Var());
- AddAttribute("NOT_CONNECTED", Var(0));
- AddAttribute("CONNECTED", Var(1));
+ // Connection status.
+ AddAttribute(kStatusAttribute, Var(STATUS_UNKNOWN));
+ // Connection status values.
+ AddAttribute("STATUS_UNKNOWN", Var(STATUS_UNKNOWN));
+ AddAttribute("STATUS_CONNECTING", Var(STATUS_CONNECTING));
+ AddAttribute("STATUS_INITIALIZING", Var(STATUS_INITIALIZING));
+ AddAttribute("STATUS_CONNECTED", Var(STATUS_CONNECTED));
+ AddAttribute("STATUS_CLOSED", Var(STATUS_CLOSED));
+ AddAttribute("STATUS_FAILED", Var(STATUS_FAILED));
- AddMethod("connect", &ChromotingScriptableObject::DoConnect);
+ // Connection quality.
+ AddAttribute(kQualityAttribute, Var(QUALITY_UNKNOWN));
+ AddAttribute("QUALITY_UNKNOWN", Var(QUALITY_UNKNOWN));
+ AddAttribute("QUALITY_GOOD", Var(QUALITY_GOOD));
+ AddAttribute("QUALITY_BAD", Var(QUALITY_BAD));
- // TODO(ajwong): Figure out how to implement the status variable.
- AddAttribute("status", Var("not_implemented_yet"));
+ AddAttribute("connectionInfoUpdate", Var());
+
+ AddMethod("connect", &ChromotingScriptableObject::DoConnect);
+ AddMethod("disconnect", &ChromotingScriptableObject::DoDisconnect);
}
bool ChromotingScriptableObject::HasProperty(const Var& name, Var* exception) {
@@ -99,7 +115,7 @@ void ChromotingScriptableObject::GetAllPropertyNames(
void ChromotingScriptableObject::SetProperty(const Var& name,
const Var& value,
Var* exception) {
- // TODO(ajwong): Check if all these name.is_string() sentinels are required.
+ // TODO(ajwong): Check if all these name.is_string() sentinels are required. 120 // No externally settable properties for Chromoting.
if (!name.is_string()) {
*exception = Var("SetProperty expects a string for the name.");
return;
@@ -108,7 +124,7 @@ void ChromotingScriptableObject::SetProperty(const Var& name,
// Only allow writing to onreadystatechange. See top of
// chromoting_scriptable_object.h for the object interface definition.
std::string property_name = name.AsString();
- if (property_name != "onstatechange") {
+ if (property_name != "connectionInfoUpdate") {
*exception =
Var("Cannot set property " + property_name + " on this object.");
return;
@@ -131,6 +147,22 @@ Var ChromotingScriptableObject::Call(const Var& method_name,
return (this->*(properties_[iter->second].method))(args, exception);
}
+void ChromotingScriptableObject::SetConnectionInfo(ConnectionStatus status,
+ ConnectionQuality quality) {
+ int status_index = property_names_[kStatusAttribute];
+ int quality_index = property_names_[kQualityAttribute];
+
+ if (properties_[status_index].attribute.AsInt() != status ||
+ properties_[quality_index].attribute.AsInt() != quality) {
+ // Update the connection state properties..
+ properties_[status_index].attribute = Var(status);
+ properties_[quality_index].attribute = Var(quality);
+
+ // Signal the Chromoting Tab UI to get the update connection state values.
+ SignalConnectionInfoChange();
+ }
+}
+
void ChromotingScriptableObject::AddAttribute(const std::string& name,
Var attribute) {
property_names_[name] = properties_.size();
@@ -143,10 +175,27 @@ void ChromotingScriptableObject::AddMethod(const std::string& name,
properties_.push_back(PropertyDescriptor(name, handler));
}
+void ChromotingScriptableObject::SignalConnectionInfoChange() {
+ pp::Var exception;
+
+ // The JavaScript callback function is the 'callback' property on the
+ // 'connectionInfoUpdate' object.
+ Var cb = GetProperty(Var("connectionInfoUpdate"), &exception);
+
+ // Var() means call the object directly as a function rather than calling
+ // a method in the object.
+ cb.Call(Var(), 0, NULL, &exception);
+
+ if (!exception.is_undefined()) {
+ LOG(WARNING) << "Exception when invoking JS callback"
+ << exception.AsString();
+ }
+}
+
pp::Var ChromotingScriptableObject::DoConnect(const std::vector<Var>& args,
- Var* exception) {
+ Var* exception) {
if (args.size() != 3) {
- *exception = Var("Usage: connect(username, host_jid, auth_token");
+ *exception = Var("Usage: connect(username, host_jid, auth_token)");
return Var();
}
@@ -175,4 +224,10 @@ pp::Var ChromotingScriptableObject::DoConnect(const std::vector<Var>& args,
return Var();
}
+pp::Var ChromotingScriptableObject::DoDisconnect(const std::vector<Var>& args,
+ Var* exception) {
+ instance_->Disconnect();
+ return Var();
+}
+
} // namespace remoting
diff --git a/remoting/client/plugin/chromoting_scriptable_object.h b/remoting/client/plugin/chromoting_scriptable_object.h
index 8c30da0..c317f57 100644
--- a/remoting/client/plugin/chromoting_scriptable_object.h
+++ b/remoting/client/plugin/chromoting_scriptable_object.h
@@ -6,25 +6,33 @@
// The Javascript API is defined as follows.
//
// interface ChromotingScriptableObject {
-// // Called when the Chromoting instance has had a state change such as
-// // connection completed.
-// attribute Function onreadystatechange;
//
-// // Constants for states, etc.
-// const unsigned short NOT_CONNECTED = 0;
-// const unsigned short CONNECTED = 1;
+// // Connection status.
+// readonly attribute unsigned short connection_status;
+
+// // Constants for connection status.
+// const unsigned short STATUS_UNKNOWN = 0;
+// const unsigned short STATUS_CONNECTING = 1;
+// const unsigned short STATUS_INITIALIZING = 2;
+// const unsigned short STATUS_CONNECTED = 3;
+// const unsigned short STATUS_CLOSED = 4;
+// const unsigned short STATUS_FAILED = 5;
+//
+// // Connection quality.
+// readonly attribute unsigned short connection_quality;
+// // Constants for connection quality
+// const unsigned short QUALITY_UNKNOWN = 0;
+// const unsigned short QUALITY_GOOD = 1;
+// const unsigned short QUALITY_BAD = 2;
+//
+// // JS callback function so we can signal the JS UI when the connection
+// // status has been updated.
+// attribute Function connectionInfoUpdate;
//
// // Methods on the object.
// void connect(string username, string host_jid, string auth_token);
-//
-// // Attributes.
-// readonly attribute unsigned short status;
+// void disconnect();
// }
-//
-// onreadystatechange
-//
-// Methods:
-// Connect(username, auth_token, host_jid, onstatechange);
#ifndef REMOTING_CLIENT_PLUGIN_CHROMOTING_SCRIPTABLE_OBJECT_H_
#define REMOTING_CLIENT_PLUGIN_CHROMOTING_SCRIPTABLE_OBJECT_H_
@@ -40,6 +48,25 @@ namespace remoting {
class ChromotingInstance;
+extern const char kStatusAttribute[];
+
+enum ConnectionStatus {
+ STATUS_UNKNOWN = 0,
+ STATUS_CONNECTING,
+ STATUS_INITIALIZING,
+ STATUS_CONNECTED,
+ STATUS_CLOSED,
+ STATUS_FAILED,
+};
+
+extern const char kQualityAttribute[];
+
+enum ConnectionQuality {
+ QUALITY_UNKNOWN = 0,
+ QUALITY_GOOD,
+ QUALITY_BAD,
+};
+
class ChromotingScriptableObject : public pp::deprecated::ScriptableObject {
public:
explicit ChromotingScriptableObject(ChromotingInstance* instance);
@@ -60,6 +87,8 @@ class ChromotingScriptableObject : public pp::deprecated::ScriptableObject {
const std::vector<pp::Var>& args,
pp::Var* exception);
+ void SetConnectionInfo(ConnectionStatus status, ConnectionQuality quality);
+
private:
typedef std::map<std::string, int> PropertyNameMap;
typedef pp::Var (ChromotingScriptableObject::*MethodHandler)(
@@ -84,10 +113,16 @@ class ChromotingScriptableObject : public pp::deprecated::ScriptableObject {
};
+ // Routines to add new attribute, method properties.
void AddAttribute(const std::string& name, pp::Var attribute);
void AddMethod(const std::string& name, MethodHandler handler);
+ // This should be called to signal the JS code that the connection status has
+ // changed.
+ void SignalConnectionInfoChange();
+
pp::Var DoConnect(const std::vector<pp::Var>& args, pp::Var* exception);
+ pp::Var DoDisconnect(const std::vector<pp::Var>& args, pp::Var* exception);
PropertyNameMap property_names_;
std::vector<PropertyDescriptor> properties_;
diff --git a/remoting/client/plugin/pepper_view.cc b/remoting/client/plugin/pepper_view.cc
index eacb37d..9a10d1a 100644
--- a/remoting/client/plugin/pepper_view.cc
+++ b/remoting/client/plugin/pepper_view.cc
@@ -135,6 +135,37 @@ void PepperView::UnsetSolidFill() {
is_static_fill_ = false;
}
+void PepperView::SetConnectionState(ConnectionState state) {
+ if (!instance_->CurrentlyOnPluginThread()) {
+ RunTaskOnPluginThread(
+ NewRunnableMethod(this, &PepperView::SetConnectionState, state));
+ return;
+ }
+
+ ChromotingScriptableObject* scriptable_obj = instance_->GetScriptableObject();
+ switch (state) {
+ case CREATED:
+ SetSolidFill(kCreatedColor);
+ scriptable_obj->SetConnectionInfo(STATUS_CONNECTING, QUALITY_UNKNOWN);
+ break;
+
+ case CONNECTED:
+ UnsetSolidFill();
+ scriptable_obj->SetConnectionInfo(STATUS_CONNECTED, QUALITY_UNKNOWN);
+ break;
+
+ case DISCONNECTED:
+ SetSolidFill(kDisconnectedColor);
+ scriptable_obj->SetConnectionInfo(STATUS_CLOSED, QUALITY_UNKNOWN);
+ break;
+
+ case FAILED:
+ SetSolidFill(kFailedColor);
+ scriptable_obj->SetConnectionInfo(STATUS_FAILED, QUALITY_UNKNOWN);
+ break;
+ }
+}
+
void PepperView::SetViewport(int x, int y, int width, int height) {
if (!instance_->CurrentlyOnPluginThread()) {
RunTaskOnPluginThread(NewTracedMethod(this, &PepperView::SetViewport,
diff --git a/remoting/client/plugin/pepper_view.h b/remoting/client/plugin/pepper_view.h
index 95c180d..80ce1ae 100644
--- a/remoting/client/plugin/pepper_view.h
+++ b/remoting/client/plugin/pepper_view.h
@@ -41,6 +41,7 @@ class PepperView : public ChromotingView,
virtual void Paint();
virtual void SetSolidFill(uint32 color);
virtual void UnsetSolidFill();
+ virtual void SetConnectionState(ConnectionState state);
virtual void SetViewport(int x, int y, int width, int height);
// FrameConsumer implementation.