1 // Copyright (c) 2011 The Chromium 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 // This implements the required interfaces for representing a plugin module 6 // instance in browser interactions and provides a way to register custom 7 // plugin interfaces. 8 // 9 10 #include <stdio.h> 11 #include <string.h> 12 13 #include <map> 14 15 #include "native_client/src/include/nacl_macros.h" 16 #include "native_client/src/shared/platform/nacl_check.h" 17 18 #include "ppapi/c/dev/ppb_var_deprecated.h" 19 #include "ppapi/c/pp_errors.h" 20 #include "ppapi/c/pp_instance.h" 21 #include "ppapi/c/pp_module.h" 22 #include "ppapi/c/pp_var.h" 23 #include "ppapi/c/ppb.h" 24 #include "ppapi/c/ppb_var.h" 25 #include "ppapi/c/ppp.h" 26 #include "ppapi/c/ppp_instance.h" 27 #include "ppapi/c/ppp_messaging.h" 28 29 #include "ppapi/native_client/tests/ppapi_test_lib/get_browser_interface.h" 30 #include "ppapi/native_client/tests/ppapi_test_lib/internal_utils.h" 31 #include "ppapi/native_client/tests/ppapi_test_lib/test_interface.h" 32 33 /////////////////////////////////////////////////////////////////////////////// 34 // Plugin interface registration 35 /////////////////////////////////////////////////////////////////////////////// 36 37 namespace { 38 39 class PluginInterfaceTable { 40 public: 41 // Return singleton intsance. 42 static PluginInterfaceTable* Get() { 43 static PluginInterfaceTable table; 44 return &table; 45 } 46 47 void AddInterface(const char* interface_name, const void* ppp_interface) { 48 interface_map_[nacl::string(interface_name)] = ppp_interface; 49 } 50 const void* GetInterface(const char* interface_name) { 51 // This will add a NULL element for missing interfaces. 52 return interface_map_[nacl::string(interface_name)]; 53 } 54 55 private: 56 NACL_DISALLOW_COPY_AND_ASSIGN(PluginInterfaceTable); 57 58 PluginInterfaceTable() {} 59 60 typedef std::map<nacl::string, const void*> InterfaceMap; 61 InterfaceMap interface_map_; 62 }; 63 64 } // namespace 65 66 void RegisterPluginInterface(const char* interface_name, 67 const void* ppp_interface) { 68 PluginInterfaceTable::Get()->AddInterface(interface_name, ppp_interface); 69 } 70 71 72 /////////////////////////////////////////////////////////////////////////////// 73 // PPP_Instance implementation 74 /////////////////////////////////////////////////////////////////////////////// 75 76 PP_Bool DidCreateDefault(PP_Instance instance, 77 uint32_t /*argc*/, 78 const char* /*argn*/[], 79 const char* /*argv*/[]) { 80 CHECK(ppb_get_interface() != NULL); 81 CHECK(PPBCore() != NULL); 82 CHECK(PPBGraphics2D() != NULL); 83 CHECK(PPBImageData() != NULL); 84 CHECK(PPBInstance() != NULL); 85 CHECK(PPBMessaging() != NULL); 86 CHECK(PPBURLLoader() != NULL); 87 CHECK(PPBURLRequestInfo() != NULL); 88 CHECK(PPBURLResponseInfo() != NULL); 89 CHECK(PPBVar() != NULL); 90 91 set_pp_instance(instance); 92 SetupTests(); 93 94 return PP_TRUE; 95 } 96 97 void DidDestroyDefault(PP_Instance /*instance*/) { 98 } 99 100 void DidChangeViewDefault(PP_Instance /*instance*/, PP_Resource /*view*/) { 101 } 102 103 void DidChangeFocusDefault(PP_Instance /*instance*/, 104 PP_Bool /*has_focus*/) { 105 } 106 107 PP_Bool HandleDocumentLoadDefault(PP_Instance instance, 108 PP_Resource url_loader) { 109 return PP_TRUE; 110 } 111 112 namespace { 113 114 const PPP_Instance ppp_instance_interface = { 115 DidCreateDefault, 116 DidDestroyDefault, 117 DidChangeViewDefault, 118 DidChangeFocusDefault, 119 HandleDocumentLoadDefault 120 }; 121 122 /////////////////////////////////////////////////////////////////////////////// 123 // PPP_Messaging implementation 124 /////////////////////////////////////////////////////////////////////////////// 125 126 void HandleMessage(PP_Instance instance, PP_Var message) { 127 if (message.type != PP_VARTYPE_STRING) 128 return; 129 uint32_t len = 0; 130 const char* test_name = PPBVar()->VarToUtf8(message, &len); 131 RunTest(test_name); 132 } 133 134 const PPP_Messaging ppp_messaging_interface = { 135 HandleMessage 136 }; 137 138 } // namespace 139 140 /////////////////////////////////////////////////////////////////////////////// 141 // PPP implementation 142 /////////////////////////////////////////////////////////////////////////////// 143 144 int32_t PPP_InitializeModule(PP_Module module, 145 PPB_GetInterface get_browser_interface) { 146 set_pp_module(module); 147 set_ppb_get_interface(get_browser_interface); 148 SetupPluginInterfaces(); 149 return PP_OK; 150 } 151 152 void PPP_ShutdownModule() { 153 } 154 155 const void* PPP_GetInterface(const char* interface_name) { 156 const void* ppp = PluginInterfaceTable::Get()->GetInterface(interface_name); 157 158 // The PPP_Instance interface is required for every plugin, 159 // so supply one if the tester has not. 160 if (ppp == NULL && 0 == strncmp(PPP_INSTANCE_INTERFACE, interface_name, 161 strlen(PPP_INSTANCE_INTERFACE))) { 162 return &ppp_instance_interface; 163 } 164 // The PPP_Messaging interface is required for the test set-up, 165 // so we supply our own. 166 if (0 == strncmp(PPP_MESSAGING_INTERFACE, interface_name, 167 strlen(PPP_MESSAGING_INTERFACE))) { 168 CHECK(ppp == NULL); 169 return &ppp_messaging_interface; 170 } 171 // All other interfaces are to be optionally supplied by the tester, 172 // so we return whatever was added in SetupPluginInterfaces() (if anything). 173 return ppp; 174 } 175