blob: af143bcd4a76a576dfa9543bc714fb7f6a029260 [file] [log] [blame]
Avi Drissmandb497b32022-09-15 19:47:281// Copyright 2012 The Chromium Authors
[email protected]b20df1c2011-08-03 14:38:242// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ppapi/proxy/ppp_messaging_proxy.h"
6
7#include <algorithm>
8
dchengced92242016-04-07 00:00:129#include "base/memory/ptr_util.h"
[email protected]b20df1c2011-08-03 14:38:2410#include "ppapi/c/ppp_messaging.h"
11#include "ppapi/proxy/host_dispatcher.h"
[email protected]e87640bd2014-06-18 16:44:0012#include "ppapi/proxy/message_handler.h"
13#include "ppapi/proxy/plugin_dispatcher.h"
[email protected]2bbd2c672011-08-09 23:14:1314#include "ppapi/proxy/plugin_resource_tracker.h"
[email protected]b20df1c2011-08-03 14:38:2415#include "ppapi/proxy/plugin_var_tracker.h"
16#include "ppapi/proxy/ppapi_messages.h"
17#include "ppapi/proxy/serialized_var.h"
[email protected]794d83cd2011-10-20 19:09:2018#include "ppapi/shared_impl/ppapi_globals.h"
[email protected]4c41d3f2012-02-15 01:44:4719#include "ppapi/shared_impl/proxy_lock.h"
[email protected]e87640bd2014-06-18 16:44:0020#include "ppapi/shared_impl/scoped_pp_var.h"
[email protected]794d83cd2011-10-20 19:09:2021#include "ppapi/shared_impl/var_tracker.h"
[email protected]b20df1c2011-08-03 14:38:2422
[email protected]4d2efd22011-08-18 21:58:0223namespace ppapi {
[email protected]b20df1c2011-08-03 14:38:2424namespace proxy {
25
[email protected]e87640bd2014-06-18 16:44:0026namespace {
27
28MessageHandler* GetMessageHandler(Dispatcher* dispatcher,
29 PP_Instance instance) {
30 if (!dispatcher || !dispatcher->IsPlugin()) {
31 NOTREACHED();
32 return NULL;
33 }
34 PluginDispatcher* plugin_dispatcher =
35 static_cast<PluginDispatcher*>(dispatcher);
36 InstanceData* instance_data = plugin_dispatcher->GetInstanceData(instance);
37 if (!instance_data)
38 return NULL;
39
40 return instance_data->message_handler.get();
41}
42
43void ResetMessageHandler(Dispatcher* dispatcher, PP_Instance instance) {
44 if (!dispatcher || !dispatcher->IsPlugin()) {
45 NOTREACHED();
46 return;
47 }
48 PluginDispatcher* plugin_dispatcher =
49 static_cast<PluginDispatcher*>(dispatcher);
50 InstanceData* instance_data = plugin_dispatcher->GetInstanceData(instance);
51 if (!instance_data)
52 return;
53
54 instance_data->message_handler.reset();
55}
56
57} // namespace
58
[email protected]5c966022011-09-13 18:09:3759PPP_Messaging_Proxy::PPP_Messaging_Proxy(Dispatcher* dispatcher)
60 : InterfaceProxy(dispatcher),
61 ppp_messaging_impl_(NULL) {
62 if (dispatcher->IsPlugin()) {
63 ppp_messaging_impl_ = static_cast<const PPP_Messaging*>(
64 dispatcher->local_get_interface()(PPP_MESSAGING_INTERFACE));
65 }
[email protected]b20df1c2011-08-03 14:38:2466}
67
68PPP_Messaging_Proxy::~PPP_Messaging_Proxy() {
69}
70
[email protected]b20df1c2011-08-03 14:38:2471bool PPP_Messaging_Proxy::OnMessageReceived(const IPC::Message& msg) {
[email protected]d5f5dc12013-01-22 23:05:0372 if (!dispatcher()->IsPlugin())
73 return false;
74
[email protected]b20df1c2011-08-03 14:38:2475 bool handled = true;
76 IPC_BEGIN_MESSAGE_MAP(PPP_Messaging_Proxy, msg)
77 IPC_MESSAGE_HANDLER(PpapiMsg_PPPMessaging_HandleMessage,
78 OnMsgHandleMessage)
[email protected]e87640bd2014-06-18 16:44:0079 IPC_MESSAGE_HANDLER_DELAY_REPLY(
80 PpapiMsg_PPPMessageHandler_HandleBlockingMessage,
81 OnMsgHandleBlockingMessage)
[email protected]b20df1c2011-08-03 14:38:2482 IPC_MESSAGE_UNHANDLED(handled = false)
83 IPC_END_MESSAGE_MAP()
84 return handled;
85}
86
87void PPP_Messaging_Proxy::OnMsgHandleMessage(
88 PP_Instance instance, SerializedVarReceiveInput message_data) {
[email protected]30e1cb752013-03-19 20:42:3389 PP_Var received_var(message_data.GetForInstance(dispatcher(), instance));
[email protected]e87640bd2014-06-18 16:44:0090 MessageHandler* message_handler = GetMessageHandler(dispatcher(), instance);
91 if (message_handler) {
92 if (message_handler->LoopIsValid()) {
93 message_handler->HandleMessage(ScopedPPVar(received_var));
94 return;
95 } else {
96 // If the MessageHandler's loop has been quit, then we should treat it as
97 // though it has been unregistered and start sending messages to the
98 // default handler. This might mean the plugin has lost messages, but
99 // there's not really anything sane we can do about it. They should have
100 // used UnregisterMessageHandler.
101 ResetMessageHandler(dispatcher(), instance);
102 }
103 }
104 // If we reach this point, then there's no message handler registered, so
105 // we send to the default PPP_Messaging one for the instance.
106
[email protected]b20df1c2011-08-03 14:38:24107 // SerializedVarReceiveInput will decrement the reference count, but we want
[email protected]e87640bd2014-06-18 16:44:00108 // to give the recipient a reference in the legacy API.
[email protected]794d83cd2011-10-20 19:09:20109 PpapiGlobals::Get()->GetVarTracker()->AddRefVar(received_var);
[email protected]4c41d3f2012-02-15 01:44:47110 CallWhileUnlocked(ppp_messaging_impl_->HandleMessage,
111 instance,
112 received_var);
[email protected]b20df1c2011-08-03 14:38:24113}
114
[email protected]e87640bd2014-06-18 16:44:00115void PPP_Messaging_Proxy::OnMsgHandleBlockingMessage(
116 PP_Instance instance,
117 SerializedVarReceiveInput message_data,
118 IPC::Message* reply_msg) {
119 ScopedPPVar received_var(message_data.GetForInstance(dispatcher(), instance));
120 MessageHandler* message_handler = GetMessageHandler(dispatcher(), instance);
121 if (message_handler) {
122 if (message_handler->LoopIsValid()) {
dchengced92242016-04-07 00:00:12123 message_handler->HandleBlockingMessage(received_var,
124 base::WrapUnique(reply_msg));
[email protected]e87640bd2014-06-18 16:44:00125 return;
126 } else {
127 // If the MessageHandler's loop has been quit, then we should treat it as
128 // though it has been unregistered. Also see the note for PostMessage.
129 ResetMessageHandler(dispatcher(), instance);
130 }
131 }
132 // We have no handler, but we still need to respond to unblock the renderer
133 // and inform the JavaScript caller.
134 PpapiMsg_PPPMessageHandler_HandleBlockingMessage::WriteReplyParams(
135 reply_msg,
136 SerializedVarReturnValue::Convert(dispatcher(), PP_MakeUndefined()),
137 false /* was_handled */);
138 dispatcher()->Send(reply_msg);
139}
140
141
[email protected]b20df1c2011-08-03 14:38:24142} // namespace proxy
[email protected]4d2efd22011-08-18 21:58:02143} // namespace ppapi