OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2009, Google Inc. | 2 * Copyright 2009, Google Inc. |
3 * All rights reserved. | 3 * All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
7 * met: | 7 * met: |
8 * | 8 * |
9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 14 matching lines...) Expand all Loading... |
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 28 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
30 */ | 30 */ |
31 | 31 |
32 | 32 |
33 #include "plugin/cross/main.h" | 33 #include "plugin/cross/main.h" |
34 | 34 |
| 35 #include "base/at_exit.h" |
| 36 #include "base/command_line.h" |
| 37 #include "base/file_util.h" |
| 38 #include "plugin/cross/config.h" |
| 39 #include "plugin/cross/out_of_memory.h" |
| 40 #include "plugin/cross/whitelist.h" |
| 41 #ifdef OS_WIN |
| 42 #include "breakpad/win/bluescreen_detector.h" |
| 43 #endif |
| 44 |
35 using glue::_o3d::PluginObject; | 45 using glue::_o3d::PluginObject; |
36 using glue::StreamManager; | 46 using glue::StreamManager; |
37 | 47 |
38 #if !defined(O3D_INTERNAL_PLUGIN) | 48 #if !defined(O3D_INTERNAL_PLUGIN) |
39 | 49 |
| 50 #ifdef OS_WIN |
| 51 #define O3D_DEBUG_LOG_FILENAME L"debug.log" |
| 52 #else |
| 53 #define O3D_DEBUG_LOG_FILENAME "debug.log" |
| 54 #endif |
| 55 |
| 56 #if defined(OS_WIN) || defined(OS_MACOSX) |
| 57 o3d::PluginLogging *g_logger = NULL; |
| 58 static bool g_logging_initialized = false; |
| 59 #ifdef OS_WIN |
| 60 static o3d::BluescreenDetector *g_bluescreen_detector = NULL; |
| 61 #endif // OS_WIN |
| 62 #endif // OS_WIN || OS_MACOSX |
| 63 |
| 64 // We would normally make this a stack variable in main(), but in a |
| 65 // plugin, that's not possible, so we make it a global. When the DLL is loaded |
| 66 // this it gets constructed and when it is unlooaded it is destructed. Note |
| 67 // that this cannot be done in NP_Initialize and NP_Shutdown because those |
| 68 // calls do not necessarily signify the DLL being loaded and unloaded. If the |
| 69 // DLL is not unloaded then the values of global variables are preserved. |
| 70 static base::AtExitManager g_at_exit_manager; |
| 71 |
40 int BreakpadEnabler::scope_count_ = 0; | 72 int BreakpadEnabler::scope_count_ = 0; |
41 | 73 |
42 // Used for breakpad crash handling | |
43 ExceptionManager *g_exception_manager = NULL; | |
44 | |
45 #endif // O3D_INTERNAL_PLUGIN | 74 #endif // O3D_INTERNAL_PLUGIN |
46 | 75 |
47 namespace o3d { | 76 namespace o3d { |
48 | 77 |
49 NPError NP_GetValue(void *instance, NPPVariable variable, void *value) { | 78 NPError NP_GetValue(NPPVariable variable, void *value) { |
50 switch (variable) { | 79 switch (variable) { |
51 case NPPVpluginNameString: | 80 case NPPVpluginNameString: |
52 *static_cast<char **>(value) = const_cast<char*>(O3D_PLUGIN_NAME); | 81 *static_cast<char **>(value) = const_cast<char*>(O3D_PLUGIN_NAME); |
53 break; | 82 break; |
54 case NPPVpluginDescriptionString: | 83 case NPPVpluginDescriptionString: |
55 *static_cast<char **>(value) = const_cast<char*>(O3D_PLUGIN_DESCRIPTION); | 84 *static_cast<char **>(value) = const_cast<char*>(O3D_PLUGIN_DESCRIPTION); |
56 break; | 85 break; |
57 default: | 86 default: |
58 return NPERR_INVALID_PARAM; | 87 return NPERR_INVALID_PARAM; |
59 break; | 88 break; |
60 } | 89 } |
61 return NPERR_NO_ERROR; | 90 return NPERR_NO_ERROR; |
62 } | 91 } |
63 | 92 |
64 NPError NPP_NewStream(NPP instance, NPMIMEType type, NPStream *stream, | 93 int16 NPP_HandleEvent(NPP instance, void *event) { |
65 NPBool seekable, uint16 *stype) { | |
66 HANDLE_CRASHES; | 94 HANDLE_CRASHES; |
67 PluginObject *obj = static_cast<PluginObject*>(instance->pdata); | 95 PluginObject *obj = static_cast<PluginObject *>(instance->pdata); |
| 96 if (!obj) { |
| 97 return 0; |
| 98 } |
| 99 |
| 100 return PlatformNPPHandleEvent(instance, obj, event); |
| 101 } |
| 102 |
| 103 NPError NPP_NewStream(NPP instance, |
| 104 NPMIMEType type, |
| 105 NPStream *stream, |
| 106 NPBool seekable, |
| 107 uint16 *stype) { |
| 108 HANDLE_CRASHES; |
| 109 PluginObject *obj = static_cast<PluginObject *>(instance->pdata); |
| 110 if (!obj) { |
| 111 return NPERR_INVALID_PARAM; |
| 112 } |
| 113 |
68 StreamManager *stream_manager = obj->stream_manager(); | 114 StreamManager *stream_manager = obj->stream_manager(); |
69 if (stream_manager->NewStream(stream, stype)) { | 115 if (stream_manager->NewStream(stream, stype)) { |
70 return NPERR_NO_ERROR; | 116 return NPERR_NO_ERROR; |
71 } else { | 117 } else { |
72 // TODO: find out which error we should return | 118 // TODO: find out which error we should return |
73 return NPERR_INVALID_PARAM; | 119 return NPERR_INVALID_PARAM; |
74 } | 120 } |
75 } | 121 } |
76 | 122 |
77 NPError NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason) { | 123 NPError NPP_DestroyStream(NPP instance, NPStream *stream, NPReason reason) { |
78 HANDLE_CRASHES; | 124 HANDLE_CRASHES; |
79 PluginObject *obj = static_cast<PluginObject*>(instance->pdata); | 125 PluginObject *obj = static_cast<PluginObject *>(instance->pdata); |
| 126 if (!obj) { |
| 127 return NPERR_NO_ERROR; |
| 128 } |
| 129 |
80 StreamManager *stream_manager = obj->stream_manager(); | 130 StreamManager *stream_manager = obj->stream_manager(); |
81 if (stream_manager->DestroyStream(stream, reason)) { | 131 if (stream_manager->DestroyStream(stream, reason)) { |
82 return NPERR_NO_ERROR; | 132 return NPERR_NO_ERROR; |
83 } else { | 133 } else { |
84 // TODO: find out which error we should return | 134 // TODO: find out which error we should return |
85 return NPERR_INVALID_PARAM; | 135 return NPERR_INVALID_PARAM; |
86 } | 136 } |
87 } | 137 } |
88 | 138 |
89 int32 NPP_WriteReady(NPP instance, NPStream *stream) { | 139 int32 NPP_WriteReady(NPP instance, NPStream *stream) { |
90 HANDLE_CRASHES; | 140 HANDLE_CRASHES; |
91 PluginObject *obj = static_cast<PluginObject*>(instance->pdata); | 141 PluginObject *obj = static_cast<PluginObject *>(instance->pdata); |
| 142 if (!obj) { |
| 143 return 0; |
| 144 } |
| 145 |
92 StreamManager *stream_manager = obj->stream_manager(); | 146 StreamManager *stream_manager = obj->stream_manager(); |
93 return stream_manager->WriteReady(stream); | 147 return stream_manager->WriteReady(stream); |
94 } | 148 } |
95 | 149 |
96 int32 NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, | 150 int32 NPP_Write(NPP instance, NPStream *stream, int32 offset, int32 len, |
97 void *buffer) { | 151 void *buffer) { |
98 HANDLE_CRASHES; | 152 HANDLE_CRASHES; |
99 PluginObject *obj = static_cast<PluginObject*>(instance->pdata); | 153 PluginObject *obj = static_cast<PluginObject *>(instance->pdata); |
| 154 if (!obj) { |
| 155 return 0; |
| 156 } |
| 157 |
100 StreamManager *stream_manager = obj->stream_manager(); | 158 StreamManager *stream_manager = obj->stream_manager(); |
101 return stream_manager->Write(stream, offset, len, buffer); | 159 return stream_manager->Write(stream, offset, len, buffer); |
102 } | 160 } |
103 | 161 |
104 void NPP_Print(NPP instance, NPPrint *platformPrint) { | 162 void NPP_Print(NPP instance, NPPrint *platformPrint) { |
105 HANDLE_CRASHES; | 163 HANDLE_CRASHES; |
106 } | 164 } |
107 | 165 |
108 void NPP_URLNotify(NPP instance, const char *url, NPReason reason, | 166 void NPP_URLNotify(NPP instance, const char *url, NPReason reason, |
109 void *notifyData) { | 167 void *notifyData) { |
110 HANDLE_CRASHES; | 168 HANDLE_CRASHES; |
111 PluginObject *obj = static_cast<PluginObject*>(instance->pdata); | 169 PluginObject *obj = static_cast<PluginObject *>(instance->pdata); |
112 // Make sure the plugin hasn't been destroyed already. | 170 if (!obj) { |
113 if (obj) { | 171 return; |
114 StreamManager *stream_manager = obj->stream_manager(); | |
115 stream_manager->URLNotify(url, reason, notifyData); | |
116 } | 172 } |
| 173 |
| 174 StreamManager *stream_manager = obj->stream_manager(); |
| 175 stream_manager->URLNotify(url, reason, notifyData); |
117 } | 176 } |
118 | 177 |
119 NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value) { | 178 NPError NPP_GetValue(NPP instance, NPPVariable variable, void *value) { |
120 HANDLE_CRASHES; | 179 HANDLE_CRASHES; |
| 180 PluginObject *obj = static_cast<PluginObject *>(instance->pdata); |
| 181 if (!obj) { |
| 182 return NPERR_INVALID_PARAM; |
| 183 } |
| 184 |
121 switch (variable) { | 185 switch (variable) { |
122 case NPPVpluginScriptableNPObject: { | 186 case NPPVpluginScriptableNPObject: { |
123 void **v = static_cast<void **>(value); | 187 void **v = static_cast<void **>(value); |
124 PluginObject *obj = static_cast<PluginObject *>(instance->pdata); | |
125 // Return value is expected to be retained | 188 // Return value is expected to be retained |
126 GLUE_PROFILE_START(instance, "retainobject"); | 189 GLUE_PROFILE_START(instance, "retainobject"); |
127 NPN_RetainObject(obj); | 190 NPN_RetainObject(obj); |
128 GLUE_PROFILE_STOP(instance, "retainobject"); | 191 GLUE_PROFILE_STOP(instance, "retainobject"); |
129 *v = obj; | 192 *v = obj; |
130 break; | 193 break; |
131 } | 194 } |
132 default: { | 195 default: { |
133 NPError ret = PlatformNPPGetValue(instance, variable, value); | 196 NPError ret = PlatformNPPGetValue(obj, variable, value); |
134 if (ret == NPERR_INVALID_PARAM) | 197 if (ret == NPERR_INVALID_PARAM) |
135 ret = o3d::NP_GetValue(instance, variable, value); | 198 ret = o3d::NP_GetValue(variable, value); |
136 return ret; | 199 return ret; |
137 } | 200 } |
138 } | 201 } |
139 return NPERR_NO_ERROR; | 202 return NPERR_NO_ERROR; |
140 } | 203 } |
141 | 204 |
| 205 NPError NPP_New(NPMIMEType pluginType, |
| 206 NPP instance, |
| 207 uint16 mode, |
| 208 int16 argc, |
| 209 char *argn[], |
| 210 char *argv[], |
| 211 NPSavedData *saved) { |
| 212 HANDLE_CRASHES; |
| 213 |
| 214 #if !defined(O3D_INTERNAL_PLUGIN) && (defined(OS_WIN) || defined(OS_MACOSX)) |
| 215 // TODO(tschmelcher): Support this on Linux? |
| 216 if (!g_logging_initialized) { |
| 217 // Get user config metrics. These won't be stored though unless the user |
| 218 // opts-in for usagestats logging |
| 219 GetUserAgentMetrics(instance); |
| 220 GetUserConfigMetrics(); |
| 221 // Create usage stats logs object |
| 222 g_logger = o3d::PluginLogging::InitializeUsageStatsLogging(); |
| 223 #ifdef OS_WIN |
| 224 if (g_logger) { |
| 225 // Setup blue-screen detection |
| 226 g_bluescreen_detector = new o3d::BluescreenDetector(); |
| 227 g_bluescreen_detector->Start(); |
| 228 } |
| 229 #endif |
| 230 g_logging_initialized = true; |
| 231 } |
| 232 #endif |
| 233 |
| 234 if (!IsDomainAuthorized(instance)) { |
| 235 return NPERR_INVALID_URL; |
| 236 } |
| 237 |
| 238 PluginObject *obj = glue::_o3d::PluginObject::Create(instance); |
| 239 instance->pdata = obj; |
| 240 glue::_o3d::InitializeGlue(instance); |
| 241 obj->Init(argc, argn, argv); |
| 242 return PlatformNPPNew(instance, obj); |
| 243 } |
| 244 |
| 245 NPError NPP_Destroy(NPP instance, NPSavedData **save) { |
| 246 HANDLE_CRASHES; |
| 247 PluginObject *obj = static_cast<PluginObject *>(instance->pdata); |
| 248 if (!obj) { |
| 249 return NPERR_NO_ERROR; |
| 250 } |
| 251 |
| 252 NPError err = PlatformNPPDestroy(instance, obj); |
| 253 |
| 254 NPN_ReleaseObject(obj); |
| 255 instance->pdata = NULL; |
| 256 |
| 257 return err; |
| 258 } |
| 259 |
142 NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value) { | 260 NPError NPP_SetValue(NPP instance, NPNVariable variable, void *value) { |
143 HANDLE_CRASHES; | 261 HANDLE_CRASHES; |
144 return NPERR_GENERIC_ERROR; | 262 return NPERR_GENERIC_ERROR; |
145 } | 263 } |
| 264 |
| 265 NPError NPP_SetWindow(NPP instance, NPWindow* window) { |
| 266 HANDLE_CRASHES; |
| 267 PluginObject *obj = static_cast<PluginObject *>(instance->pdata); |
| 268 if (!obj) { |
| 269 return NPERR_NO_ERROR; |
| 270 } |
| 271 |
| 272 return PlatformNPPSetWindow(instance, obj, window); |
| 273 } |
| 274 |
| 275 // Called when the browser has finished attempting to stream data to |
| 276 // a file as requested. If fname == NULL the attempt was not successful. |
| 277 void NPP_StreamAsFile(NPP instance, NPStream *stream, const char *fname) { |
| 278 HANDLE_CRASHES; |
| 279 PluginObject *obj = static_cast<PluginObject *>(instance->pdata); |
| 280 if (!obj) { |
| 281 return; |
| 282 } |
| 283 |
| 284 StreamManager *stream_manager = obj->stream_manager(); |
| 285 PlatformNPPStreamAsFile(stream_manager, stream, fname); |
| 286 } |
| 287 |
146 } // namespace o3d | 288 } // namespace o3d |
147 | 289 |
148 #if defined(O3D_INTERNAL_PLUGIN) | 290 #if defined(O3D_INTERNAL_PLUGIN) |
149 namespace o3d { | 291 namespace o3d { |
150 #else | 292 #else |
151 extern "C" { | 293 extern "C" { |
152 #endif | 294 #endif |
153 | 295 |
| 296 NPError EXPORT_SYMBOL OSCALL NP_Initialize(NPNetscapeFuncs *browserFuncs |
| 297 #ifdef OS_LINUX |
| 298 , |
| 299 NPPluginFuncs *pluginFuncs |
| 300 #endif |
| 301 ) { |
| 302 HANDLE_CRASHES; |
| 303 NPError err = InitializeNPNApi(browserFuncs); |
| 304 if (err != NPERR_NO_ERROR) { |
| 305 return err; |
| 306 } |
| 307 |
| 308 #ifdef OS_LINUX |
| 309 NP_GetEntryPoints(pluginFuncs); |
| 310 #endif // OS_LINUX |
| 311 |
| 312 #if !defined(O3D_INTERNAL_PLUGIN) |
| 313 if (!o3d::SetupOutOfMemoryHandler()) |
| 314 return NPERR_MODULE_LOAD_FAILED_ERROR; |
| 315 #endif // O3D_INTERNAL_PLUGIN |
| 316 |
| 317 err = o3d::PlatformPreNPInitialize(); |
| 318 if (err != NPERR_NO_ERROR) { |
| 319 return err; |
| 320 } |
| 321 |
| 322 #if !defined(O3D_INTERNAL_PLUGIN) |
| 323 // Turn on the logging. |
| 324 CommandLine::Init(0, NULL); |
| 325 |
| 326 FilePath log; |
| 327 file_util::GetTempDir(&log); |
| 328 log.Append(O3D_DEBUG_LOG_FILENAME); |
| 329 |
| 330 InitLogging(log.value().c_str(), |
| 331 logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG, |
| 332 logging::DONT_LOCK_LOG_FILE, |
| 333 logging::APPEND_TO_OLD_LOG_FILE); |
| 334 #endif // O3D_INTERNAL_PLUGIN |
| 335 |
| 336 DLOG(INFO) << "NP_Initialize"; |
| 337 |
| 338 return o3d::PlatformPostNPInitialize(); |
| 339 } |
| 340 |
| 341 NPError EXPORT_SYMBOL OSCALL NP_Shutdown(void) { |
| 342 HANDLE_CRASHES; |
| 343 DLOG(INFO) << "NP_Shutdown"; |
| 344 |
| 345 NPError err = o3d::PlatformPreNPShutdown(); |
| 346 if (err != NPERR_NO_ERROR) { |
| 347 return err; |
| 348 } |
| 349 |
| 350 #if !defined(O3D_INTERNAL_PLUGIN) |
| 351 #if defined(OS_WIN) || defined(OS_MACOSX) |
| 352 if (g_logger) { |
| 353 // Do a last sweep to aggregate metrics before we shut down |
| 354 g_logger->ProcessMetrics(true, false, false); |
| 355 delete g_logger; |
| 356 g_logger = NULL; |
| 357 g_logging_initialized = false; |
| 358 stats_report::g_global_metrics.Uninitialize(); |
| 359 } |
| 360 #endif // OS_WIN || OS_MACOSX |
| 361 |
| 362 CommandLine::Reset(); |
| 363 |
| 364 #ifdef OS_WIN |
| 365 // Strictly speaking, on windows, it's not really necessary to call |
| 366 // Stop(), but we do so for completeness |
| 367 if (g_bluescreen_detector) { |
| 368 g_bluescreen_detector->Stop(); |
| 369 delete g_bluescreen_detector; |
| 370 g_bluescreen_detector = NULL; |
| 371 } |
| 372 #endif // OS_WIN |
| 373 #endif // O3D_INTERNAL_PLUGIN |
| 374 |
| 375 return o3d::PlatformPostNPShutdown(); |
| 376 } |
| 377 |
154 NPError EXPORT_SYMBOL OSCALL NP_GetEntryPoints(NPPluginFuncs *pluginFuncs) { | 378 NPError EXPORT_SYMBOL OSCALL NP_GetEntryPoints(NPPluginFuncs *pluginFuncs) { |
155 HANDLE_CRASHES; | 379 HANDLE_CRASHES; |
156 pluginFuncs->version = 11; | 380 pluginFuncs->version = 11; |
157 pluginFuncs->size = sizeof(*pluginFuncs); | 381 pluginFuncs->size = sizeof(*pluginFuncs); |
158 pluginFuncs->newp = o3d::NPP_New; | 382 pluginFuncs->newp = o3d::NPP_New; |
159 pluginFuncs->destroy = o3d::NPP_Destroy; | 383 pluginFuncs->destroy = o3d::NPP_Destroy; |
160 pluginFuncs->setwindow = o3d::NPP_SetWindow; | 384 pluginFuncs->setwindow = o3d::NPP_SetWindow; |
161 pluginFuncs->newstream = o3d::NPP_NewStream; | 385 pluginFuncs->newstream = o3d::NPP_NewStream; |
162 pluginFuncs->destroystream = o3d::NPP_DestroyStream; | 386 pluginFuncs->destroystream = o3d::NPP_DestroyStream; |
163 pluginFuncs->asfile = o3d::NPP_StreamAsFile; | 387 pluginFuncs->asfile = o3d::NPP_StreamAsFile; |
(...skipping 11 matching lines...) Expand all Loading... |
175 char* NP_GetMIMEDescription(void) { | 399 char* NP_GetMIMEDescription(void) { |
176 return const_cast<char*>(O3D_PLUGIN_NPAPI_MIMETYPE "::O3D MIME"); | 400 return const_cast<char*>(O3D_PLUGIN_NPAPI_MIMETYPE "::O3D MIME"); |
177 } | 401 } |
178 | 402 |
179 } // namespace o3d / extern "C" | 403 } // namespace o3d / extern "C" |
180 | 404 |
181 #if !defined(O3D_INTERNAL_PLUGIN) | 405 #if !defined(O3D_INTERNAL_PLUGIN) |
182 extern "C" { | 406 extern "C" { |
183 NPError EXPORT_SYMBOL NP_GetValue(void *instance, NPPVariable variable, | 407 NPError EXPORT_SYMBOL NP_GetValue(void *instance, NPPVariable variable, |
184 void *value) { | 408 void *value) { |
185 return o3d::NP_GetValue(instance, variable, value); | 409 return o3d::NP_GetValue(variable, value); |
186 } | 410 } |
187 } | 411 } |
188 #endif | 412 #endif |
OLD | NEW |