OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2011 The Native Client Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "native_client/src/shared/ppapi_proxy/browser_globals.h" |
| 6 |
| 7 #include <stdio.h> |
| 8 #include <stdlib.h> |
| 9 #include <string.h> |
| 10 #include <map> |
| 11 |
| 12 #include "native_client/src/include/nacl_macros.h" |
| 13 #include "native_client/src/shared/platform/nacl_check.h" |
| 14 #include "native_client/src/shared/ppapi_proxy/browser_ppp.h" |
| 15 #include "native_client/src/shared/ppapi_proxy/utility.h" |
| 16 #include "native_client/src/shared/srpc/nacl_srpc.h" |
| 17 #include "native_client/src/trusted/plugin/plugin.h" |
| 18 |
| 19 namespace ppapi_proxy { |
| 20 |
| 21 // All of these methods are called from the browser main (UI, JavaScript, ...) |
| 22 // thread. |
| 23 |
| 24 const PP_Resource kInvalidResourceId = 0; |
| 25 |
| 26 namespace { |
| 27 |
| 28 std::map<PP_Instance, BrowserPpp*>* instance_to_ppp_map = NULL; |
| 29 |
| 30 // In the future, we might have one sel_ldr with one channel per module, shared |
| 31 // by multiple instances, where each instance consists of a trusted plugin with |
| 32 // a proxy to a nexe. When this happens, we will need to provide the instance id |
| 33 // with each SRPC message. But in the meantime it is enough to map channels |
| 34 // to instances since each proxy has its own SRPC channel. |
| 35 std::map<NaClSrpcChannel*, PP_Module>* channel_to_module_id_map = NULL; |
| 36 std::map<NaClSrpcChannel*, PP_Instance>* channel_to_instance_id_map = NULL; |
| 37 |
| 38 // The function pointer from the browser, and whether or not the plugin |
| 39 // is requesting PPAPI Dev interfaces to be available. |
| 40 // Set by SetPPBGetInterface(). |
| 41 PPB_GetInterface get_interface = NULL; |
| 42 bool plugin_requests_dev_interface = false; |
| 43 |
| 44 } // namespace |
| 45 |
| 46 // By default, disable developer (Dev) interfaces. To enable developer |
| 47 // interfaces, set the environment variable NACL_ENABLE_PPAPI_DEV to 1. |
| 48 // Also, the plugin can request whether or not to enable dev interfaces. |
| 49 bool DevInterfaceEnabled() { |
| 50 static bool first = true; |
| 51 static bool env_dev_enabled = false; |
| 52 if (first) { |
| 53 const char *nacl_enable_ppapi_dev = getenv("NACL_ENABLE_PPAPI_DEV"); |
| 54 if (NULL != nacl_enable_ppapi_dev) { |
| 55 int v = strtol(nacl_enable_ppapi_dev, (char **) 0, 0); |
| 56 if (v != 0) { |
| 57 env_dev_enabled = true; |
| 58 } |
| 59 } |
| 60 first = false; |
| 61 } |
| 62 return env_dev_enabled || plugin_requests_dev_interface; |
| 63 } |
| 64 |
| 65 |
| 66 void SetBrowserPppForInstance(PP_Instance instance, BrowserPpp* browser_ppp) { |
| 67 // If there was no map, create one. |
| 68 if (instance_to_ppp_map == NULL) { |
| 69 instance_to_ppp_map = new std::map<PP_Instance, BrowserPpp*>; |
| 70 } |
| 71 // Add the instance to the map. |
| 72 (*instance_to_ppp_map)[instance] = browser_ppp; |
| 73 } |
| 74 |
| 75 void UnsetBrowserPppForInstance(PP_Instance instance) { |
| 76 if (instance_to_ppp_map == NULL) { |
| 77 // Something major is wrong here. We are deleting a map entry |
| 78 // when there is no map. |
| 79 NACL_NOTREACHED(); |
| 80 return; |
| 81 } |
| 82 // Erase the instance from the map. |
| 83 instance_to_ppp_map->erase(instance); |
| 84 // If there are no more instances alive, remove the map. |
| 85 if (instance_to_ppp_map->size() == 0) { |
| 86 delete instance_to_ppp_map; |
| 87 instance_to_ppp_map = NULL; |
| 88 } |
| 89 } |
| 90 |
| 91 BrowserPpp* LookupBrowserPppForInstance(PP_Instance instance) { |
| 92 if (instance_to_ppp_map == NULL) { |
| 93 return NULL; |
| 94 } |
| 95 return (*instance_to_ppp_map)[instance]; |
| 96 } |
| 97 |
| 98 void SetModuleIdForSrpcChannel(NaClSrpcChannel* channel, PP_Module module_id) { |
| 99 // If there was no map, create one. |
| 100 if (channel_to_module_id_map == NULL) { |
| 101 channel_to_module_id_map = new std::map<NaClSrpcChannel*, PP_Module>; |
| 102 } |
| 103 // Add the channel to the map. |
| 104 (*channel_to_module_id_map)[channel] = module_id; |
| 105 } |
| 106 |
| 107 void SetInstanceIdForSrpcChannel(NaClSrpcChannel* channel, |
| 108 PP_Instance instance_id) { |
| 109 if (channel_to_instance_id_map == NULL) { |
| 110 channel_to_instance_id_map = new std::map<NaClSrpcChannel*, PP_Instance>; |
| 111 } |
| 112 (*channel_to_instance_id_map)[channel] = instance_id; |
| 113 } |
| 114 |
| 115 void UnsetModuleIdForSrpcChannel(NaClSrpcChannel* channel) { |
| 116 if (channel_to_module_id_map == NULL) { |
| 117 // Something major is wrong here. We are deleting a map entry |
| 118 // when there is no map. |
| 119 NACL_NOTREACHED(); |
| 120 return; |
| 121 } |
| 122 // Erase the channel from the map. |
| 123 channel_to_module_id_map->erase(channel); |
| 124 // If there are no more channels alive, remove the map. |
| 125 if (channel_to_module_id_map->size() == 0) { |
| 126 delete channel_to_module_id_map; |
| 127 channel_to_module_id_map = NULL; |
| 128 } |
| 129 } |
| 130 |
| 131 void UnsetInstanceIdForSrpcChannel(NaClSrpcChannel* channel) { |
| 132 if (channel_to_instance_id_map == NULL) { |
| 133 NACL_NOTREACHED(); |
| 134 return; |
| 135 } |
| 136 channel_to_instance_id_map->erase(channel); |
| 137 if (channel_to_instance_id_map->size() == 0) { |
| 138 delete channel_to_module_id_map; |
| 139 channel_to_module_id_map = NULL; |
| 140 } |
| 141 } |
| 142 |
| 143 PP_Module LookupModuleIdForSrpcChannel(NaClSrpcChannel* channel) { |
| 144 if (channel_to_module_id_map == NULL) { |
| 145 return 0; |
| 146 } |
| 147 return (*channel_to_module_id_map)[channel]; |
| 148 } |
| 149 |
| 150 PP_Module LookupInstanceIdForSrpcChannel(NaClSrpcChannel* channel) { |
| 151 if (channel_to_instance_id_map == NULL) { |
| 152 return 0; |
| 153 } |
| 154 return (*channel_to_instance_id_map)[channel]; |
| 155 } |
| 156 |
| 157 NaClSrpcChannel* GetMainSrpcChannel(NaClSrpcRpc* upcall_rpc) { |
| 158 // The upcall channel's server_instance_data member is initialized to point |
| 159 // to the main channel for this instance. Here it is retrieved to use in |
| 160 // constructing a RemoteCallbackInfo. |
| 161 return static_cast<NaClSrpcChannel*>( |
| 162 upcall_rpc->channel->server_instance_data); |
| 163 } |
| 164 |
| 165 NaClSrpcChannel* GetMainSrpcChannel(PP_Instance instance) { |
| 166 return LookupBrowserPppForInstance(instance)->main_channel(); |
| 167 } |
| 168 |
| 169 void CleanUpAfterDeadNexe(PP_Instance instance) { |
| 170 DebugPrintf("CleanUpAfterDeadNexe\n"); |
| 171 BrowserPpp* proxy = LookupBrowserPppForInstance(instance); |
| 172 if (proxy == NULL) |
| 173 return; |
| 174 proxy->ShutdownModule(); |
| 175 proxy->plugin()->ReportDeadNexe(); // Deletes the proxy. |
| 176 } |
| 177 |
| 178 void SetPPBGetInterface(PPB_GetInterface get_interface_function, |
| 179 bool dev_interface) { |
| 180 get_interface = get_interface_function; |
| 181 plugin_requests_dev_interface = dev_interface; |
| 182 } |
| 183 |
| 184 const void* GetBrowserInterface(const char* interface_name) { |
| 185 // Reject suspiciously long interface strings. |
| 186 const size_t kMaxLength = 1024; |
| 187 if (NULL == memchr(interface_name, '\0', kMaxLength)) { |
| 188 return NULL; |
| 189 } |
| 190 // If dev interface is not enabled, reject interfaces containing "(Dev)" |
| 191 if (!DevInterfaceEnabled() && strstr(interface_name, "(Dev)") != NULL) { |
| 192 return NULL; |
| 193 } |
| 194 return (*get_interface)(interface_name); |
| 195 } |
| 196 |
| 197 const void* GetBrowserInterfaceSafe(const char* interface_name) { |
| 198 const void* ppb_interface = GetBrowserInterface(interface_name); |
| 199 if (ppb_interface == NULL) |
| 200 DebugPrintf("PPB_GetInterface: %s not found\n", interface_name); |
| 201 CHECK(ppb_interface != NULL); |
| 202 return ppb_interface; |
| 203 } |
| 204 |
| 205 const PPB_Core* PPBCoreInterface() { |
| 206 static const PPB_Core* ppb = static_cast<const PPB_Core*>( |
| 207 GetBrowserInterfaceSafe(PPB_CORE_INTERFACE)); |
| 208 return ppb; |
| 209 } |
| 210 |
| 211 const PPB_Graphics2D* PPBGraphics2DInterface() { |
| 212 static const PPB_Graphics2D* ppb = static_cast<const PPB_Graphics2D*>( |
| 213 GetBrowserInterfaceSafe(PPB_GRAPHICS_2D_INTERFACE)); |
| 214 return ppb; |
| 215 } |
| 216 |
| 217 const PPB_Graphics3D_Dev* PPBGraphics3DInterface() { |
| 218 static const PPB_Graphics3D_Dev* ppb = static_cast<const PPB_Graphics3D_Dev*>( |
| 219 GetBrowserInterfaceSafe(PPB_GRAPHICS_3D_DEV_INTERFACE)); |
| 220 return ppb; |
| 221 } |
| 222 |
| 223 const PPB_Graphics3DTrusted_Dev* PPBGraphics3DTrustedInterface() { |
| 224 static const PPB_Graphics3DTrusted_Dev* ppb = |
| 225 static_cast<const PPB_Graphics3DTrusted_Dev*>( |
| 226 GetBrowserInterfaceSafe(PPB_GRAPHICS_3D_TRUSTED_DEV_INTERFACE)); |
| 227 return ppb; |
| 228 } |
| 229 |
| 230 const PPB_ImageData* PPBImageDataInterface() { |
| 231 static const PPB_ImageData* ppb = static_cast<const PPB_ImageData*>( |
| 232 GetBrowserInterfaceSafe(PPB_IMAGEDATA_INTERFACE)); |
| 233 return ppb; |
| 234 } |
| 235 |
| 236 const PPB_ImageDataTrusted* PPBImageDataTrustedInterface() { |
| 237 static const PPB_ImageDataTrusted* ppb = |
| 238 static_cast<const PPB_ImageDataTrusted*>( |
| 239 GetBrowserInterfaceSafe(PPB_IMAGEDATA_TRUSTED_INTERFACE)); |
| 240 return ppb; |
| 241 } |
| 242 |
| 243 const PPB_InputEvent* PPBInputEventInterface() { |
| 244 static const PPB_InputEvent* ppb = static_cast<const PPB_InputEvent*>( |
| 245 GetBrowserInterfaceSafe(PPB_INPUT_EVENT_INTERFACE)); |
| 246 return ppb; |
| 247 } |
| 248 |
| 249 const PPB_Instance* PPBInstanceInterface() { |
| 250 static const PPB_Instance* ppb = static_cast<const PPB_Instance*>( |
| 251 GetBrowserInterfaceSafe(PPB_INSTANCE_INTERFACE)); |
| 252 return ppb; |
| 253 } |
| 254 |
| 255 const PPB_KeyboardInputEvent* PPBKeyboardInputEventInterface() { |
| 256 static const PPB_KeyboardInputEvent* ppb = |
| 257 static_cast<const PPB_KeyboardInputEvent*>( |
| 258 GetBrowserInterfaceSafe(PPB_KEYBOARD_INPUT_EVENT_INTERFACE)); |
| 259 return ppb; |
| 260 } |
| 261 |
| 262 const PPB_Memory_Dev* PPBMemoryInterface() { |
| 263 static const PPB_Memory_Dev* ppb = static_cast<const PPB_Memory_Dev*>( |
| 264 GetBrowserInterfaceSafe(PPB_MEMORY_DEV_INTERFACE)); |
| 265 return ppb; |
| 266 } |
| 267 |
| 268 const PPB_Messaging* PPBMessagingInterface() { |
| 269 static const PPB_Messaging* ppb = |
| 270 static_cast<const PPB_Messaging*>( |
| 271 GetBrowserInterfaceSafe(PPB_MESSAGING_INTERFACE)); |
| 272 return ppb; |
| 273 } |
| 274 |
| 275 const PPB_MouseInputEvent* PPBMouseInputEventInterface() { |
| 276 static const PPB_MouseInputEvent* ppb = |
| 277 static_cast<const PPB_MouseInputEvent*>( |
| 278 GetBrowserInterfaceSafe(PPB_MOUSE_INPUT_EVENT_INTERFACE)); |
| 279 return ppb; |
| 280 } |
| 281 |
| 282 const PPB_URLLoader* PPBURLLoaderInterface() { |
| 283 static const PPB_URLLoader* ppb = |
| 284 static_cast<const PPB_URLLoader*>( |
| 285 GetBrowserInterfaceSafe(PPB_URLLOADER_INTERFACE)); |
| 286 return ppb; |
| 287 } |
| 288 |
| 289 const PPB_URLRequestInfo* PPBURLRequestInfoInterface() { |
| 290 static const PPB_URLRequestInfo* ppb = |
| 291 static_cast<const PPB_URLRequestInfo*>( |
| 292 GetBrowserInterfaceSafe(PPB_URLREQUESTINFO_INTERFACE)); |
| 293 return ppb; |
| 294 } |
| 295 |
| 296 const PPB_URLResponseInfo* PPBURLResponseInfoInterface() { |
| 297 static const PPB_URLResponseInfo* ppb = |
| 298 static_cast<const PPB_URLResponseInfo*>( |
| 299 GetBrowserInterfaceSafe(PPB_URLRESPONSEINFO_INTERFACE)); |
| 300 return ppb; |
| 301 } |
| 302 |
| 303 const PPB_Var* PPBVarInterface() { |
| 304 static const PPB_Var* ppb = |
| 305 static_cast<const PPB_Var*>( |
| 306 GetBrowserInterfaceSafe(PPB_VAR_INTERFACE)); |
| 307 return ppb; |
| 308 } |
| 309 |
| 310 const PPB_WheelInputEvent* PPBWheelInputEventInterface() { |
| 311 static const PPB_WheelInputEvent* ppb = |
| 312 static_cast<const PPB_WheelInputEvent*>( |
| 313 GetBrowserInterfaceSafe(PPB_WHEEL_INPUT_EVENT_INTERFACE)); |
| 314 return ppb; |
| 315 } |
| 316 |
| 317 // Dev interfaces. |
| 318 const PPB_CursorControl_Dev* PPBCursorControlInterface() { |
| 319 static const PPB_CursorControl_Dev* ppb = |
| 320 static_cast<const PPB_CursorControl_Dev*>( |
| 321 GetBrowserInterfaceSafe(PPB_CURSOR_CONTROL_DEV_INTERFACE)); |
| 322 return ppb; |
| 323 } |
| 324 |
| 325 const PPB_FileIO* PPBFileIOInterface() { |
| 326 static const PPB_FileIO* ppb = |
| 327 static_cast<const PPB_FileIO*>( |
| 328 GetBrowserInterfaceSafe(PPB_FILEIO_INTERFACE)); |
| 329 return ppb; |
| 330 } |
| 331 |
| 332 const PPB_FileRef* PPBFileRefInterface() { |
| 333 static const PPB_FileRef* ppb = |
| 334 static_cast<const PPB_FileRef*>( |
| 335 GetBrowserInterfaceSafe(PPB_FILEREF_INTERFACE)); |
| 336 return ppb; |
| 337 } |
| 338 |
| 339 const PPB_FileSystem* PPBFileSystemInterface() { |
| 340 static const PPB_FileSystem* ppb = |
| 341 static_cast<const PPB_FileSystem*>( |
| 342 GetBrowserInterfaceSafe(PPB_FILESYSTEM_INTERFACE)); |
| 343 return ppb; |
| 344 } |
| 345 |
| 346 const PPB_Find_Dev* PPBFindInterface() { |
| 347 static const PPB_Find_Dev* ppb = |
| 348 static_cast<const PPB_Find_Dev*>( |
| 349 GetBrowserInterfaceSafe(PPB_FIND_DEV_INTERFACE)); |
| 350 return ppb; |
| 351 } |
| 352 |
| 353 const PPB_Font_Dev* PPBFontInterface() { |
| 354 static const PPB_Font_Dev* ppb = |
| 355 static_cast<const PPB_Font_Dev*>( |
| 356 GetBrowserInterfaceSafe(PPB_FONT_DEV_INTERFACE)); |
| 357 return ppb; |
| 358 } |
| 359 |
| 360 const PPB_Scrollbar_Dev* PPBScrollbarInterface() { |
| 361 static const PPB_Scrollbar_Dev* ppb = |
| 362 static_cast<const PPB_Scrollbar_Dev*>( |
| 363 GetBrowserInterfaceSafe(PPB_SCROLLBAR_DEV_INTERFACE)); |
| 364 return ppb; |
| 365 } |
| 366 |
| 367 const PPB_Testing_Dev* PPBTestingInterface() { |
| 368 static const PPB_Testing_Dev* ppb = |
| 369 static_cast<const PPB_Testing_Dev*>( |
| 370 GetBrowserInterfaceSafe(PPB_TESTING_DEV_INTERFACE)); |
| 371 return ppb; |
| 372 } |
| 373 |
| 374 const PPB_Widget_Dev* PPBWidgetInterface() { |
| 375 static const PPB_Widget_Dev* ppb = |
| 376 static_cast<const PPB_Widget_Dev*>( |
| 377 GetBrowserInterfaceSafe(PPB_WIDGET_DEV_INTERFACE)); |
| 378 return ppb; |
| 379 } |
| 380 |
| 381 const PPB_Zoom_Dev* PPBZoomInterface() { |
| 382 static const PPB_Zoom_Dev* ppb = |
| 383 static_cast<const PPB_Zoom_Dev*>( |
| 384 GetBrowserInterfaceSafe(PPB_ZOOM_DEV_INTERFACE)); |
| 385 return ppb; |
| 386 } |
| 387 |
| 388 // Private interfaces. |
| 389 const PPB_PDF* PPBPDFInterface() { |
| 390 static const PPB_PDF* ppb = |
| 391 static_cast<const PPB_PDF*>( |
| 392 GetBrowserInterfaceSafe(PPB_PDF_INTERFACE)); |
| 393 return ppb; |
| 394 } |
| 395 |
| 396 } // namespace ppapi_proxy |
OLD | NEW |