diff options
Diffstat (limited to 'Source/WebKit2/WebProcess/Plugins')
14 files changed, 264 insertions, 35 deletions
diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp index 4d82cff01..b20743213 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.cpp @@ -548,6 +548,38 @@ bool NetscapePlugin::allowPopups() const return false; } +#if PLUGIN_ARCHITECTURE(MAC) +static bool isTransparentSilverlightBackgroundValue(const String& lowercaseBackgroundValue) +{ + // This checks if the background color value is transparent, according to + // the forumat documented at http://msdn.microsoft.com/en-us/library/cc838148(VS.95).aspx + if (lowercaseBackgroundValue.startsWith('#')) { + if (lowercaseBackgroundValue.length() == 5 && lowercaseBackgroundValue[1] != 'f') { + // An 8-bit RGB value with alpha transparency, in the form #ARGB. + return true; + } + + if (lowercaseBackgroundValue.length() == 9 && !(lowercaseBackgroundValue[1] == 'f' && lowercaseBackgroundValue[2] == 'f')) { + // A 16-bit RGB value with alpha transparency, in the form #AARRGGBB. + return true; + } + } else if (lowercaseBackgroundValue.startsWith("sc#")) { + Vector<String> components; + lowercaseBackgroundValue.substring(3).split(",", components); + + // An ScRGB value with alpha transparency, in the form sc#A,R,G,B. + if (components.size() == 4) { + if (components[0].toDouble() < 1) + return true; + } + } else if (lowercaseBackgroundValue == "transparent") + return true; + + // This is an opaque color. + return false; +} +#endif + bool NetscapePlugin::initialize(const Parameters& parameters) { uint16_t mode = parameters.isFullFramePlugin ? NP_FULL : NP_EMBED; @@ -581,10 +613,10 @@ bool NetscapePlugin::initialize(const Parameters& parameters) } #if PLUGIN_ARCHITECTURE(MAC) - if (m_pluginModule->pluginQuirks().contains(PluginQuirks::MakeTransparentIfBackgroundAttributeExists)) { + if (m_pluginModule->pluginQuirks().contains(PluginQuirks::MakeOpaqueUnlessTransparentSilverlightBackgroundAttributeExists)) { for (size_t i = 0; i < parameters.names.size(); ++i) { if (equalIgnoringCase(parameters.names[i], "background")) { - setIsTransparent(true); + setIsTransparent(isTransparentSilverlightBackgroundValue(parameters.values[i].lower())); break; } } diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h index 1c49c6032..8591892b8 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/NetscapePlugin.h @@ -54,6 +54,10 @@ public: static PassRefPtr<NetscapePlugin> fromNPP(NPP); + // In-process NetscapePlugins don't support asynchronous initialization. + virtual void waitForAsynchronousInitialization() { } + virtual bool isBeingAsynchronouslyInitialized() const { return false; } + #if PLATFORM(MAC) NPError setDrawingModel(NPDrawingModel); NPError setEventModel(NPEventModel); diff --git a/Source/WebKit2/WebProcess/Plugins/Netscape/mac/NetscapePluginMac.mm b/Source/WebKit2/WebProcess/Plugins/Netscape/mac/NetscapePluginMac.mm index f1fa2f646..8a447df31 100644 --- a/Source/WebKit2/WebProcess/Plugins/Netscape/mac/NetscapePluginMac.mm +++ b/Source/WebKit2/WebProcess/Plugins/Netscape/mac/NetscapePluginMac.mm @@ -1057,6 +1057,27 @@ PlatformLayer* NetscapePlugin::pluginLayer() return static_cast<PlatformLayer*>(m_pluginLayer.get()); } +static void makeCGLPresentLayerOpaque(CALayer *pluginRootLayer) +{ + // We look for a layer that's the only sublayer of the root layer that is an instance + // of the CGLPresentLayer class which in turn is a subclass of CAOpenGLLayer and make + // it opaque if all these conditions hold. + + NSArray *sublayers = [pluginRootLayer sublayers]; + if ([sublayers count] != 1) + return; + + Class cglPresentLayerClass = NSClassFromString(@"CGLPresentLayer"); + if (![cglPresentLayerClass isSubclassOfClass:[CAOpenGLLayer class]]) + return; + + CALayer *layer = [sublayers objectAtIndex:0]; + if (![layer isKindOfClass:cglPresentLayerClass]) + return; + + [layer setOpaque:YES]; +} + void NetscapePlugin::updatePluginLayer() { if (m_drawingModel != NPDrawingModelCoreAnimation) @@ -1086,6 +1107,10 @@ void NetscapePlugin::updatePluginLayer() m_pluginLayer = reinterpret_cast<CALayer *>(value); else m_pluginLayer.adoptNS(reinterpret_cast<CALayer *>(value)); + + if (m_pluginModule->pluginQuirks().contains(PluginQuirks::MakeOpaqueUnlessTransparentSilverlightBackgroundAttributeExists) && + !m_isTransparent) + makeCGLPresentLayerOpaque(m_pluginLayer.get()); } #ifndef NP_NO_CARBON diff --git a/Source/WebKit2/WebProcess/Plugins/PDF/BuiltInPDFView.h b/Source/WebKit2/WebProcess/Plugins/PDF/BuiltInPDFView.h index 6d11c8552..8a7c28a5b 100644 --- a/Source/WebKit2/WebProcess/Plugins/PDF/BuiltInPDFView.h +++ b/Source/WebKit2/WebProcess/Plugins/PDF/BuiltInPDFView.h @@ -50,6 +50,10 @@ public: static WebCore::PluginInfo pluginInfo(); + // In-process PDFViews don't support asynchronous initialization. + virtual void waitForAsynchronousInitialization() { } + virtual bool isBeingAsynchronouslyInitialized() const { return false; } + private: explicit BuiltInPDFView(WebFrame*); diff --git a/Source/WebKit2/WebProcess/Plugins/Plugin.h b/Source/WebKit2/WebProcess/Plugins/Plugin.h index 5be84f476..b91174f9e 100644 --- a/Source/WebKit2/WebProcess/Plugins/Plugin.h +++ b/Source/WebKit2/WebProcess/Plugins/Plugin.h @@ -83,6 +83,10 @@ public: // Sets the active plug-in controller and initializes the plug-in. bool initialize(PluginController*, const Parameters&); + // Forces synchronous initialization of a plugin previously initialized asynchronously. + virtual void waitForAsynchronousInitialization() = 0; + virtual bool isBeingAsynchronouslyInitialized() const = 0; + // Destroys the plug-in. void destroyPlugin(); diff --git a/Source/WebKit2/WebProcess/Plugins/PluginController.h b/Source/WebKit2/WebProcess/Plugins/PluginController.h index 42c29595e..6682ba020 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginController.h +++ b/Source/WebKit2/WebProcess/Plugins/PluginController.h @@ -138,6 +138,15 @@ public: // Returns whether private browsing is enabled. virtual bool isPrivateBrowsingEnabled() = 0; + + // Returns whether or not asynchronous plugin initialization is enabled. + virtual bool asynchronousPluginInitializationEnabled() const { return false; } + + // Returns whether or not asynchronous plugin initialization should be attempted for all plugins. + virtual bool asynchronousPluginInitializationEnabledForAllPlugins() const { return false; } + + // Returns the articifical plugin delay to use for testing of asynchronous plugin initialization. + virtual bool artificialPluginInitializationDelayEnabled() const { return false; } // Increments a counter that prevents the plug-in from being destroyed. virtual void protectPluginFromDestruction() = 0; @@ -151,6 +160,12 @@ public: virtual void windowedPluginGeometryDidChange(const WebCore::IntRect& frameRect, const WebCore::IntRect& clipRect, uint64_t windowID) = 0; #endif + // Called when the a plug-in instance is successfully initialized, either synchronously or asynchronously. + virtual void didInitializePlugin() = 0; + + // Called when the a plug-in instance fails to initialized, either synchronously or asynchronously. + virtual void didFailToInitializePlugin() = 0; + // Helper class for delaying destruction of a plug-in. class PluginDestructionProtector { public: diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.cpp b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.cpp index 8339ad45c..cc313d2e4 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.cpp +++ b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.cpp @@ -73,9 +73,10 @@ static double defaultSyncMessageTimeout(const String& pluginPath) return syncMessageTimeout; } -PluginProcessConnection::PluginProcessConnection(PluginProcessConnectionManager* pluginProcessConnectionManager, const String& pluginPath, CoreIPC::Connection::Identifier connectionIdentifier) +PluginProcessConnection::PluginProcessConnection(PluginProcessConnectionManager* pluginProcessConnectionManager, const String& pluginPath, CoreIPC::Connection::Identifier connectionIdentifier, bool supportsAsynchronousPluginInitialization) : m_pluginProcessConnectionManager(pluginProcessConnectionManager) , m_pluginPath(pluginPath) + , m_supportsAsynchronousPluginInitialization(supportsAsynchronousPluginInitialization) { m_connection = CoreIPC::Connection::createClientConnection(connectionIdentifier, this, WebProcess::shared().runLoop()); diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.h b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.h index 61c4ac2a5..bc866d10c 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.h +++ b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.h @@ -43,9 +43,9 @@ class PluginProxy; class PluginProcessConnection : public RefCounted<PluginProcessConnection>, CoreIPC::Connection::Client { public: - static PassRefPtr<PluginProcessConnection> create(PluginProcessConnectionManager* pluginProcessConnectionManager, const String& pluginPath, CoreIPC::Connection::Identifier connectionIdentifier) + static PassRefPtr<PluginProcessConnection> create(PluginProcessConnectionManager* pluginProcessConnectionManager, const String& pluginPath, CoreIPC::Connection::Identifier connectionIdentifier, bool supportsAsynchronousPluginInitialization) { - return adoptRef(new PluginProcessConnection(pluginProcessConnectionManager, pluginPath, connectionIdentifier)); + return adoptRef(new PluginProcessConnection(pluginProcessConnectionManager, pluginPath, connectionIdentifier, supportsAsynchronousPluginInitialization)); } ~PluginProcessConnection(); @@ -58,8 +58,10 @@ public: NPRemoteObjectMap* npRemoteObjectMap() const { return m_npRemoteObjectMap.get(); } + bool supportsAsynchronousPluginInitialization() const { return m_supportsAsynchronousPluginInitialization; } + private: - PluginProcessConnection(PluginProcessConnectionManager* pluginProcessConnectionManager, const String& pluginPath, CoreIPC::Connection::Identifier connectionIdentifier); + PluginProcessConnection(PluginProcessConnectionManager*, const String& pluginPath, CoreIPC::Connection::Identifier connectionIdentifier, bool supportsAsynchronousInitialization); // CoreIPC::Connection::Client virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); @@ -82,6 +84,8 @@ private: HashMap<uint64_t, PluginProxy*> m_plugins; RefPtr<NPRemoteObjectMap> m_npRemoteObjectMap; + + bool m_supportsAsynchronousPluginInitialization; }; } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProcessConnectionManager.cpp b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnectionManager.cpp index fd1906d7a..b77050992 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginProcessConnectionManager.cpp +++ b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnectionManager.cpp @@ -57,13 +57,14 @@ PluginProcessConnection* PluginProcessConnectionManager::getPluginProcessConnect } CoreIPC::Attachment encodedConnectionIdentifier; + bool supportsAsynchronousInitialization; if (!WebProcess::shared().connection()->sendSync(Messages::WebProcessProxy::GetPluginProcessConnection(pluginPath), - Messages::WebProcessProxy::GetPluginProcessConnection::Reply(encodedConnectionIdentifier), 0)) + Messages::WebProcessProxy::GetPluginProcessConnection::Reply(encodedConnectionIdentifier, supportsAsynchronousInitialization), 0)) return 0; #if PLATFORM(MAC) - CoreIPC::Connection::Identifier connectionIdentifier = encodedConnectionIdentifier.port(); - if (!connectionIdentifier) + CoreIPC::Connection::Identifier connectionIdentifier(encodedConnectionIdentifier.port()); + if (CoreIPC::Connection::identifierIsNull(connectionIdentifier)) return 0; #elif USE(UNIX_DOMAIN_SOCKETS) CoreIPC::Connection::Identifier connectionIdentifier = encodedConnectionIdentifier.fileDescriptor(); @@ -71,7 +72,7 @@ PluginProcessConnection* PluginProcessConnectionManager::getPluginProcessConnect return 0; #endif - RefPtr<PluginProcessConnection> pluginProcessConnection = PluginProcessConnection::create(this, pluginPath, connectionIdentifier); + RefPtr<PluginProcessConnection> pluginProcessConnection = PluginProcessConnection::create(this, pluginPath, connectionIdentifier, supportsAsynchronousInitialization); m_pluginProcessConnections.append(pluginProcessConnection); { diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProxy.cpp b/Source/WebKit2/WebProcess/Plugins/PluginProxy.cpp index d4a3549f4..17db25708 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginProxy.cpp +++ b/Source/WebKit2/WebProcess/Plugins/PluginProxy.cpp @@ -68,6 +68,7 @@ PluginProxy::PluginProxy(const String& pluginPath) , m_waitingForPaintInResponseToUpdate(false) , m_wantsWheelEvents(false) , m_remoteLayerClientID(0) + , m_waitingOnAsynchronousInitialization(false) { } @@ -93,38 +94,112 @@ bool PluginProxy::initialize(const Parameters& parameters) m_connection->addPluginProxy(this); // Ask the plug-in process to create a plug-in. - PluginCreationParameters creationParameters; - creationParameters.pluginInstanceID = m_pluginInstanceID; - creationParameters.windowNPObjectID = windowNPObjectID(); - creationParameters.parameters = parameters; - creationParameters.userAgent = controller()->userAgent(); - creationParameters.contentsScaleFactor = contentsScaleFactor(); - creationParameters.isPrivateBrowsingEnabled = controller()->isPrivateBrowsingEnabled(); + m_pendingPluginCreationParameters = adoptPtr(new PluginCreationParameters); + + m_pendingPluginCreationParameters->pluginInstanceID = m_pluginInstanceID; + m_pendingPluginCreationParameters->windowNPObjectID = windowNPObjectID(); + m_pendingPluginCreationParameters->parameters = parameters; + m_pendingPluginCreationParameters->userAgent = controller()->userAgent(); + m_pendingPluginCreationParameters->contentsScaleFactor = contentsScaleFactor(); + m_pendingPluginCreationParameters->isPrivateBrowsingEnabled = controller()->isPrivateBrowsingEnabled(); + m_pendingPluginCreationParameters->artificialPluginInitializationDelayEnabled = controller()->artificialPluginInitializationDelayEnabled(); + #if USE(ACCELERATED_COMPOSITING) - creationParameters.isAcceleratedCompositingEnabled = controller()->isAcceleratedCompositingEnabled(); + m_pendingPluginCreationParameters->isAcceleratedCompositingEnabled = controller()->isAcceleratedCompositingEnabled(); #endif + if (!canInitializeAsynchronously()) + return initializeSynchronously(); + + // Remember that we tried to create this plug-in asynchronously in case we need to create it synchronously later. + m_waitingOnAsynchronousInitialization = true; + PluginCreationParameters creationParameters(*m_pendingPluginCreationParameters.get()); + m_connection->connection()->send(Messages::WebProcessConnection::CreatePluginAsynchronously(creationParameters), m_pluginInstanceID); + return true; +} + +bool PluginProxy::canInitializeAsynchronously() const +{ + return controller()->asynchronousPluginInitializationEnabled() && (m_connection->supportsAsynchronousPluginInitialization() || controller()->asynchronousPluginInitializationEnabledForAllPlugins()); +} + +void PluginProxy::waitForAsynchronousInitialization() +{ + ASSERT(!m_isStarted); + ASSERT(m_waitingOnAsynchronousInitialization); + + initializeSynchronously(); +} + +bool PluginProxy::initializeSynchronously() +{ + ASSERT(m_pendingPluginCreationParameters); + + m_pendingPluginCreationParameters->asynchronousCreationIncomplete = m_waitingOnAsynchronousInitialization; bool result = false; bool wantsWheelEvents = false; uint32_t remoteLayerClientID = 0; + + PluginCreationParameters parameters(*m_pendingPluginCreationParameters.get()); - if (!m_connection->connection()->sendSync(Messages::WebProcessConnection::CreatePlugin(creationParameters), Messages::WebProcessConnection::CreatePlugin::Reply(result, wantsWheelEvents, remoteLayerClientID), 0) || !result) { - m_connection->removePluginProxy(this); - return false; - } + if (!m_connection->connection()->sendSync(Messages::WebProcessConnection::CreatePlugin(parameters), Messages::WebProcessConnection::CreatePlugin::Reply(result, wantsWheelEvents, remoteLayerClientID), 0) || !result) + didFailToCreatePluginInternal(); + else + didCreatePluginInternal(wantsWheelEvents, remoteLayerClientID); + + return result; +} +void PluginProxy::didCreatePlugin(bool wantsWheelEvents, uint32_t remoteLayerClientID) +{ + // We might have tried to create the plug-in sychronously while waiting on the asynchronous reply, + // in which case we should ignore this message. + if (!m_waitingOnAsynchronousInitialization) + return; + + didCreatePluginInternal(wantsWheelEvents, remoteLayerClientID); +} + +void PluginProxy::didFailToCreatePlugin() +{ + // We might have tried to create the plug-in sychronously while waiting on the asynchronous reply, + // in which case we should ignore this message. + if (!m_waitingOnAsynchronousInitialization) + return; + + didFailToCreatePluginInternal(); +} + +void PluginProxy::didCreatePluginInternal(bool wantsWheelEvents, uint32_t remoteLayerClientID) +{ m_wantsWheelEvents = wantsWheelEvents; m_remoteLayerClientID = remoteLayerClientID; m_isStarted = true; + controller()->didInitializePlugin(); - return true; + // Whether synchronously or asynchronously, this plug-in was created and we shouldn't need to remember + // anything about how. + m_pendingPluginCreationParameters.clear(); + m_waitingOnAsynchronousInitialization = false; } -void PluginProxy::destroy() +void PluginProxy::didFailToCreatePluginInternal() { - ASSERT(m_isStarted); + // Calling out to the connection and the controller could potentially cause the plug-in proxy to go away, so protect it here. + RefPtr<PluginProxy> protect(this); + + m_connection->removePluginProxy(this); + controller()->didFailToInitializePlugin(); + + // Whether synchronously or asynchronously, this plug-in failed to create and we shouldn't need to remember + // anything about how. + m_pendingPluginCreationParameters.clear(); + m_waitingOnAsynchronousInitialization = false; +} - m_connection->connection()->sendSync(Messages::WebProcessConnection::DestroyPlugin(m_pluginInstanceID), Messages::WebProcessConnection::DestroyPlugin::Reply(), 0); +void PluginProxy::destroy() +{ + m_connection->connection()->sendSync(Messages::WebProcessConnection::DestroyPlugin(m_pluginInstanceID, m_waitingOnAsynchronousInitialization), Messages::WebProcessConnection::DestroyPlugin::Reply(), 0); m_isStarted = false; diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProxy.h b/Source/WebKit2/WebProcess/Plugins/PluginProxy.h index be07caa85..c0ca116b0 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginProxy.h +++ b/Source/WebKit2/WebProcess/Plugins/PluginProxy.h @@ -49,6 +49,8 @@ class ShareableBitmap; class NPVariantData; class PluginProcessConnection; +struct PluginCreationParameters; + class PluginProxy : public Plugin { public: static PassRefPtr<PluginProxy> create(const String& pluginPath); @@ -60,11 +62,16 @@ public: void didReceivePluginProxyMessage(CoreIPC::Connection*, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments); void didReceiveSyncPluginProxyMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, OwnPtr<CoreIPC::ArgumentEncoder>&); + bool isBeingAsynchronouslyInitialized() const { return m_waitingOnAsynchronousInitialization; } + private: explicit PluginProxy(const String& pluginPath); // Plugin virtual bool initialize(const Parameters&); + bool initializeSynchronously(); + + virtual void waitForAsynchronousInitialization(); virtual void destroy(); virtual void paint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect); virtual PassRefPtr<ShareableBitmap> snapshot(); @@ -141,6 +148,14 @@ private: void windowedPluginGeometryDidChange(const WebCore::IntRect& frameRect, const WebCore::IntRect& clipRect, uint64_t windowID); #endif + bool canInitializeAsynchronously() const; + + void didCreatePlugin(bool wantsWheelEvents, uint32_t remoteLayerClientID); + void didFailToCreatePlugin(); + + void didCreatePluginInternal(bool wantsWheelEvents, uint32_t remoteLayerClientID); + void didFailToCreatePluginInternal(); + String m_pluginPath; RefPtr<PluginProcessConnection> m_connection; @@ -174,6 +189,9 @@ private: // The client ID for the CA layer in the plug-in process. Will be 0 if the plug-in is not a CA plug-in. uint32_t m_remoteLayerClientID; + + OwnPtr<PluginCreationParameters> m_pendingPluginCreationParameters; + bool m_waitingOnAsynchronousInitialization; #if PLATFORM(MAC) RetainPtr<CALayer> m_pluginLayer; diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProxy.messages.in b/Source/WebKit2/WebProcess/Plugins/PluginProxy.messages.in index a2ef31965..453c0f1d2 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginProxy.messages.in +++ b/Source/WebKit2/WebProcess/Plugins/PluginProxy.messages.in @@ -74,6 +74,12 @@ messages -> PluginProxy { # Update geometry of windowed plugin widget WindowedPluginGeometryDidChange(WebCore::IntRect frameRect, WebCore::IntRect clipRect, uint64_t windowID) #endif + + # Tells the WebProcess that the plug-in was successfully initialized asynchronously + DidCreatePlugin(bool wantsWheelEvents, uint32_t remoteLayerClientID) -> () + + # Tells the WebProcess that the plug-in failed to initialize. + DidFailToCreatePlugin() -> () } #endif diff --git a/Source/WebKit2/WebProcess/Plugins/PluginView.cpp b/Source/WebKit2/WebProcess/Plugins/PluginView.cpp index 072a69c9c..d07f8b79d 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginView.cpp +++ b/Source/WebKit2/WebProcess/Plugins/PluginView.cpp @@ -260,6 +260,7 @@ PluginView::PluginView(PassRefPtr<HTMLPlugInElement> pluginElement, PassRefPtr<P , m_webPage(webPage(m_pluginElement.get())) , m_parameters(parameters) , m_isInitialized(false) + , m_isWaitingForSynchronousInitialization(false) , m_isWaitingUntilMediaCanStart(false) , m_isBeingDestroyed(false) , m_pendingURLRequestsTimer(RunLoop::main(), this, &PluginView::pendingURLRequestsTimerFired) @@ -285,7 +286,7 @@ PluginView::~PluginView() for (FrameLoadMap::iterator it = m_pendingFrameLoads.begin(), end = m_pendingFrameLoads.end(); it != end; ++it) it->first->setLoadListener(0); - if (m_plugin && m_isInitialized) { + if (m_plugin) { m_isBeingDestroyed = true; m_plugin->destroyPlugin(); m_isBeingDestroyed = false; @@ -487,15 +488,20 @@ void PluginView::initializePlugin() } } } - - if (!m_plugin->initialize(this, m_parameters)) { - // We failed to initialize the plug-in. - m_plugin = 0; - m_webPage->send(Messages::WebPageProxy::DidFailToInitializePlugin(m_parameters.mimeType)); - return; - } + m_plugin->initialize(this, m_parameters); + // Plug-in initialization continued in didFailToInitializePlugin() or didInitializePlugin(). +} + +void PluginView::didFailToInitializePlugin() +{ + m_plugin = 0; + m_webPage->send(Messages::WebPageProxy::DidFailToInitializePlugin(m_parameters.mimeType)); +} + +void PluginView::didInitializePlugin() +{ m_isInitialized = true; #if PLATFORM(MAC) @@ -539,6 +545,19 @@ PlatformLayer* PluginView::platformLayer() const JSObject* PluginView::scriptObject(JSGlobalObject* globalObject) { + // If we're already waiting for synchronous initialization of the plugin, + // calls to scriptObject() are from the plug-in itself and need to return 0; + if (m_isWaitingForSynchronousInitialization) + return 0; + + // If the plug-in exists but is not initialized then we're still initializing asynchronously. + // We need to wait here until initialization has either succeeded or failed. + if (m_plugin->isBeingAsynchronouslyInitialized()) { + m_isWaitingForSynchronousInitialization = true; + m_plugin->waitForAsynchronousInitialization(); + m_isWaitingForSynchronousInitialization = false; + } + // The plug-in can be null here if it failed to initialize. if (!m_isInitialized || !m_plugin) return 0; @@ -1250,6 +1269,21 @@ bool PluginView::isPrivateBrowsingEnabled() return settings->privateBrowsingEnabled(); } +bool PluginView::asynchronousPluginInitializationEnabled() const +{ + return m_webPage->asynchronousPluginInitializationEnabled(); +} + +bool PluginView::asynchronousPluginInitializationEnabledForAllPlugins() const +{ + return m_webPage->asynchronousPluginInitializationEnabledForAllPlugins(); +} + +bool PluginView::artificialPluginInitializationDelayEnabled() const +{ + return m_webPage->artificialPluginInitializationDelayEnabled(); +} + void PluginView::protectPluginFromDestruction() { if (!m_isBeingDestroyed) diff --git a/Source/WebKit2/WebProcess/Plugins/PluginView.h b/Source/WebKit2/WebProcess/Plugins/PluginView.h index f101b2f4f..a6a056ccd 100644 --- a/Source/WebKit2/WebProcess/Plugins/PluginView.h +++ b/Source/WebKit2/WebProcess/Plugins/PluginView.h @@ -80,7 +80,6 @@ private: virtual ~PluginView(); void initializePlugin(); - void destroyPlugin(); void viewGeometryDidChange(); void viewVisibilityDidChange(); @@ -164,6 +163,9 @@ private: virtual void setCookiesForURL(const String& urlString, const String& cookieString); virtual bool getAuthenticationInfo(const WebCore::ProtectionSpace&, String& username, String& password); virtual bool isPrivateBrowsingEnabled(); + virtual bool asynchronousPluginInitializationEnabled() const; + virtual bool asynchronousPluginInitializationEnabledForAllPlugins() const; + virtual bool artificialPluginInitializationDelayEnabled() const; virtual void protectPluginFromDestruction(); virtual void unprotectPluginFromDestruction(); #if PLUGIN_ARCHITECTURE(X11) @@ -171,6 +173,9 @@ private: virtual void windowedPluginGeometryDidChange(const WebCore::IntRect& frameRect, const WebCore::IntRect& clipRect, uint64_t windowID); #endif + virtual void didInitializePlugin(); + virtual void didFailToInitializePlugin(); + // WebFrame::LoadListener virtual void didFinishLoad(WebFrame*); virtual void didFailLoad(WebFrame*, bool wasCancelled); @@ -181,6 +186,7 @@ private: Plugin::Parameters m_parameters; bool m_isInitialized; + bool m_isWaitingForSynchronousInitialization; bool m_isWaitingUntilMediaCanStart; bool m_isBeingDestroyed; |
