| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (c) 2011 The Native Client Authors. All rights reserved. | |
| 3 * Use of this source code is governed by a BSD-style license that can be | |
| 4 * found in the LICENSE file. | |
| 5 */ | |
| 6 | |
| 7 #include <stdio.h> | |
| 8 | |
| 9 #include <cstring> | |
| 10 #include <string> | |
| 11 #include <vector> | |
| 12 | |
| 13 #include "native_client/src/include/nacl_macros.h" | |
| 14 #include "native_client/src/include/portability.h" | |
| 15 #include "native_client/src/shared/platform/nacl_check.h" | |
| 16 #include "native_client/src/shared/ppapi_proxy/plugin_ppb_var_deprecated.h" | |
| 17 #include "native_client/tests/fake_browser_ppapi/fake_core.h" | |
| 18 #include "native_client/tests/fake_browser_ppapi/fake_file_io.h" | |
| 19 #include "native_client/tests/fake_browser_ppapi/fake_file_io_trusted.h" | |
| 20 #include "native_client/tests/fake_browser_ppapi/fake_host.h" | |
| 21 #include "native_client/tests/fake_browser_ppapi/fake_instance.h" | |
| 22 #include "native_client/tests/fake_browser_ppapi/fake_nacl_private.h" | |
| 23 #include "native_client/tests/fake_browser_ppapi/fake_resource.h" | |
| 24 #include "native_client/tests/fake_browser_ppapi/fake_url_loader.h" | |
| 25 #include "native_client/tests/fake_browser_ppapi/fake_url_request_info.h" | |
| 26 #include "native_client/tests/fake_browser_ppapi/fake_url_response_info.h" | |
| 27 #include "native_client/tests/fake_browser_ppapi/fake_url_util.h" | |
| 28 #include "native_client/tests/fake_browser_ppapi/fake_window.h" | |
| 29 #include "native_client/tests/fake_browser_ppapi/test_scriptable.h" | |
| 30 #include "native_client/tests/fake_browser_ppapi/utility.h" | |
| 31 | |
| 32 #include "ppapi/c/dev/ppb_var_deprecated.h" | |
| 33 #include "ppapi/c/ppb_core.h" | |
| 34 #include "ppapi/c/ppb_instance.h" | |
| 35 #include "ppapi/c/ppp_instance.h" | |
| 36 #include "ppapi/c/pp_errors.h" | |
| 37 #include "ppapi/c/private/ppb_instance_private.h" | |
| 38 #include "ppapi/c/private/ppb_uma_private.h" | |
| 39 | |
| 40 using fake_browser_ppapi::DebugPrintf; | |
| 41 using fake_browser_ppapi::Host; | |
| 42 using fake_browser_ppapi::FakeWindow; | |
| 43 | |
| 44 namespace { | |
| 45 | |
| 46 Host* host = NULL; | |
| 47 | |
| 48 const void* FakeGetBrowserInterface(const char* interface_name) { | |
| 49 DebugPrintf("PPB_GetInterface: name='%s'\n", interface_name); | |
| 50 const void* ppb = NULL; | |
| 51 if (std::strcmp(interface_name, PPB_CORE_INTERFACE) == 0) { | |
| 52 ppb = fake_browser_ppapi::Core::GetInterface(); | |
| 53 } else if (std::strcmp(interface_name, PPB_INSTANCE_INTERFACE) == 0) { | |
| 54 ppb = fake_browser_ppapi::Instance::GetInterface(); | |
| 55 } else if (std::strcmp(interface_name, PPB_INSTANCE_PRIVATE_INTERFACE) == 0) { | |
| 56 ppb = fake_browser_ppapi::Instance::GetPrivateInterface(); | |
| 57 } else if (std::strcmp(interface_name, PPB_VAR_DEPRECATED_INTERFACE) == 0) { | |
| 58 ppb = host->var_deprecated_interface(); | |
| 59 } else if (std::strcmp(interface_name, PPB_URLLOADER_INTERFACE) == 0) { | |
| 60 ppb = fake_browser_ppapi::URLLoader::GetInterface(); | |
| 61 } else if (std::strcmp(interface_name, | |
| 62 PPB_URLREQUESTINFO_INTERFACE) == 0) { | |
| 63 ppb = fake_browser_ppapi::URLRequestInfo::GetInterface(); | |
| 64 } else if (std::strcmp(interface_name, | |
| 65 PPB_URLRESPONSEINFO_INTERFACE) == 0) { | |
| 66 ppb = fake_browser_ppapi::URLResponseInfo::GetInterface(); | |
| 67 } else if (std::strcmp(interface_name, PPB_FILEIO_DEV_INTERFACE) == 0) { | |
| 68 ppb = fake_browser_ppapi::FileIO::GetInterface(); | |
| 69 } else if (std::strcmp(interface_name, | |
| 70 PPB_FILEIOTRUSTED_DEV_INTERFACE) == 0) { | |
| 71 ppb = fake_browser_ppapi::FileIOTrusted::GetInterface(); | |
| 72 } else if (std::strcmp(interface_name, | |
| 73 PPB_URLUTIL_DEV_INTERFACE_0_6) == 0) { | |
| 74 ppb = fake_browser_ppapi::URLUtil_Dev::GetInterface(); | |
| 75 } else if (std::strcmp(interface_name, | |
| 76 PPB_NACL_PRIVATE_INTERFACE) == 0) { | |
| 77 ppb = fake_browser_ppapi::NaClPrivate::GetInterface(); | |
| 78 } else if (std::strcmp(interface_name, | |
| 79 PPB_UMA_PRIVATE_INTERFACE) == 0) { | |
| 80 ppb = NULL; | |
| 81 } else { | |
| 82 NACL_UNIMPLEMENTED(); | |
| 83 } | |
| 84 DebugPrintf("PPB_GetInterface: value=%p\n", ppb); | |
| 85 return ppb; | |
| 86 } | |
| 87 | |
| 88 // Module ids are needed for some call APIs, but the fake browser does | |
| 89 // not implement the storage tracking APIs that would use a real value. | |
| 90 // Since we have just two modules (browser and plugin), we'll statically | |
| 91 // assign id of 1 to one, 100 to other. | |
| 92 // TODO(sehr): implement storage tracking. | |
| 93 | |
| 94 // The storage allocated by the browser for the window object, etc., are | |
| 95 // attributed to the browser's module id. | |
| 96 PP_Module BrowserModuleId() { | |
| 97 static PP_Module id = 100; | |
| 98 return id; | |
| 99 } | |
| 100 | |
| 101 // The storage allocated by the plugin for its scriptable objects are | |
| 102 // attributed to the its module id. | |
| 103 PP_Module PluginModuleId() { | |
| 104 static PP_Module id = 1; | |
| 105 return id; | |
| 106 } | |
| 107 | |
| 108 bool ParseArgs(const char* str, | |
| 109 uint32_t* argc, | |
| 110 const char*** argn, | |
| 111 const char*** argv) { | |
| 112 std::vector<std::string> argn_vector; | |
| 113 std::vector<std::string> argv_vector; | |
| 114 *argc = 0; | |
| 115 char* embed_arg = std::strtok(strdup(str), ";"); | |
| 116 while (embed_arg != NULL) { | |
| 117 char* equal_loc = std::strchr(embed_arg, '='); | |
| 118 if (equal_loc == NULL) { | |
| 119 return false; | |
| 120 } | |
| 121 size_t name_length = static_cast<size_t>(equal_loc - embed_arg); | |
| 122 argn_vector.push_back(std::string(embed_arg, name_length)); | |
| 123 argv_vector.push_back(equal_loc + 1); | |
| 124 ++*argc; | |
| 125 embed_arg = std::strtok(NULL, ";"); | |
| 126 } | |
| 127 | |
| 128 *argn = reinterpret_cast<const char**>(malloc(*argc * sizeof(*argn))); | |
| 129 *argv = reinterpret_cast<const char**>(malloc(*argc * sizeof(*argv))); | |
| 130 for (uint32_t i = 0; i < *argc; ++i) { | |
| 131 (*argn)[i] = strdup(argn_vector[i].c_str()); | |
| 132 (*argv)[i] = strdup(argv_vector[i].c_str()); | |
| 133 DebugPrintf("ParseArgs(): arg[%u]: '%s' = '%s'\n", | |
| 134 i, (*argn)[i], (*argv)[i]); | |
| 135 } | |
| 136 return true; | |
| 137 } | |
| 138 | |
| 139 } // namespace | |
| 140 | |
| 141 namespace fake_browser_ppapi { | |
| 142 | |
| 143 PP_Resource TrackResource(Resource* resource) { | |
| 144 PP_Resource resource_id = host->TrackResource(resource); | |
| 145 DebugPrintf("TrackResource: resource_id=%"NACL_PRId32"\n", resource_id); | |
| 146 return resource_id; | |
| 147 } | |
| 148 | |
| 149 Resource* GetResource(PP_Resource resource_id) { | |
| 150 return host->GetResource(resource_id); | |
| 151 } | |
| 152 | |
| 153 PP_Instance TrackInstance(Instance* instance) { | |
| 154 PP_Instance instance_id = host->TrackInstance(instance); | |
| 155 DebugPrintf("TrackInstance: instance_id=%"NACL_PRId32"\n", instance_id); | |
| 156 return instance_id; | |
| 157 } | |
| 158 | |
| 159 Instance* GetInstance(PP_Instance instance_id) { | |
| 160 return host->GetInstance(instance_id); | |
| 161 } | |
| 162 | |
| 163 } // namespace fake_browser_ppapi | |
| 164 | |
| 165 namespace { | |
| 166 | |
| 167 // Test instance execution. | |
| 168 void TestInstance(PP_Module browser_module_id, | |
| 169 const PPP_Instance* instance_interface, | |
| 170 const char* page_url, | |
| 171 uint32_t argc, | |
| 172 const char** argn, | |
| 173 const char** argv) { | |
| 174 DebugPrintf("TestInstance(): page url %s\n", page_url); | |
| 175 // Create an instance and the corresponding id. | |
| 176 fake_browser_ppapi::Instance* instance = new fake_browser_ppapi::Instance; | |
| 177 PP_Instance instance_id = TrackInstance(instance); | |
| 178 // Create a fake window object. | |
| 179 FakeWindow window(browser_module_id, instance_id, host, page_url); | |
| 180 instance->set_window(&window); | |
| 181 // Create and initialize plugin instance. | |
| 182 CHECK(instance_interface->DidCreate(instance_id, argc, argn, argv)); | |
| 183 #ifndef PPAPI_INSTANCE_REMOVE_SCRIPTING | |
| 184 // Test the scriptable object for the instance. | |
| 185 PP_Var instance_object = instance_interface->GetInstanceObject(instance_id); | |
| 186 const PPB_Var_Deprecated* var_deprecated_interface = | |
| 187 reinterpret_cast<const PPB_Var_Deprecated*>( | |
| 188 FakeGetBrowserInterface(PPB_VAR_DEPRECATED_INTERFACE)); | |
| 189 TestScriptableObject(instance_object, | |
| 190 fake_browser_ppapi::Instance::GetInterface(), | |
| 191 var_deprecated_interface, | |
| 192 instance_id, | |
| 193 browser_module_id); | |
| 194 #endif | |
| 195 } | |
| 196 | |
| 197 } // namespace | |
| 198 | |
| 199 int main(int argc, char** argv) { | |
| 200 // Turn off stdout buffering to aid debugging in case of a crash. | |
| 201 setvbuf(stdout, NULL, _IONBF, 0); | |
| 202 | |
| 203 NaClLogModuleInit(); | |
| 204 | |
| 205 if (argc < 5) { | |
| 206 fprintf(stderr, | |
| 207 "Usage: fake_browser_ppapi plugin page_url \"embed args\"" | |
| 208 " root_path\n"); | |
| 209 return 1; | |
| 210 } | |
| 211 | |
| 212 const char* plugin_name = argv[1]; | |
| 213 host = new fake_browser_ppapi::Host(plugin_name); | |
| 214 // TODO(polina): Change FakeWindow functions to not rely on host for | |
| 215 // the var interface. | |
| 216 host->set_var_deprecated_interface( | |
| 217 ppapi_proxy::PluginVarDeprecated::GetInterface()); | |
| 218 | |
| 219 // Test startup. | |
| 220 CHECK(host->InitializeModule(PluginModuleId(), FakeGetBrowserInterface) == | |
| 221 PP_OK); | |
| 222 | |
| 223 // Get an instance of the plugin. | |
| 224 const PPP_Instance* instance_interface = | |
| 225 reinterpret_cast<const PPP_Instance*>( | |
| 226 host->GetInterface(PPP_INSTANCE_INTERFACE)); | |
| 227 CHECK(instance_interface != NULL); | |
| 228 const char* page_url = argv[2]; | |
| 229 | |
| 230 // Get the embed argc/argn/argv. | |
| 231 const char* embed_args = argv[3]; | |
| 232 uint32_t embed_argc = 0; | |
| 233 const char** embed_argn = NULL; | |
| 234 const char** embed_argv = NULL; | |
| 235 CHECK(ParseArgs(embed_args, &embed_argc, &embed_argn, &embed_argv)); | |
| 236 | |
| 237 // Set url path and local path for nexe - required by fake url loader. | |
| 238 std::string url_path = page_url; | |
| 239 size_t last_slash = url_path.rfind("/"); | |
| 240 CHECK(last_slash != std::string::npos); | |
| 241 url_path.erase(last_slash, url_path.size()); | |
| 242 fake_browser_ppapi::g_nacl_ppapi_url_path = url_path; | |
| 243 fake_browser_ppapi::g_nacl_ppapi_local_path = argv[4]; | |
| 244 | |
| 245 // Test an instance. | |
| 246 TestInstance(BrowserModuleId(), | |
| 247 instance_interface, | |
| 248 page_url, | |
| 249 embed_argc, | |
| 250 embed_argn, | |
| 251 embed_argv); | |
| 252 | |
| 253 // Shutdown. | |
| 254 host->ShutdownModule(); | |
| 255 | |
| 256 // Close the plugin .so. | |
| 257 delete host; | |
| 258 | |
| 259 printf("PASS\n"); | |
| 260 return 0; | |
| 261 } | |
| OLD | NEW |