| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "ppapi/proxy/message_handler.h" | 5 #include "ppapi/proxy/message_handler.h" |
| 6 | 6 |
| 7 #include "ipc/ipc_message.h" | 7 #include "ipc/ipc_message.h" |
| 8 #include "ppapi/proxy/plugin_dispatcher.h" | 8 #include "ppapi/proxy/plugin_dispatcher.h" |
| 9 #include "ppapi/proxy/ppapi_messages.h" | 9 #include "ppapi/proxy/ppapi_messages.h" |
| 10 #include "ppapi/proxy/ppb_message_loop_proxy.h" | 10 #include "ppapi/proxy/ppb_message_loop_proxy.h" |
| 11 #include "ppapi/shared_impl/proxy_lock.h" | 11 #include "ppapi/shared_impl/proxy_lock.h" |
| 12 #include "ppapi/shared_impl/scoped_pp_var.h" | 12 #include "ppapi/shared_impl/scoped_pp_var.h" |
| 13 #include "ppapi/thunk/enter.h" | 13 #include "ppapi/thunk/enter.h" |
| 14 | 14 |
| 15 namespace ppapi { | 15 namespace ppapi { |
| 16 namespace proxy { | 16 namespace proxy { |
| 17 namespace { | 17 namespace { |
| 18 | 18 |
| 19 typedef void (*HandleMessageFunc)(PP_Instance, void*, const PP_Var*); | 19 typedef void (*HandleMessageFunc)(PP_Instance, void*, const PP_Var*); |
| 20 typedef void (*HandleBlockingMessageFunc)( | 20 typedef void (*HandleBlockingMessageFunc)( |
| 21 PP_Instance, void*, const PP_Var*, PP_Var*); | 21 PP_Instance, void*, const PP_Var*, PP_Var*); |
| 22 typedef void (*HandleMessageFunc_0_1)(PP_Instance, void*, PP_Var); | |
| 23 typedef PP_Var (*HandleBlockingMessageFunc_0_1)(PP_Instance, void*, PP_Var); | |
| 24 | 22 |
| 25 void HandleMessageWrapper(HandleMessageFunc function, | 23 void HandleMessageWrapper(HandleMessageFunc function, |
| 26 PP_Instance instance, | 24 PP_Instance instance, |
| 27 void* user_data, | 25 void* user_data, |
| 28 ScopedPPVar message_data) { | 26 ScopedPPVar message_data) { |
| 29 CallWhileUnlocked(function, instance, user_data, | 27 CallWhileUnlocked(function, instance, user_data, |
| 30 &message_data.get()); | 28 &message_data.get()); |
| 31 } | 29 } |
| 32 | 30 |
| 33 void HandleBlockingMessageWrapper(HandleBlockingMessageFunc function, | 31 void HandleBlockingMessageWrapper(HandleBlockingMessageFunc function, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 45 function, instance, user_data, &message_data.get(), &result); | 43 function, instance, user_data, &message_data.get(), &result); |
| 46 MessageLoopResource::GetCurrent()-> | 44 MessageLoopResource::GetCurrent()-> |
| 47 set_currently_handling_blocking_message(false); | 45 set_currently_handling_blocking_message(false); |
| 48 PpapiMsg_PPPMessageHandler_HandleBlockingMessage::WriteReplyParams( | 46 PpapiMsg_PPPMessageHandler_HandleBlockingMessage::WriteReplyParams( |
| 49 reply_msg.get(), | 47 reply_msg.get(), |
| 50 SerializedVarReturnValue::Convert(dispatcher, result), | 48 SerializedVarReturnValue::Convert(dispatcher, result), |
| 51 true /* was_handled */); | 49 true /* was_handled */); |
| 52 dispatcher->Send(reply_msg.release()); | 50 dispatcher->Send(reply_msg.release()); |
| 53 } | 51 } |
| 54 | 52 |
| 55 // TODO(dmichael): Remove the 0_1 verions; crbug.com/414398 | |
| 56 void HandleMessageWrapper_0_1(HandleMessageFunc_0_1 function, | |
| 57 PP_Instance instance, | |
| 58 void* user_data, | |
| 59 ScopedPPVar message_data) { | |
| 60 CallWhileUnlocked(function, instance, user_data, message_data.get()); | |
| 61 } | |
| 62 | |
| 63 void HandleBlockingMessageWrapper_0_1(HandleBlockingMessageFunc_0_1 function, | |
| 64 PP_Instance instance, | |
| 65 void* user_data, | |
| 66 ScopedPPVar message_data, | |
| 67 scoped_ptr<IPC::Message> reply_msg) { | |
| 68 PluginDispatcher* dispatcher = PluginDispatcher::GetForInstance(instance); | |
| 69 if (!dispatcher) | |
| 70 return; | |
| 71 MessageLoopResource::GetCurrent()-> | |
| 72 set_currently_handling_blocking_message(true); | |
| 73 PP_Var return_value = CallWhileUnlocked(function, | |
| 74 instance, | |
| 75 user_data, | |
| 76 message_data.get()); | |
| 77 MessageLoopResource::GetCurrent()-> | |
| 78 set_currently_handling_blocking_message(false); | |
| 79 PpapiMsg_PPPMessageHandler_HandleBlockingMessage::WriteReplyParams( | |
| 80 reply_msg.get(), | |
| 81 SerializedVarReturnValue::Convert(dispatcher, return_value), | |
| 82 true /* was_handled */); | |
| 83 dispatcher->Send(reply_msg.release()); | |
| 84 } | |
| 85 | |
| 86 } // namespace | 53 } // namespace |
| 87 | 54 |
| 88 // static | 55 // static |
| 89 scoped_ptr<MessageHandler> MessageHandler::Create( | 56 scoped_ptr<MessageHandler> MessageHandler::Create( |
| 90 PP_Instance instance, | 57 PP_Instance instance, |
| 91 const PPP_MessageHandler_0_2* handler_if, | 58 const PPP_MessageHandler_0_2* handler_if, |
| 92 void* user_data, | 59 void* user_data, |
| 93 PP_Resource message_loop, | 60 PP_Resource message_loop, |
| 94 int32_t* error) { | 61 int32_t* error) { |
| 95 scoped_ptr<MessageHandler> result; | 62 scoped_ptr<MessageHandler> result; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 113 *error = PP_ERROR_WRONG_THREAD; | 80 *error = PP_ERROR_WRONG_THREAD; |
| 114 return result.Pass(); | 81 return result.Pass(); |
| 115 } | 82 } |
| 116 | 83 |
| 117 result.reset(new MessageHandler( | 84 result.reset(new MessageHandler( |
| 118 instance, handler_if, user_data, message_loop_resource)); | 85 instance, handler_if, user_data, message_loop_resource)); |
| 119 *error = PP_OK; | 86 *error = PP_OK; |
| 120 return result.Pass(); | 87 return result.Pass(); |
| 121 } | 88 } |
| 122 | 89 |
| 123 // CreateDeprecated is a near-exact copy of Create, but we'll just delete it | |
| 124 // when 0.1 is deprecated, so need to get fancy to avoid code duplication. | |
| 125 // TODO(dmichael) crbug.com/414398 | |
| 126 // static | |
| 127 scoped_ptr<MessageHandler> MessageHandler::CreateDeprecated( | |
| 128 PP_Instance instance, | |
| 129 const PPP_MessageHandler_0_1_Deprecated* handler_if, | |
| 130 void* user_data, | |
| 131 PP_Resource message_loop, | |
| 132 int32_t* error) { | |
| 133 scoped_ptr<MessageHandler> result; | |
| 134 // The interface and all function pointers must be valid. | |
| 135 if (!handler_if || | |
| 136 !handler_if->HandleMessage || | |
| 137 !handler_if->HandleBlockingMessage || | |
| 138 !handler_if->Destroy) { | |
| 139 *error = PP_ERROR_BADARGUMENT; | |
| 140 return result.Pass(); | |
| 141 } | |
| 142 thunk::EnterResourceNoLock<thunk::PPB_MessageLoop_API> | |
| 143 enter_loop(message_loop, true); | |
| 144 if (enter_loop.failed()) { | |
| 145 *error = PP_ERROR_BADRESOURCE; | |
| 146 return result.Pass(); | |
| 147 } | |
| 148 scoped_refptr<MessageLoopResource> message_loop_resource( | |
| 149 static_cast<MessageLoopResource*>(enter_loop.object())); | |
| 150 if (message_loop_resource->is_main_thread_loop()) { | |
| 151 *error = PP_ERROR_WRONG_THREAD; | |
| 152 return result.Pass(); | |
| 153 } | |
| 154 | |
| 155 result.reset(new MessageHandler( | |
| 156 instance, handler_if, user_data, message_loop_resource)); | |
| 157 *error = PP_OK; | |
| 158 return result.Pass(); | |
| 159 } | |
| 160 | |
| 161 MessageHandler::~MessageHandler() { | 90 MessageHandler::~MessageHandler() { |
| 162 // It's possible the message_loop_proxy is NULL if that loop has been quit. | 91 // It's possible the message_loop_proxy is NULL if that loop has been quit. |
| 163 // In that case, we unfortunately just can't call Destroy. | 92 // In that case, we unfortunately just can't call Destroy. |
| 164 if (message_loop_->message_loop_proxy().get()) { | 93 if (message_loop_->message_loop_proxy().get()) { |
| 165 // The posted task won't have the proxy lock, but that's OK, it doesn't | 94 // The posted task won't have the proxy lock, but that's OK, it doesn't |
| 166 // touch any internal state; it's a direct call on the plugin's function. | 95 // touch any internal state; it's a direct call on the plugin's function. |
| 167 if (handler_if_0_1_) { | |
| 168 message_loop_->message_loop_proxy()->PostTask(FROM_HERE, | |
| 169 base::Bind(handler_if_0_1_->Destroy, | |
| 170 instance_, | |
| 171 user_data_)); | |
| 172 return; | |
| 173 } | |
| 174 message_loop_->message_loop_proxy()->PostTask(FROM_HERE, | 96 message_loop_->message_loop_proxy()->PostTask(FROM_HERE, |
| 175 base::Bind(handler_if_->Destroy, | 97 base::Bind(handler_if_->Destroy, |
| 176 instance_, | 98 instance_, |
| 177 user_data_)); | 99 user_data_)); |
| 178 } | 100 } |
| 179 } | 101 } |
| 180 | 102 |
| 181 bool MessageHandler::LoopIsValid() const { | 103 bool MessageHandler::LoopIsValid() const { |
| 182 return !!message_loop_->message_loop_proxy().get(); | 104 return !!message_loop_->message_loop_proxy().get(); |
| 183 } | 105 } |
| 184 | 106 |
| 185 void MessageHandler::HandleMessage(ScopedPPVar var) { | 107 void MessageHandler::HandleMessage(ScopedPPVar var) { |
| 186 if (handler_if_0_1_) { | |
| 187 // TODO(dmichael): Remove this code path. crbug.com/414398 | |
| 188 message_loop_->message_loop_proxy()->PostTask(FROM_HERE, | |
| 189 RunWhileLocked(base::Bind(&HandleMessageWrapper_0_1, | |
| 190 handler_if_0_1_->HandleMessage, | |
| 191 instance_, | |
| 192 user_data_, | |
| 193 var))); | |
| 194 return; | |
| 195 } | |
| 196 message_loop_->message_loop_proxy()->PostTask(FROM_HERE, | 108 message_loop_->message_loop_proxy()->PostTask(FROM_HERE, |
| 197 RunWhileLocked(base::Bind(&HandleMessageWrapper, | 109 RunWhileLocked(base::Bind(&HandleMessageWrapper, |
| 198 handler_if_->HandleMessage, | 110 handler_if_->HandleMessage, |
| 199 instance_, | 111 instance_, |
| 200 user_data_, | 112 user_data_, |
| 201 var))); | 113 var))); |
| 202 } | 114 } |
| 203 | 115 |
| 204 void MessageHandler::HandleBlockingMessage(ScopedPPVar var, | 116 void MessageHandler::HandleBlockingMessage(ScopedPPVar var, |
| 205 scoped_ptr<IPC::Message> reply_msg) { | 117 scoped_ptr<IPC::Message> reply_msg) { |
| 206 if (handler_if_0_1_) { | |
| 207 // TODO(dmichael): Remove this code path. crbug.com/414398 | |
| 208 message_loop_->message_loop_proxy()->PostTask(FROM_HERE, | |
| 209 RunWhileLocked(base::Bind(&HandleBlockingMessageWrapper_0_1, | |
| 210 handler_if_0_1_->HandleBlockingMessage, | |
| 211 instance_, | |
| 212 user_data_, | |
| 213 var, | |
| 214 base::Passed(reply_msg.Pass())))); | |
| 215 return; | |
| 216 } | |
| 217 message_loop_->message_loop_proxy()->PostTask(FROM_HERE, | 118 message_loop_->message_loop_proxy()->PostTask(FROM_HERE, |
| 218 RunWhileLocked(base::Bind(&HandleBlockingMessageWrapper, | 119 RunWhileLocked(base::Bind(&HandleBlockingMessageWrapper, |
| 219 handler_if_->HandleBlockingMessage, | 120 handler_if_->HandleBlockingMessage, |
| 220 instance_, | 121 instance_, |
| 221 user_data_, | 122 user_data_, |
| 222 var, | 123 var, |
| 223 base::Passed(reply_msg.Pass())))); | 124 base::Passed(reply_msg.Pass())))); |
| 224 } | 125 } |
| 225 | 126 |
| 226 MessageHandler::MessageHandler( | 127 MessageHandler::MessageHandler( |
| 227 PP_Instance instance, | 128 PP_Instance instance, |
| 228 const PPP_MessageHandler_0_2* handler_if, | 129 const PPP_MessageHandler_0_2* handler_if, |
| 229 void* user_data, | 130 void* user_data, |
| 230 scoped_refptr<MessageLoopResource> message_loop) | 131 scoped_refptr<MessageLoopResource> message_loop) |
| 231 : instance_(instance), | 132 : instance_(instance), |
| 232 handler_if_(handler_if), | 133 handler_if_(handler_if), |
| 233 handler_if_0_1_(NULL), | |
| 234 user_data_(user_data), | 134 user_data_(user_data), |
| 235 message_loop_(message_loop) { | 135 message_loop_(message_loop) { |
| 236 } | 136 } |
| 237 | |
| 238 MessageHandler::MessageHandler( | |
| 239 PP_Instance instance, | |
| 240 const PPP_MessageHandler_0_1_Deprecated* handler_if, | |
| 241 void* user_data, | |
| 242 scoped_refptr<MessageLoopResource> message_loop) | |
| 243 : instance_(instance), | |
| 244 handler_if_(NULL), | |
| 245 handler_if_0_1_(handler_if), | |
| 246 user_data_(user_data), | |
| 247 message_loop_(message_loop) { | |
| 248 } | |
| 249 | 137 |
| 250 } // namespace proxy | 138 } // namespace proxy |
| 251 } // namespace ppapi | 139 } // namespace ppapi |
| OLD | NEW |