summaryrefslogtreecommitdiffstats
path: root/ppapi/proxy/ppp_messaging_proxy.cc
diff options
context:
space:
mode:
authordmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-18 16:44:00 +0000
committerdmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-06-18 16:44:00 +0000
commite87640bdf9afb28737f94c6784b7723d27b9dfdd (patch)
treedba77d110fa9b84c2ba1547a35208a11629b2e76 /ppapi/proxy/ppp_messaging_proxy.cc
parent2073de75d29457e2e865bdbb87148e42b3ccf454 (diff)
downloadchromium_src-e87640bdf9afb28737f94c6784b7723d27b9dfdd.zip
chromium_src-e87640bdf9afb28737f94c6784b7723d27b9dfdd.tar.gz
chromium_src-e87640bdf9afb28737f94c6784b7723d27b9dfdd.tar.bz2
PPAPI: Implement synchronous postMessage
BUG=367896 Review URL: https://codereview.chromium.org/264303002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@278102 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ppapi/proxy/ppp_messaging_proxy.cc')
-rw-r--r--ppapi/proxy/ppp_messaging_proxy.cc85
1 files changed, 84 insertions, 1 deletions
diff --git a/ppapi/proxy/ppp_messaging_proxy.cc b/ppapi/proxy/ppp_messaging_proxy.cc
index ba83ca7..75614ae 100644
--- a/ppapi/proxy/ppp_messaging_proxy.cc
+++ b/ppapi/proxy/ppp_messaging_proxy.cc
@@ -8,17 +8,53 @@
#include "ppapi/c/ppp_messaging.h"
#include "ppapi/proxy/host_dispatcher.h"
+#include "ppapi/proxy/message_handler.h"
+#include "ppapi/proxy/plugin_dispatcher.h"
#include "ppapi/proxy/plugin_resource_tracker.h"
#include "ppapi/proxy/plugin_var_tracker.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/serialized_var.h"
#include "ppapi/shared_impl/ppapi_globals.h"
#include "ppapi/shared_impl/proxy_lock.h"
+#include "ppapi/shared_impl/scoped_pp_var.h"
#include "ppapi/shared_impl/var_tracker.h"
namespace ppapi {
namespace proxy {
+namespace {
+
+MessageHandler* GetMessageHandler(Dispatcher* dispatcher,
+ PP_Instance instance) {
+ if (!dispatcher || !dispatcher->IsPlugin()) {
+ NOTREACHED();
+ return NULL;
+ }
+ PluginDispatcher* plugin_dispatcher =
+ static_cast<PluginDispatcher*>(dispatcher);
+ InstanceData* instance_data = plugin_dispatcher->GetInstanceData(instance);
+ if (!instance_data)
+ return NULL;
+
+ return instance_data->message_handler.get();
+}
+
+void ResetMessageHandler(Dispatcher* dispatcher, PP_Instance instance) {
+ if (!dispatcher || !dispatcher->IsPlugin()) {
+ NOTREACHED();
+ return;
+ }
+ PluginDispatcher* plugin_dispatcher =
+ static_cast<PluginDispatcher*>(dispatcher);
+ InstanceData* instance_data = plugin_dispatcher->GetInstanceData(instance);
+ if (!instance_data)
+ return;
+
+ instance_data->message_handler.reset();
+}
+
+} // namespace
+
PPP_Messaging_Proxy::PPP_Messaging_Proxy(Dispatcher* dispatcher)
: InterfaceProxy(dispatcher),
ppp_messaging_impl_(NULL) {
@@ -39,6 +75,9 @@ bool PPP_Messaging_Proxy::OnMessageReceived(const IPC::Message& msg) {
IPC_BEGIN_MESSAGE_MAP(PPP_Messaging_Proxy, msg)
IPC_MESSAGE_HANDLER(PpapiMsg_PPPMessaging_HandleMessage,
OnMsgHandleMessage)
+ IPC_MESSAGE_HANDLER_DELAY_REPLY(
+ PpapiMsg_PPPMessageHandler_HandleBlockingMessage,
+ OnMsgHandleBlockingMessage)
IPC_MESSAGE_UNHANDLED(handled = false)
IPC_END_MESSAGE_MAP()
return handled;
@@ -47,13 +86,57 @@ bool PPP_Messaging_Proxy::OnMessageReceived(const IPC::Message& msg) {
void PPP_Messaging_Proxy::OnMsgHandleMessage(
PP_Instance instance, SerializedVarReceiveInput message_data) {
PP_Var received_var(message_data.GetForInstance(dispatcher(), instance));
+ MessageHandler* message_handler = GetMessageHandler(dispatcher(), instance);
+ if (message_handler) {
+ if (message_handler->LoopIsValid()) {
+ message_handler->HandleMessage(ScopedPPVar(received_var));
+ return;
+ } else {
+ // If the MessageHandler's loop has been quit, then we should treat it as
+ // though it has been unregistered and start sending messages to the
+ // default handler. This might mean the plugin has lost messages, but
+ // there's not really anything sane we can do about it. They should have
+ // used UnregisterMessageHandler.
+ ResetMessageHandler(dispatcher(), instance);
+ }
+ }
+ // If we reach this point, then there's no message handler registered, so
+ // we send to the default PPP_Messaging one for the instance.
+
// SerializedVarReceiveInput will decrement the reference count, but we want
- // to give the recipient a reference.
+ // to give the recipient a reference in the legacy API.
PpapiGlobals::Get()->GetVarTracker()->AddRefVar(received_var);
CallWhileUnlocked(ppp_messaging_impl_->HandleMessage,
instance,
received_var);
}
+void PPP_Messaging_Proxy::OnMsgHandleBlockingMessage(
+ PP_Instance instance,
+ SerializedVarReceiveInput message_data,
+ IPC::Message* reply_msg) {
+ ScopedPPVar received_var(message_data.GetForInstance(dispatcher(), instance));
+ MessageHandler* message_handler = GetMessageHandler(dispatcher(), instance);
+ if (message_handler) {
+ if (message_handler->LoopIsValid()) {
+ message_handler->HandleBlockingMessage(
+ received_var, scoped_ptr<IPC::Message>(reply_msg));
+ return;
+ } else {
+ // If the MessageHandler's loop has been quit, then we should treat it as
+ // though it has been unregistered. Also see the note for PostMessage.
+ ResetMessageHandler(dispatcher(), instance);
+ }
+ }
+ // We have no handler, but we still need to respond to unblock the renderer
+ // and inform the JavaScript caller.
+ PpapiMsg_PPPMessageHandler_HandleBlockingMessage::WriteReplyParams(
+ reply_msg,
+ SerializedVarReturnValue::Convert(dispatcher(), PP_MakeUndefined()),
+ false /* was_handled */);
+ dispatcher()->Send(reply_msg);
+}
+
+
} // namespace proxy
} // namespace ppapi