Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(666)

Side by Side Diff: plugin/mac/main_mac.mm

Issue 4957002: - Check for a NULL PluginObject at all NPAPI entry points. This fixes a crash in Chrome where ... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/o3d/
Patch Set: '' Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « plugin/linux/main_linux.cc ('k') | plugin/win/main_win.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 17 matching lines...) Expand all
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 // This file implements the platform specific parts of the plugin for 33 // This file implements the platform specific parts of the plugin for
34 // the Macintosh platform. 34 // the Macintosh platform.
35 35
36 #include "plugin/cross/main.h" 36 #include "plugin/cross/main.h"
37 37
38 #include "base/at_exit.h"
39 #include "base/command_line.h"
40 #include "base/file_util.h"
41 #include "base/logging.h"
42 #include "base/scoped_ptr.h"
43
44 #import <Cocoa/Cocoa.h> 38 #import <Cocoa/Cocoa.h>
45 #include <Carbon/Carbon.h> 39 #include <Carbon/Carbon.h>
46 #include <OpenGL/OpenGL.h> 40 #include <OpenGL/OpenGL.h>
47 #include <AGL/agl.h> 41 #include <AGL/agl.h>
48 #include <AGL/aglRenderers.h> 42 #include <AGL/aglRenderers.h>
49 43
44 #include "base/logging.h"
50 #include "core/cross/event.h" 45 #include "core/cross/event.h"
51 #include "statsreport/metrics.h" 46 #include "core/mac/display_window_mac.h"
52 #include "plugin/cross/config.h" 47 #include "plugin/cross/config.h"
53 #include "plugin/cross/plugin_logging.h"
54 #include "plugin/cross/plugin_metrics.h" 48 #include "plugin/cross/plugin_metrics.h"
55 #include "plugin/cross/o3d_glue.h"
56 #include "plugin/cross/out_of_memory.h"
57 #include "plugin/cross/whitelist.h"
58 #include "plugin/mac/plugin_mac.h" 49 #include "plugin/mac/plugin_mac.h"
59 #include "plugin/mac/graphics_utils_mac.h" 50 #include "plugin/mac/graphics_utils_mac.h"
60 #include "plugin/mac/fullscreen_window_mac.h" 51 #include "plugin/mac/fullscreen_window_mac.h"
61 #import "plugin/mac/o3d_layer.h" 52 #import "plugin/mac/o3d_layer.h"
62 53
63
64 #if !defined(O3D_INTERNAL_PLUGIN)
65 o3d::PluginLogging* g_logger = NULL;
66 bool g_logging_initialized = false;
67 #endif
68
69 using glue::_o3d::PluginObject; 54 using glue::_o3d::PluginObject;
70 using glue::StreamManager; 55 using glue::StreamManager;
71 using o3d::Bitmap; 56 using o3d::Bitmap;
72 using o3d::DisplayWindowMac; 57 using o3d::DisplayWindowMac;
73 using o3d::Event; 58 using o3d::Event;
74 using o3d::FullscreenWindowMac; 59 using o3d::FullscreenWindowMac;
75 using o3d::Renderer; 60 using o3d::Renderer;
76 61
77 namespace { 62 namespace {
78 // We would normally make this a stack variable in main(), but in a
79 // plugin, that's not possible, so we make it a global. When the DLL is loaded
80 // this it gets constructed and when it is unlooaded it is destructed. Note
81 // that this cannot be done in NP_Initialize and NP_Shutdown because those
82 // calls do not necessarily signify the DLL being loaded and unloaded. If the
83 // DLL is not unloaded then the values of global variables are preserved.
84 base::AtExitManager g_at_exit_manager;
85 63
86 #define CFTIMER 64 #define CFTIMER
87 // #define DEFERRED_DRAW_ON_NULLEVENTS 65 // #define DEFERRED_DRAW_ON_NULLEVENTS
88 66
89 67
90 // Helper that extracts the O3DLayer obj c object from the PluginObject 68 // Helper that extracts the O3DLayer obj c object from the PluginObject
91 // and coerces it to the right type. The code can't live in the PluginObject 69 // and coerces it to the right type. The code can't live in the PluginObject
92 // since it's c++ code and doesn't know about objective c types, and it saves 70 // since it's c++ code and doesn't know about objective c types, and it saves
93 // lots of casts elsewhere in the code. 71 // lots of casts elsewhere in the code.
94 static O3DLayer* ObjO3DLayer(PluginObject* obj) { 72 static O3DLayer* ObjO3DLayer(PluginObject* obj) {
95 return static_cast<O3DLayer*>(obj ? obj->gl_layer_ : nil); 73 return static_cast<O3DLayer*>(obj ? obj->gl_layer_ : nil);
96 } 74 }
97 75
98 void DrawPlugin(PluginObject* obj, bool send_callback, CGContextRef context) { 76 void DrawPlugin(PluginObject* obj, bool send_callback, CGContextRef context) {
99 obj->client()->RenderClient(send_callback); 77 obj->client()->RenderClient(send_callback);
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 nsPluginEventType_GetFocusEvent = (osEvt + 16), 448 nsPluginEventType_GetFocusEvent = (osEvt + 16),
471 nsPluginEventType_LoseFocusEvent, 449 nsPluginEventType_LoseFocusEvent,
472 nsPluginEventType_AdjustCursorEvent, 450 nsPluginEventType_AdjustCursorEvent,
473 nsPluginEventType_MenuCommandEvent, 451 nsPluginEventType_MenuCommandEvent,
474 nsPluginEventType_ClippingChangedEvent, 452 nsPluginEventType_ClippingChangedEvent,
475 nsPluginEventType_ScrollingBeginsEvent, 453 nsPluginEventType_ScrollingBeginsEvent,
476 nsPluginEventType_ScrollingEndsEvent, 454 nsPluginEventType_ScrollingEndsEvent,
477 nsPluginEventType_Idle = 0 455 nsPluginEventType_Idle = 0
478 }; 456 };
479 457
480 NPError InitializePlugin() {
481 #if !defined(O3D_INTERNAL_PLUGIN)
482 if (!o3d::SetupOutOfMemoryHandler())
483 return NPERR_MODULE_LOAD_FAILED_ERROR;
484
485 o3d::InitializeBreakpad();
486
487 #ifdef CFTIMER
488 o3d::gRenderTimer.Start();
489 #endif // CFTIMER
490
491 // Turn on the logging.
492 CommandLine::Init(0, NULL);
493
494 FilePath log;
495 file_util::GetTempDir(&log);
496 log = log.Append("debug.log");
497
498 InitLogging(log.value().c_str(),
499 logging::LOG_TO_BOTH_FILE_AND_SYSTEM_DEBUG_LOG,
500 logging::DONT_LOCK_LOG_FILE,
501 logging::APPEND_TO_OLD_LOG_FILE);
502
503 DLOG(INFO) << "NP_Initialize";
504
505 o3d::SetupOutOfMemoryHandler();
506 #endif // O3D_INTERNAL_PLUGIN
507
508 return NPERR_NO_ERROR;
509 }
510
511 // When to prefer Core Animation. Safari's support in 10.5 was too 458 // When to prefer Core Animation. Safari's support in 10.5 was too
512 // buggy to attempt to use. 459 // buggy to attempt to use.
513 static bool PreferCoreAnimation() { 460 static bool PreferCoreAnimation() {
514 bool isSafari = o3d::metric_browser_type.value() == o3d::BROWSER_NAME_SAFARI; 461 bool isSafari = o3d::metric_browser_type.value() == o3d::BROWSER_NAME_SAFARI;
515 return (!isSafari || o3d::IsMacOSTenSixOrHigher()); 462 return (!isSafari || o3d::IsMacOSTenSixOrHigher());
516 } 463 }
517 464
518 // Negotiates the best plugin drawing and event model, sets the 465 // Negotiates the best plugin drawing and event model, sets the
519 // browser to use that, and updates the PluginObject so we can 466 // browser to use that, and updates the PluginObject so we can
520 // remember which one we chose. We prefer these combinations in the 467 // remember which one we chose. We prefer these combinations in the
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 return NPERR_NO_ERROR; 577 return NPERR_NO_ERROR;
631 } 578 }
632 } // end anonymous namespace 579 } // end anonymous namespace
633 580
634 #if defined(O3D_INTERNAL_PLUGIN) 581 #if defined(O3D_INTERNAL_PLUGIN)
635 namespace o3d { 582 namespace o3d {
636 #else 583 #else
637 extern "C" { 584 extern "C" {
638 #endif 585 #endif
639 586
640 NPError OSCALL NP_Initialize(NPNetscapeFuncs* browserFuncs) {
641 HANDLE_CRASHES;
642 NPError retval = InitializeNPNApi(browserFuncs);
643 if (retval != NPERR_NO_ERROR) return retval;
644 return InitializePlugin();
645 }
646
647 #if !defined(O3D_INTERNAL_PLUGIN) 587 #if !defined(O3D_INTERNAL_PLUGIN)
648 588
649 // Wrapper that discards the return value to match the expected type of 589 // Wrapper that discards the return value to match the expected type of
650 // NPP_ShutdownProcPtr. 590 // NPP_ShutdownProcPtr.
651 void NPP_ShutdownWrapper() { 591 static void NPP_ShutdownWrapper() {
652 NP_Shutdown(); 592 NP_Shutdown();
653 } 593 }
654 594
655 // This code is needed to support browsers based on a slightly dated version 595 // This code is needed to support browsers based on a slightly dated version
656 // of the NPAPI such as Firefox 2, and Camino 1.6. These browsers expect there 596 // of the NPAPI such as Firefox 2, and Camino 1.6. These browsers expect there
657 // to be a main() to call to do basic setup. 597 // to be a main() to call to do basic setup.
658 int main(NPNetscapeFuncs* browserFuncs, 598 int main(NPNetscapeFuncs* browserFuncs,
659 NPPluginFuncs* pluginFuncs, 599 NPPluginFuncs* pluginFuncs,
660 NPP_ShutdownProcPtr* shutdownProc) { 600 NPP_ShutdownProcPtr* shutdownProc) {
661 HANDLE_CRASHES; 601 HANDLE_CRASHES;
662 NPError error = NP_Initialize(browserFuncs); 602 NPError error = NP_Initialize(browserFuncs);
663 if (error == NPERR_NO_ERROR) 603 if (error == NPERR_NO_ERROR)
664 error = NP_GetEntryPoints(pluginFuncs); 604 error = NP_GetEntryPoints(pluginFuncs);
665 *shutdownProc = NPP_ShutdownWrapper; 605 *shutdownProc = NPP_ShutdownWrapper;
666 606
667 return error; 607 return error;
668 } 608 }
669 609
670 #endif // O3D_INTERNAL_PLUGIN 610 #endif // O3D_INTERNAL_PLUGIN
671 611
672 NPError OSCALL NP_Shutdown(void) { 612 } // namespace o3d / extern "C"
613
614 namespace o3d {
615
616 NPError PlatformPreNPInitialize() {
673 #if !defined(O3D_INTERNAL_PLUGIN) 617 #if !defined(O3D_INTERNAL_PLUGIN)
674 HANDLE_CRASHES; 618 o3d::InitializeBreakpad();
675 DLOG(INFO) << "NP_Shutdown";
676 619
677 if (g_logger) { 620 #ifdef CFTIMER
678 // Do a last sweep to aggregate metrics before we shut down 621 o3d::gRenderTimer.Start();
679 g_logger->ProcessMetrics(true, false, false); 622 #endif // CFTIMER
680 delete g_logger; 623 #endif // O3D_INTERNAL_PLUGIN
681 g_logger = NULL;
682 g_logging_initialized = false;
683 stats_report::g_global_metrics.Uninitialize();
684 }
685 624
686 CommandLine::Reset(); 625 return NPERR_NO_ERROR;
626 }
687 627
628 NPError PlatformPostNPInitialize() {
629 return NPERR_NO_ERROR;
630 }
631
632 NPError PlatformPreNPShutdown() {
633 return NPERR_NO_ERROR;
634 }
635
636 NPError PlatformPostNPShutdown() {
637 #if !defined(O3D_INTERNAL_PLUGIN)
688 #ifdef CFTIMER 638 #ifdef CFTIMER
689 o3d::gRenderTimer.Stop(); 639 o3d::gRenderTimer.Stop();
690 #endif 640 #endif
691 641
692 o3d::ShutdownBreakpad(); 642 o3d::ShutdownBreakpad();
693 #endif // O3D_INTERNAL_PLUGIN 643 #endif // O3D_INTERNAL_PLUGIN
694 644
695 return NPERR_NO_ERROR; 645 return NPERR_NO_ERROR;
696 } 646 }
697 647
698 } // namespace o3d / extern "C" 648 NPError PlatformNPPGetValue(PluginObject *obj,
699 649 NPPVariable variable,
700 650 void *value) {
701
702 namespace o3d {
703
704 NPError PlatformNPPGetValue(NPP instance, NPPVariable variable, void *value) {
705 PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
706
707 switch (variable) { 651 switch (variable) {
708 case NPPVpluginCoreAnimationLayer: 652 case NPPVpluginCoreAnimationLayer:
709 if (!ObjO3DLayer(obj)) { 653 if (!ObjO3DLayer(obj)) {
710 // Setup layer 654 // Setup layer
711 O3DLayer* gl_layer = [[[O3DLayer alloc] init] retain]; 655 O3DLayer* gl_layer = [[[O3DLayer alloc] init] retain];
712 656
713 gl_layer.autoresizingMask = 657 gl_layer.autoresizingMask =
714 kCALayerWidthSizable + kCALayerHeightSizable; 658 kCALayerWidthSizable + kCALayerHeightSizable;
715 obj->gl_layer_ = gl_layer; 659 obj->gl_layer_ = gl_layer;
716 660
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
935 } 879 }
936 880
937 break; 881 break;
938 case NPCocoaEventTextInput: 882 case NPCocoaEventTextInput:
939 break; 883 break;
940 } 884 }
941 885
942 return handled; 886 return handled;
943 } 887 }
944 888
945 NPError NPP_New(NPMIMEType pluginType, NPP instance, uint16 mode, int16 argc, 889 NPError PlatformNPPNew(NPP instance, PluginObject *obj) {
946 char* argn[], char* argv[], NPSavedData* saved) { 890 NPError err = Mac_SetBestEventAndDrawingModel(instance, obj);
947 HANDLE_CRASHES;
948
949 NPError err = NPERR_NO_ERROR;
950
951 #if !defined(O3D_INTERNAL_PLUGIN)
952 if (!g_logging_initialized) {
953 o3d::GetUserAgentMetrics(instance);
954 GetUserConfigMetrics();
955 // Create usage stats logs object
956 g_logger = o3d::PluginLogging::InitializeUsageStatsLogging();
957 g_logging_initialized = true;
958 }
959 #endif // O3D_INTERNAL_PLUGIN
960
961 if (!IsDomainAuthorized(instance)) {
962 return NPERR_INVALID_URL;
963 }
964
965 PluginObject* pluginObject = glue::_o3d::PluginObject::Create(
966 instance);
967 instance->pdata = pluginObject;
968 glue::_o3d::InitializeGlue(instance);
969 pluginObject->Init(argc, argn, argv);
970
971 err = Mac_SetBestEventAndDrawingModel(instance,
972 static_cast<PluginObject*>(
973 instance->pdata));
974 if (err != NPERR_NO_ERROR) 891 if (err != NPERR_NO_ERROR)
975 return err; 892 return err;
976 #ifdef CFTIMER 893 #ifdef CFTIMER
977 if (pluginObject->drawing_model_ == NPDrawingModelCoreAnimation) { 894 if (obj->drawing_model_ == NPDrawingModelCoreAnimation) {
978 o3d::gRenderTimer.AddInstance(instance); 895 o3d::gRenderTimer.AddInstance(instance);
979 } 896 }
980 #endif 897 #endif
981 return NPERR_NO_ERROR; 898 return NPERR_NO_ERROR;
982 } 899 }
983 900
984 NPError NPP_Destroy(NPP instance, NPSavedData** save) { 901 NPError PlatformNPPDestroy(NPP instance, PluginObject *obj) {
985 HANDLE_CRASHES;
986 PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
987 if (obj) {
988 #if defined(CFTIMER) 902 #if defined(CFTIMER)
989 o3d::gRenderTimer.RemoveInstance(instance); 903 o3d::gRenderTimer.RemoveInstance(instance);
990 #endif 904 #endif
991 905
992 // TODO(maf) / TODO(kbr): are we leaking AGL / CGL contexts? 906 // TODO(maf) / TODO(kbr): are we leaking AGL / CGL contexts?
993 907
994 if (obj->drawing_model_ == NPDrawingModelCoreAnimation) { 908 if (obj->drawing_model_ == NPDrawingModelCoreAnimation) {
995 O3DLayer* layer = ObjO3DLayer(obj); 909 O3DLayer* layer = ObjO3DLayer(obj);
996 if (layer) { 910 if (layer) {
997 // Prevent the layer from rendering any more. 911 // Prevent the layer from rendering any more.
998 [layer setPluginObject:NULL]; 912 [layer setPluginObject:NULL];
999 }
1000 } 913 }
914 }
1001 915
1002 obj->TearDown(); 916 obj->TearDown();
1003 NPN_ReleaseObject(obj);
1004 instance->pdata = NULL;
1005 }
1006 917
1007 return NPERR_NO_ERROR; 918 return NPERR_NO_ERROR;
1008 } 919 }
1009 920
1010 bool CheckForAGLError() { 921 bool CheckForAGLError() {
1011 return aglGetError() != AGL_NO_ERROR; 922 return aglGetError() != AGL_NO_ERROR;
1012 } 923 }
1013 924
1014 NPError NPP_SetWindow(NPP instance, NPWindow* window) { 925 NPError PlatformNPPSetWindow(NPP instance,
1015 HANDLE_CRASHES; 926 PluginObject *obj,
1016 PluginObject* obj = static_cast<PluginObject*>(instance->pdata); 927 NPWindow* window) {
1017 WindowRef new_window = NULL; 928 WindowRef new_window = NULL;
1018 929
1019 assert(window != NULL); 930 assert(window != NULL);
1020 931
1021 if (window->window == NULL && 932 if (window->window == NULL &&
1022 obj->drawing_model_ != NPDrawingModelCoreGraphics && 933 obj->drawing_model_ != NPDrawingModelCoreGraphics &&
1023 obj->drawing_model_!= NPDrawingModelCoreAnimation) { 934 obj->drawing_model_!= NPDrawingModelCoreAnimation) {
1024 return NPERR_NO_ERROR; 935 return NPERR_NO_ERROR;
1025 } 936 }
1026 937
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
1334 #ifdef CFTIMER 1245 #ifdef CFTIMER
1335 // now that the grahics context is setup, add this instance to the timer 1246 // now that the grahics context is setup, add this instance to the timer
1336 // list so it gets drawn repeatedly 1247 // list so it gets drawn repeatedly
1337 gRenderTimer.AddInstance(instance); 1248 gRenderTimer.AddInstance(instance);
1338 #endif // CFTIMER 1249 #endif // CFTIMER
1339 } 1250 }
1340 1251
1341 return NPERR_NO_ERROR; 1252 return NPERR_NO_ERROR;
1342 } 1253 }
1343 1254
1344 // Called when the browser has finished attempting to stream data to 1255 void PlatformNPPStreamAsFile(StreamManager *stream_manager,
1345 // a file as requested. If fname == NULL the attempt was not successful. 1256 NPStream *stream,
1346 void NPP_StreamAsFile(NPP instance, NPStream* stream, const char* fname) { 1257 const char *fname) {
1347 HANDLE_CRASHES;
1348 PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
1349 StreamManager* stream_manager = obj->stream_manager();
1350
1351 // Some browsers give us an absolute HFS path in fname, some give us an 1258 // Some browsers give us an absolute HFS path in fname, some give us an
1352 // absolute Posix path, so convert to Posix if needed. 1259 // absolute Posix path, so convert to Posix if needed.
1353 if ((!fname) || (fname[0] == '/') || !fname[0]) { 1260 if ((!fname) || (fname[0] == '/') || !fname[0]) {
1354 stream_manager->SetStreamFile(stream, fname); 1261 stream_manager->SetStreamFile(stream, fname);
1355 } else { 1262 } else {
1356 const char* converted_fname = CreatePosixFilePathFromHFSFilePath(fname); 1263 const char* converted_fname = CreatePosixFilePathFromHFSFilePath(fname);
1357 if (converted_fname == NULL) 1264 if (converted_fname == NULL)
1358 return; // TODO should also log error if we ever get here 1265 return; // TODO should also log error if we ever get here
1359 stream_manager->SetStreamFile(stream, converted_fname); 1266 stream_manager->SetStreamFile(stream, converted_fname);
1360 delete converted_fname; 1267 delete converted_fname;
1361 } 1268 }
1362 } 1269 }
1363 1270
1364 int16 NPP_HandleEvent(NPP instance, void* event) { 1271 int16 PlatformNPPHandleEvent(NPP instance, PluginObject *obj, void *event) {
1365 HANDLE_CRASHES;
1366 PluginObject* obj = static_cast<PluginObject*>(instance->pdata);
1367 if (obj->event_model_ == NPEventModelCarbon) { 1272 if (obj->event_model_ == NPEventModelCarbon) {
1368 EventRecord* theEvent = static_cast<EventRecord*>(event); 1273 EventRecord* theEvent = static_cast<EventRecord*>(event);
1369 return HandleMacEvent(theEvent, instance) ? 1 : 0; 1274 return HandleMacEvent(theEvent, instance) ? 1 : 0;
1370 } else if (obj->event_model_ == NPEventModelCocoa){ 1275 } else if (obj->event_model_ == NPEventModelCocoa){
1371 return HandleCocoaEvent(instance, (NPCocoaEvent*)event, true) ? 1 : 0; 1276 return HandleCocoaEvent(instance, (NPCocoaEvent*)event, true) ? 1 : 0;
1372 } 1277 }
1373 return 0; 1278 return 0;
1374 } 1279 }
1375 1280
1376 } // namespace o3d 1281 } // namespace o3d
OLDNEW
« no previous file with comments | « plugin/linux/main_linux.cc ('k') | plugin/win/main_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698