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 |