summaryrefslogtreecommitdiffstats
path: root/ppapi/cpp
diff options
context:
space:
mode:
authordmichael@google.com <dmichael@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-23 21:07:15 +0000
committerdmichael@google.com <dmichael@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-23 21:07:15 +0000
commit9888f134c655a95c5922c980eb59d3337341d653 (patch)
tree8ec7b6849cd94196df9bf3ee7810f6a838242e8d /ppapi/cpp
parent2752bf6a3120e172d216ab7bde42222a3ae4b5cb (diff)
downloadchromium_src-9888f134c655a95c5922c980eb59d3337341d653.zip
chromium_src-9888f134c655a95c5922c980eb59d3337341d653.tar.gz
chromium_src-9888f134c655a95c5922c980eb59d3337341d653.tar.bz2
A proposal and implementation for an initial postMessage interface. These interfaces will allow JavaScript to send data asynchronously to a module instance, and the module instance to asynchronously send data to a JavaScript message handler.
Note, I did something differently from other per-instance interfaces. While the C interface has 'PPB_Messaging' and 'PPP_Messaging' separate from the Instance interfaces, I stuck the per-instance messaging in to pp::Instance. It seems more intuitive to me, and doesn't have the drawbacks of having too many functions in the C layer instance interfaces. Happy to back off of that position, but it's worth a shot. Overview: From JavaScript, you can invoke 'postMessage' on the embedded module. That results in a call to 'PPP_Messaging::HandleMessage'. From Native Code, you can invoke 'PPB_Messaging::PostMessage', which results in a call to an 'onmessage' function on the DOM element for the module instance in the JavaScript code (if one has been registered). Please see the included example or the examples in the comments of PPB_Messaging and PPP_Messaging. Restrictions: - This implementation is synchronous. A later CL will make it asynchronous. - This implementation supports only intrinsic values and strings (all types that PP_Var supports except for objects). Object & array support will come later. - This implementation only allows for 1 channel per instance. You can not expose other 'channels' or 'ports'. Future CLs will add support for MessagePorts. BUG=None TEST=test_post_message.h/.cc (This CL replaces http://codereview.chromium.org/6538028/ ) Review URL: http://codereview.chromium.org/6716005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@79178 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/cpp')
-rw-r--r--ppapi/cpp/instance.cc16
-rw-r--r--ppapi/cpp/instance.h10
-rw-r--r--ppapi/cpp/module.cc18
3 files changed, 44 insertions, 0 deletions
diff --git a/ppapi/cpp/instance.cc b/ppapi/cpp/instance.cc
index 72676d1..025741f 100644
--- a/ppapi/cpp/instance.cc
+++ b/ppapi/cpp/instance.cc
@@ -4,6 +4,7 @@
#include "ppapi/cpp/instance.h"
+#include "ppapi/c/dev/ppb_messaging_dev.h"
#include "ppapi/c/dev/ppp_printing_dev.h"
#include "ppapi/c/ppb_instance.h"
#include "ppapi/cpp/common.h"
@@ -25,6 +26,10 @@ template <> const char* interface_name<PPB_Instance>() {
return PPB_INSTANCE_INTERFACE;
}
+template <> const char* interface_name<PPB_Messaging_Dev>() {
+ return PPB_MESSAGING_DEV_INTERFACE;
+}
+
} // namespace
Instance::Instance(PP_Instance instance) : pp_instance_(instance) {
@@ -61,6 +66,10 @@ bool Instance::HandleInputEvent(const PP_InputEvent& /*event*/) {
return false;
}
+void Instance::HandleMessage(const Var& /*message_data*/) {
+ return;
+}
+
Var Instance::GetInstanceObject() {
return Var();
}
@@ -115,6 +124,13 @@ Var Instance::ExecuteScript(const Var& script, Var* exception) {
Var::OutException(exception).get()));
}
+void Instance::PostMessage(const Var& message) {
+ if (!has_interface<PPB_Messaging_Dev>())
+ return;
+ get_interface<PPB_Messaging_Dev>()->PostMessage(pp_instance(),
+ message.pp_var());
+}
+
void Instance::AddPerInstanceObject(const std::string& interface_name,
void* object) {
// Ensure we're not trying to register more than one object per interface
diff --git a/ppapi/cpp/instance.h b/ppapi/cpp/instance.h
index 497189f..69de79f 100644
--- a/ppapi/cpp/instance.h
+++ b/ppapi/cpp/instance.h
@@ -96,6 +96,16 @@ class Instance {
/** See PPB_Instance.ExecuteScript. */
Var ExecuteScript(const Var& script, Var* exception = NULL);
+
+ // These functions use the PPP_Messaging and PPB_Messaging interfaces, so that
+ // messaging can be done conveniently for a pp::Instance without using a
+ // separate C++ class.
+
+ /** See PPP_Messaging.HandleMessage. */
+ virtual void HandleMessage(const Var& message_data);
+ /** See PPB_Messaging.PostMessage. */
+ void PostMessage(const Var& message);
+
// @}
/**
diff --git a/ppapi/cpp/module.cc b/ppapi/cpp/module.cc
index 220609d..f64041d 100644
--- a/ppapi/cpp/module.cc
+++ b/ppapi/cpp/module.cc
@@ -25,6 +25,7 @@
#include <string.h>
+#include "ppapi/c/dev/ppp_messaging_dev.h"
#include "ppapi/c/pp_instance.h"
#include "ppapi/c/pp_var.h"
#include "ppapi/c/ppp_instance.h"
@@ -134,6 +135,20 @@ static PPP_Instance instance_interface = {
&Instance_GetInstanceObject
};
+void Messaging_HandleMessage(PP_Instance pp_instance, PP_Var var) {
+ Module* module_singleton = Module::Get();
+ if (!module_singleton)
+ return;
+ Instance* instance = module_singleton->InstanceForPPInstance(pp_instance);
+ if (!instance)
+ return;
+ instance->HandleMessage(Var(Var::PassRef(), var));
+}
+
+static PPP_Messaging_Dev instance_messaging_interface = {
+ &Messaging_HandleMessage
+};
+
// Module ----------------------------------------------------------------------
Module::Module() : pp_module_(0), get_browser_interface_(NULL), core_(NULL) {
@@ -152,6 +167,9 @@ const void* Module::GetPluginInterface(const char* interface_name) {
if (strcmp(interface_name, PPP_INSTANCE_INTERFACE) == 0)
return &instance_interface;
+ if (strcmp(interface_name, PPP_MESSAGING_DEV_INTERFACE) == 0)
+ return &instance_messaging_interface;
+
// Now see if anything was dynamically registered.
InterfaceMap::const_iterator found = additional_interfaces_.find(
std::string(interface_name));