diff options
author | dmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-18 16:44:00 +0000 |
---|---|---|
committer | dmichael@chromium.org <dmichael@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-06-18 16:44:00 +0000 |
commit | e87640bdf9afb28737f94c6784b7723d27b9dfdd (patch) | |
tree | dba77d110fa9b84c2ba1547a35208a11629b2e76 /ppapi/proxy/ppp_messaging_proxy.cc | |
parent | 2073de75d29457e2e865bdbb87148e42b3ccf454 (diff) | |
download | chromium_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.cc | 85 |
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 |