diff options
| author | Simon Hausmann <simon.hausmann@nokia.com> | 2012-01-06 14:44:00 +0100 |
|---|---|---|
| committer | Simon Hausmann <simon.hausmann@nokia.com> | 2012-01-06 14:44:00 +0100 |
| commit | 40736c5763bf61337c8c14e16d8587db021a87d4 (patch) | |
| tree | b17a9c00042ad89cb1308e2484491799aa14e9f8 /Source/WebKit2/PluginProcess | |
| download | qtwebkit-40736c5763bf61337c8c14e16d8587db021a87d4.tar.gz | |
Imported WebKit commit 2ea9d364d0f6efa8fa64acf19f451504c59be0e4 (http://svn.webkit.org/repository/webkit/trunk@104285)
Diffstat (limited to 'Source/WebKit2/PluginProcess')
25 files changed, 3040 insertions, 0 deletions
diff --git a/Source/WebKit2/PluginProcess/Info.plist b/Source/WebKit2/PluginProcess/Info.plist new file mode 100644 index 000000000..94b0059f5 --- /dev/null +++ b/Source/WebKit2/PluginProcess/Info.plist @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> +<dict> + <key>CFBundleExecutable</key> + <string>${PRODUCT_NAME}</string> + <key>CFBundleGetInfoString</key> + <string>${BUNDLE_VERSION}, Copyright 2003-2012 Apple Inc.</string> + <key>CFBundleIdentifier</key> + <string>com.apple.WebKit.${PRODUCT_NAME}</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundleName</key> + <string>${PRODUCT_NAME}</string> + <key>CFBundlePackageType</key> + <string>APPL</string> + <key>CFBundleShortVersionString</key> + <string>${SHORT_VERSION_STRING}</string> + <key>CFBundleVersion</key> + <string>${BUNDLE_VERSION}</string> + <key>LSFileQuarantineEnabled</key> + <true/> + <key>LSMinimumSystemVersion</key> + <string>${MACOSX_DEPLOYMENT_TARGET}</string> + <key>LSUIElement</key> + <true/> + <key>NSPrincipalClass</key> + <string>NSApplication</string> +</dict> +</plist> diff --git a/Source/WebKit2/PluginProcess/PluginControllerProxy.cpp b/Source/WebKit2/PluginProcess/PluginControllerProxy.cpp new file mode 100644 index 000000000..b548f8126 --- /dev/null +++ b/Source/WebKit2/PluginProcess/PluginControllerProxy.cpp @@ -0,0 +1,626 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PluginControllerProxy.h" + +#if ENABLE(PLUGIN_PROCESS) + +#include "DataReference.h" +#include "NPObjectProxy.h" +#include "NPRemoteObjectMap.h" +#include "NPRuntimeUtilities.h" +#include "NPVariantData.h" +#include "NetscapePlugin.h" +#include "PluginCreationParameters.h" +#include "PluginProcess.h" +#include "PluginProxyMessages.h" +#include "ShareableBitmap.h" +#include "WebCoreArgumentCoders.h" +#include "WebProcessConnection.h" +#include <WebCore/GraphicsContext.h> +#include <WebCore/IdentifierRep.h> +#include <WebCore/NotImplemented.h> +#include <wtf/text/WTFString.h> + +using namespace WebCore; + +namespace WebKit { + +PassOwnPtr<PluginControllerProxy> PluginControllerProxy::create(WebProcessConnection* connection, const PluginCreationParameters& creationParameters) +{ + return adoptPtr(new PluginControllerProxy(connection, creationParameters)); +} + +PluginControllerProxy::PluginControllerProxy(WebProcessConnection* connection, const PluginCreationParameters& creationParameters) + : m_connection(connection) + , m_pluginInstanceID(creationParameters.pluginInstanceID) + , m_userAgent(creationParameters.userAgent) + , m_isPrivateBrowsingEnabled(creationParameters.isPrivateBrowsingEnabled) +#if USE(ACCELERATED_COMPOSITING) + , m_isAcceleratedCompositingEnabled(creationParameters.isAcceleratedCompositingEnabled) +#endif + , m_paintTimer(RunLoop::main(), this, &PluginControllerProxy::paint) + , m_pluginDestructionProtectCount(0) + , m_pluginDestroyTimer(RunLoop::main(), this, &PluginControllerProxy::destroy) + , m_pluginCreationParameters(0) + , m_waitingForDidUpdate(false) + , m_pluginCanceledManualStreamLoad(false) +#if PLATFORM(MAC) + , m_isComplexTextInputEnabled(false) +#endif + , m_contentsScaleFactor(creationParameters.contentsScaleFactor) + , m_windowNPObject(0) + , m_pluginElementNPObject(0) +{ +} + +PluginControllerProxy::~PluginControllerProxy() +{ + ASSERT(!m_plugin); + + if (m_windowNPObject) + releaseNPObject(m_windowNPObject); + + if (m_pluginElementNPObject) + releaseNPObject(m_pluginElementNPObject); +} + +bool PluginControllerProxy::initialize(const PluginCreationParameters& creationParameters) +{ + ASSERT(!m_plugin); + + m_plugin = NetscapePlugin::create(PluginProcess::shared().netscapePluginModule()); + if (!m_plugin) { + // This will delete the plug-in controller proxy object. + m_connection->removePluginControllerProxy(this, 0); + return false; + } + + m_windowNPObject = m_connection->npRemoteObjectMap()->createNPObjectProxy(creationParameters.windowNPObjectID, m_plugin.get()); + ASSERT(m_windowNPObject); + + m_pluginCreationParameters = &creationParameters; + bool returnValue = m_plugin->initialize(this, creationParameters.parameters); + m_pluginCreationParameters = 0; + + if (!returnValue) { + // Get the plug-in so we can pass it to removePluginControllerProxy. The pointer is only + // used as an identifier so it's OK to just get a weak reference. + Plugin* plugin = m_plugin.get(); + + m_plugin = 0; + + // This will delete the plug-in controller proxy object. + m_connection->removePluginControllerProxy(this, plugin); + return false; + } + + platformInitialize(); + + return true; +} + +void PluginControllerProxy::destroy() +{ + ASSERT(m_plugin); + + if (m_pluginDestructionProtectCount) { + // We have plug-in code on the stack so we can't destroy it right now. + // Destroy it later. + m_pluginDestroyTimer.startOneShot(0); + return; + } + + // Get the plug-in so we can pass it to removePluginControllerProxy. The pointer is only + // used as an identifier so it's OK to just get a weak reference. + Plugin* plugin = m_plugin.get(); + + m_plugin->destroyPlugin(); + m_plugin = 0; + + platformDestroy(); + + // This will delete the plug-in controller proxy object. + m_connection->removePluginControllerProxy(this, plugin); +} + +void PluginControllerProxy::paint() +{ + ASSERT(!m_dirtyRect.isEmpty()); + m_paintTimer.stop(); + + if (!m_backingStore) + return; + + IntRect dirtyRect = m_dirtyRect; + m_dirtyRect = IntRect(); + + ASSERT(m_plugin); + + // Create a graphics context. + OwnPtr<GraphicsContext> graphicsContext = m_backingStore->createGraphicsContext(); + +#if PLATFORM(MAC) + // FIXME: We should really call applyDeviceScaleFactor instead of scale, but that ends up calling into WKSI + // which we currently don't have initiated in the plug-in process. + graphicsContext->scale(FloatSize(m_contentsScaleFactor, m_contentsScaleFactor)); +#endif + + if (m_plugin->isTransparent()) + graphicsContext->clearRect(dirtyRect); + + m_plugin->paint(graphicsContext.get(), dirtyRect); + + m_connection->connection()->send(Messages::PluginProxy::Update(dirtyRect), m_pluginInstanceID); +} + +void PluginControllerProxy::startPaintTimer() +{ + // Check if we should start the timer. + + if (m_dirtyRect.isEmpty()) + return; + + // FIXME: Check clip rect. + + if (m_paintTimer.isActive()) + return; + + if (m_waitingForDidUpdate) + return; + + // Start the timer. + m_paintTimer.startOneShot(0); + + m_waitingForDidUpdate = true; +} + +bool PluginControllerProxy::isPluginVisible() +{ + // FIXME: Implement this. + notImplemented(); + return false; +} + +void PluginControllerProxy::invalidate(const IntRect& rect) +{ + IntRect dirtyRect = rect; + + // Make sure that the dirty rect is not greater than the plug-in itself. + dirtyRect.intersect(IntRect(IntPoint(), m_pluginSize)); + m_dirtyRect.unite(dirtyRect); + + startPaintTimer(); +} + +String PluginControllerProxy::userAgent() +{ + return m_userAgent; +} + +void PluginControllerProxy::loadURL(uint64_t requestID, const String& method, const String& urlString, const String& target, const HTTPHeaderMap& headerFields, const Vector<uint8_t>& httpBody, bool allowPopups) +{ + m_connection->connection()->send(Messages::PluginProxy::LoadURL(requestID, method, urlString, target, headerFields, httpBody, allowPopups), m_pluginInstanceID); +} + +void PluginControllerProxy::cancelStreamLoad(uint64_t streamID) +{ + m_connection->connection()->send(Messages::PluginProxy::CancelStreamLoad(streamID), m_pluginInstanceID); +} + +void PluginControllerProxy::cancelManualStreamLoad() +{ + m_pluginCanceledManualStreamLoad = true; + + m_connection->connection()->send(Messages::PluginProxy::CancelManualStreamLoad(), m_pluginInstanceID); +} + +NPObject* PluginControllerProxy::windowScriptNPObject() +{ + retainNPObject(m_windowNPObject); + return m_windowNPObject; +} + +NPObject* PluginControllerProxy::pluginElementNPObject() +{ + if (!m_pluginElementNPObject) { + uint64_t pluginElementNPObjectID = 0; + + if (!m_connection->connection()->sendSync(Messages::PluginProxy::GetPluginElementNPObject(), Messages::PluginProxy::GetPluginElementNPObject::Reply(pluginElementNPObjectID), m_pluginInstanceID)) + return 0; + + if (!pluginElementNPObjectID) + return 0; + + m_pluginElementNPObject = m_connection->npRemoteObjectMap()->createNPObjectProxy(pluginElementNPObjectID, m_plugin.get()); + ASSERT(m_pluginElementNPObject); + } + + retainNPObject(m_pluginElementNPObject); + return m_pluginElementNPObject; +} + +bool PluginControllerProxy::evaluate(NPObject* npObject, const String& scriptString, NPVariant* result, bool allowPopups) +{ + if (tryToShortCircuitEvaluate(npObject, scriptString, result)) + return true; + + PluginDestructionProtector protector(this); + + NPVariant npObjectAsNPVariant; + OBJECT_TO_NPVARIANT(npObject, npObjectAsNPVariant); + + // Send the NPObject over as an NPVariantData. + NPVariantData npObjectAsNPVariantData = m_connection->npRemoteObjectMap()->npVariantToNPVariantData(npObjectAsNPVariant, m_plugin.get()); + + bool returnValue = false; + NPVariantData resultData; + + if (!m_connection->connection()->sendSync(Messages::PluginProxy::Evaluate(npObjectAsNPVariantData, scriptString, allowPopups), Messages::PluginProxy::Evaluate::Reply(returnValue, resultData), m_pluginInstanceID)) + return false; + + if (!returnValue) + return false; + + *result = m_connection->npRemoteObjectMap()->npVariantDataToNPVariant(resultData, m_plugin.get()); + return true; +} + +bool PluginControllerProxy::tryToShortCircuitInvoke(NPObject* npObject, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, bool& returnValue, NPVariant& result) +{ + // Only try to short circuit evaluate for plug-ins that have the quirk specified. +#if PLUGIN_ARCHITECTURE(MAC) + if (!PluginProcess::shared().netscapePluginModule()->pluginQuirks().contains(PluginQuirks::CanShortCircuitSomeNPRuntimeCallsDuringInitialization)) + return false; +#else + return false; +#endif + + // And only when we're in initialize. + if (!inInitialize()) + return false; + + // And only when the NPObject is the window NPObject. + if (npObject != m_windowNPObject) + return false; + + // And only when we don't have any arguments. + if (argumentCount) + return false; + + IdentifierRep* methodNameRep = static_cast<IdentifierRep*>(methodName); + if (!methodNameRep->isString()) + return false; + + if (!strcmp(methodNameRep->string(), "__flash_getWindowLocation")) { + result.type = NPVariantType_String; + result.value.stringValue = createNPString(m_pluginCreationParameters->parameters.documentURL.utf8()); + returnValue = true; + return true; + } + + if (!strcmp(methodNameRep->string(), "__flash_getTopLocation")) { + if (m_pluginCreationParameters->parameters.toplevelDocumentURL.isNull()) { + // If the toplevel document is URL it means that the frame that the plug-in is in doesn't have access to the toplevel document. + // In this case, just pass the string "[object]" to Flash. + result.type = NPVariantType_String; + result.value.stringValue = createNPString("[object]"); + returnValue = true; + return true; + } + + result.type = NPVariantType_String; + result.value.stringValue = createNPString(m_pluginCreationParameters->parameters.toplevelDocumentURL.utf8()); + returnValue = true; + return true; + } + + return false; +} + +void PluginControllerProxy::setStatusbarText(const String& statusbarText) +{ + m_connection->connection()->send(Messages::PluginProxy::SetStatusbarText(statusbarText), m_pluginInstanceID); +} + +bool PluginControllerProxy::isAcceleratedCompositingEnabled() +{ + return m_isAcceleratedCompositingEnabled; +} + +void PluginControllerProxy::pluginProcessCrashed() +{ + // This should never be called from here. + ASSERT_NOT_REACHED(); +} + +void PluginControllerProxy::willSendEventToPlugin() +{ + // This is only used when running plugins in the web process. + ASSERT_NOT_REACHED(); +} + +float PluginControllerProxy::contentsScaleFactor() +{ + return m_contentsScaleFactor; +} + +String PluginControllerProxy::proxiesForURL(const String& urlString) +{ + String proxyString; + + if (!m_connection->connection()->sendSync(Messages::PluginProxy::ProxiesForURL(urlString), Messages::PluginProxy::ProxiesForURL::Reply(proxyString), m_pluginInstanceID)) + return String(); + + return proxyString; +} + +String PluginControllerProxy::cookiesForURL(const String& urlString) +{ + String cookieString; + + if (!m_connection->connection()->sendSync(Messages::PluginProxy::CookiesForURL(urlString), Messages::PluginProxy::CookiesForURL::Reply(cookieString), m_pluginInstanceID)) + return String(); + + return cookieString; +} + +void PluginControllerProxy::setCookiesForURL(const String& urlString, const String& cookieString) +{ + m_connection->connection()->send(Messages::PluginProxy::SetCookiesForURL(urlString, cookieString), m_pluginInstanceID); +} + +bool PluginControllerProxy::isPrivateBrowsingEnabled() +{ + return m_isPrivateBrowsingEnabled; +} + +bool PluginControllerProxy::getAuthenticationInfo(const ProtectionSpace& protectionSpace, String& username, String& password) +{ + bool returnValue; + if (!m_connection->connection()->sendSync(Messages::PluginProxy::GetAuthenticationInfo(protectionSpace), Messages::PluginProxy::GetAuthenticationInfo::Reply(returnValue, username, password), m_pluginInstanceID)) + return false; + + return returnValue; +} + +void PluginControllerProxy::protectPluginFromDestruction() +{ + m_pluginDestructionProtectCount++; +} + +void PluginControllerProxy::unprotectPluginFromDestruction() +{ + ASSERT(m_pluginDestructionProtectCount); + + m_pluginDestructionProtectCount--; +} + +void PluginControllerProxy::frameDidFinishLoading(uint64_t requestID) +{ + m_plugin->frameDidFinishLoading(requestID); +} + +void PluginControllerProxy::frameDidFail(uint64_t requestID, bool wasCancelled) +{ + m_plugin->frameDidFail(requestID, wasCancelled); +} + +void PluginControllerProxy::geometryDidChange(const IntSize& pluginSize, const IntRect& clipRect, const AffineTransform& pluginToRootViewTransform, float contentsScaleFactor, const ShareableBitmap::Handle& backingStoreHandle) +{ + ASSERT(m_plugin); + + m_pluginSize = pluginSize; + + if (contentsScaleFactor != m_contentsScaleFactor) { + m_contentsScaleFactor = contentsScaleFactor; + m_plugin->contentsScaleFactorChanged(m_contentsScaleFactor); + } + + platformGeometryDidChange(); + + if (!backingStoreHandle.isNull()) { + // Create a new backing store. + m_backingStore = ShareableBitmap::create(backingStoreHandle); + } + + m_plugin->geometryDidChange(pluginSize, clipRect, pluginToRootViewTransform); +} + +void PluginControllerProxy::didEvaluateJavaScript(uint64_t requestID, const String& result) +{ + m_plugin->didEvaluateJavaScript(requestID, result); +} + +void PluginControllerProxy::streamDidReceiveResponse(uint64_t streamID, const String& responseURLString, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers) +{ + m_plugin->streamDidReceiveResponse(streamID, KURL(ParsedURLString, responseURLString), streamLength, lastModifiedTime, mimeType, headers, String()); +} + +void PluginControllerProxy::streamDidReceiveData(uint64_t streamID, const CoreIPC::DataReference& data) +{ + m_plugin->streamDidReceiveData(streamID, reinterpret_cast<const char*>(data.data()), data.size()); +} + +void PluginControllerProxy::streamDidFinishLoading(uint64_t streamID) +{ + m_plugin->streamDidFinishLoading(streamID); +} + +void PluginControllerProxy::streamDidFail(uint64_t streamID, bool wasCancelled) +{ + m_plugin->streamDidFail(streamID, wasCancelled); +} + +void PluginControllerProxy::manualStreamDidReceiveResponse(const String& responseURLString, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers) +{ + if (m_pluginCanceledManualStreamLoad) + return; + + m_plugin->manualStreamDidReceiveResponse(KURL(ParsedURLString, responseURLString), streamLength, lastModifiedTime, mimeType, headers, String()); +} + +void PluginControllerProxy::manualStreamDidReceiveData(const CoreIPC::DataReference& data) +{ + if (m_pluginCanceledManualStreamLoad) + return; + + m_plugin->manualStreamDidReceiveData(reinterpret_cast<const char*>(data.data()), data.size()); +} + +void PluginControllerProxy::manualStreamDidFinishLoading() +{ + if (m_pluginCanceledManualStreamLoad) + return; + + m_plugin->manualStreamDidFinishLoading(); +} + +void PluginControllerProxy::manualStreamDidFail(bool wasCancelled) +{ + if (m_pluginCanceledManualStreamLoad) + return; + + m_plugin->manualStreamDidFail(wasCancelled); +} + +void PluginControllerProxy::handleMouseEvent(const WebMouseEvent& mouseEvent, PassRefPtr<Messages::PluginControllerProxy::HandleMouseEvent::DelayedReply> reply) +{ + // Always let the web process think that we've handled this mouse event, even before passing it along to the plug-in. + // This is a workaround for + // <rdar://problem/9299901> UI process thinks the page is unresponsive when a plug-in is showing a context menu. + // The web process sends a synchronous HandleMouseEvent message and the plug-in process spawns a nested + // run loop when showing the context menu, so eventually the unresponsiveness timer kicks in in the UI process. + // FIXME: We should come up with a better way to do this. + reply->send(true); + + m_plugin->handleMouseEvent(mouseEvent); +} + +void PluginControllerProxy::handleWheelEvent(const WebWheelEvent& wheelEvent, bool& handled) +{ + handled = m_plugin->handleWheelEvent(wheelEvent); +} + +void PluginControllerProxy::handleMouseEnterEvent(const WebMouseEvent& mouseEnterEvent, bool& handled) +{ + handled = m_plugin->handleMouseEnterEvent(mouseEnterEvent); +} + +void PluginControllerProxy::handleMouseLeaveEvent(const WebMouseEvent& mouseLeaveEvent, bool& handled) +{ + handled = m_plugin->handleMouseLeaveEvent(mouseLeaveEvent); +} + +void PluginControllerProxy::handleKeyboardEvent(const WebKeyboardEvent& keyboardEvent, bool& handled) +{ + handled = m_plugin->handleKeyboardEvent(keyboardEvent); +} + +void PluginControllerProxy::paintEntirePlugin() +{ + if (m_pluginSize.isEmpty()) + return; + + m_dirtyRect = IntRect(IntPoint(), m_pluginSize); + paint(); +} + +void PluginControllerProxy::snapshot(ShareableBitmap::Handle& backingStoreHandle) +{ + ASSERT(m_plugin); + RefPtr<ShareableBitmap> bitmap = m_plugin->snapshot(); + if (!bitmap) + return; + + bitmap->createHandle(backingStoreHandle); +} + +void PluginControllerProxy::setFocus(bool hasFocus) +{ + m_plugin->setFocus(hasFocus); +} + +void PluginControllerProxy::didUpdate() +{ + m_waitingForDidUpdate = false; + startPaintTimer(); +} + +void PluginControllerProxy::getPluginScriptableNPObject(uint64_t& pluginScriptableNPObjectID) +{ + NPObject* pluginScriptableNPObject = m_plugin->pluginScriptableNPObject(); + if (!pluginScriptableNPObject) { + pluginScriptableNPObjectID = 0; + return; + } + + pluginScriptableNPObjectID = m_connection->npRemoteObjectMap()->registerNPObject(pluginScriptableNPObject, m_plugin.get()); + releaseNPObject(pluginScriptableNPObject); +} + +void PluginControllerProxy::privateBrowsingStateChanged(bool isPrivateBrowsingEnabled) +{ + m_isPrivateBrowsingEnabled = isPrivateBrowsingEnabled; + + m_plugin->privateBrowsingStateChanged(isPrivateBrowsingEnabled); +} + +void PluginControllerProxy::getFormValue(bool& returnValue, String& formValue) +{ + returnValue = m_plugin->getFormValue(formValue); +} + +bool PluginControllerProxy::tryToShortCircuitEvaluate(NPObject* npObject, const String& scriptString, NPVariant* result) +{ + // Only try to short circuit evaluate for plug-ins that have the quirk specified. +#if PLUGIN_ARCHITECTURE(MAC) + if (!PluginProcess::shared().netscapePluginModule()->pluginQuirks().contains(PluginQuirks::CanShortCircuitSomeNPRuntimeCallsDuringInitialization)) + return false; +#else + return false; +#endif + + // And only when we're in initialize. + if (!inInitialize()) + return false; + + // And only when the NPObject is the window NPObject. + if (npObject != m_windowNPObject) + return false; + + // Now, check for the right strings. + if (scriptString != "function __flash_getWindowLocation() { return window.location; }" + && scriptString != "function __flash_getTopLocation() { return top.location; }") + return false; + + VOID_TO_NPVARIANT(*result); + return true; +} + +} // namespace WebKit + +#endif // ENABLE(PLUGIN_PROCESS) diff --git a/Source/WebKit2/PluginProcess/PluginControllerProxy.h b/Source/WebKit2/PluginProcess/PluginControllerProxy.h new file mode 100644 index 000000000..51c348da1 --- /dev/null +++ b/Source/WebKit2/PluginProcess/PluginControllerProxy.h @@ -0,0 +1,214 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PluginControllerProxy_h +#define PluginControllerProxy_h + +#if ENABLE(PLUGIN_PROCESS) + +#include "Connection.h" +#include "Plugin.h" +#include "PluginController.h" +#include "PluginControllerProxyMessages.h" +#include "RunLoop.h" +#include "ShareableBitmap.h" +#include <wtf/Noncopyable.h> + +#if PLATFORM(MAC) +#include <wtf/RetainPtr.h> + +typedef struct __WKCARemoteLayerClientRef *WKCARemoteLayerClientRef; +#endif + +namespace CoreIPC { + class DataReference; +} + +namespace WebKit { + +class ShareableBitmap; +class WebProcessConnection; +struct PluginCreationParameters; + +class PluginControllerProxy : PluginController { + WTF_MAKE_NONCOPYABLE(PluginControllerProxy); + +public: + static PassOwnPtr<PluginControllerProxy> create(WebProcessConnection*, const PluginCreationParameters&); + ~PluginControllerProxy(); + + uint64_t pluginInstanceID() const { return m_pluginInstanceID; } + + bool initialize(const PluginCreationParameters&); + void destroy(); + + void didReceivePluginControllerProxyMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + void didReceiveSyncPluginControllerProxyMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, OwnPtr<CoreIPC::ArgumentEncoder>&); + +#if PLATFORM(MAC) + uint32_t remoteLayerClientID() const; +#endif + + PluginController* asPluginController() { return this; } + +private: + PluginControllerProxy(WebProcessConnection*, const PluginCreationParameters&); + + void startPaintTimer(); + void paint(); + + // PluginController + virtual bool isPluginVisible(); + virtual void invalidate(const WebCore::IntRect&); + virtual String userAgent(); + virtual void loadURL(uint64_t requestID, const String& method, const String& urlString, const String& target, const WebCore::HTTPHeaderMap& headerFields, const Vector<uint8_t>& httpBody, bool allowPopups); + virtual void cancelStreamLoad(uint64_t streamID); + virtual void cancelManualStreamLoad(); + virtual NPObject* windowScriptNPObject(); + virtual NPObject* pluginElementNPObject(); + virtual bool evaluate(NPObject*, const String& scriptString, NPVariant* result, bool allowPopups); + virtual bool tryToShortCircuitInvoke(NPObject*, NPIdentifier methodName, const NPVariant* arguments, uint32_t argumentCount, bool& returnValue, NPVariant& result); + virtual void setStatusbarText(const String&); + virtual bool isAcceleratedCompositingEnabled(); + virtual void pluginProcessCrashed(); + virtual void willSendEventToPlugin(); + +#if PLATFORM(MAC) + virtual void pluginFocusOrWindowFocusChanged(bool); + virtual void setComplexTextInputState(PluginComplexTextInputState); + virtual mach_port_t compositingRenderServerPort(); +#endif + + virtual float contentsScaleFactor(); + virtual String proxiesForURL(const String&); + virtual String cookiesForURL(const String&); + virtual void setCookiesForURL(const String& urlString, const String& cookieString); + virtual bool isPrivateBrowsingEnabled(); + virtual bool getAuthenticationInfo(const WebCore::ProtectionSpace&, String& username, String& password); + virtual void protectPluginFromDestruction(); + virtual void unprotectPluginFromDestruction(); + + // Message handlers. + void frameDidFinishLoading(uint64_t requestID); + void frameDidFail(uint64_t requestID, bool wasCancelled); + void geometryDidChange(const WebCore::IntSize& pluginSize, const WebCore::IntRect& clipRect, const WebCore::AffineTransform& pluginToRootViewTransform, float contentsScaleFactor, const ShareableBitmap::Handle& backingStoreHandle); + void didEvaluateJavaScript(uint64_t requestID, const String& result); + void streamDidReceiveResponse(uint64_t streamID, const String& responseURLString, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers); + void streamDidReceiveData(uint64_t streamID, const CoreIPC::DataReference& data); + void streamDidFinishLoading(uint64_t streamID); + void streamDidFail(uint64_t streamID, bool wasCancelled); + void manualStreamDidReceiveResponse(const String& responseURLString, uint32_t streamLength, uint32_t lastModifiedTime, const String& mimeType, const String& headers); + void manualStreamDidReceiveData(const CoreIPC::DataReference& data); + void manualStreamDidFinishLoading(); + void manualStreamDidFail(bool wasCancelled); + void handleMouseEvent(const WebMouseEvent&, PassRefPtr<Messages::PluginControllerProxy::HandleMouseEvent::DelayedReply>); + void handleWheelEvent(const WebWheelEvent&, bool& handled); + void handleMouseEnterEvent(const WebMouseEvent&, bool& handled); + void handleMouseLeaveEvent(const WebMouseEvent&, bool& handled); + void handleKeyboardEvent(const WebKeyboardEvent&, bool& handled); + void paintEntirePlugin(); + void snapshot(ShareableBitmap::Handle& backingStoreHandle); + void setFocus(bool); + void didUpdate(); + void getPluginScriptableNPObject(uint64_t& pluginScriptableNPObjectID); + +#if PLATFORM(MAC) + void windowFocusChanged(bool); + void windowAndViewFramesChanged(const WebCore::IntRect& windowFrameInScreenCoordinates, const WebCore::IntRect& viewFrameInWindowCoordinates); + void windowVisibilityChanged(bool); + void sendComplexTextInput(const String& textInput); +#endif + + void privateBrowsingStateChanged(bool); + void getFormValue(bool& returnValue, String& formValue); + + bool tryToShortCircuitEvaluate(NPObject*, const String& scriptString, NPVariant* result); + + bool inInitialize() const { return m_pluginCreationParameters; } + + void platformInitialize(); + void platformDestroy(); + void platformGeometryDidChange(); + + WebProcessConnection* m_connection; + uint64_t m_pluginInstanceID; + + String m_userAgent; + bool m_isPrivateBrowsingEnabled; + bool m_isAcceleratedCompositingEnabled; + + RefPtr<Plugin> m_plugin; + + WebCore::IntSize m_pluginSize; + + // The dirty rect in plug-in coordinates. + WebCore::IntRect m_dirtyRect; + + // The paint timer, used for coalescing painting. + RunLoop::Timer<PluginControllerProxy> m_paintTimer; + + // A counter used to prevent the plug-in from being destroyed. + unsigned m_pluginDestructionProtectCount; + + // A timer that we use to prevent destruction of the plug-in while plug-in + // code is on the stack. + RunLoop::Timer<PluginControllerProxy> m_pluginDestroyTimer; + + // Will point to the plug-in creation parameters of the plug-in we're currently initializing and will be null when we're done initializing. + const PluginCreationParameters* m_pluginCreationParameters; + + // Whether we're waiting for the plug-in proxy in the web process to draw the contents of its + // backing store into the web process backing store. + bool m_waitingForDidUpdate; + + // Whether the plug-in has canceled the manual stream load. + bool m_pluginCanceledManualStreamLoad; + +#if PLATFORM(MAC) + // Whether complex text input is enabled for this plug-in. + bool m_isComplexTextInputEnabled; + + // For CA plug-ins, this holds the information needed to export the layer hierarchy to the UI process. + RetainPtr<WKCARemoteLayerClientRef> m_remoteLayerClient; +#endif + + // The contents scale factor of this plug-in. + float m_contentsScaleFactor; + + // The backing store that this plug-in draws into. + RefPtr<ShareableBitmap> m_backingStore; + + // The window NPObject. + NPObject* m_windowNPObject; + + // The plug-in element NPObject. + NPObject* m_pluginElementNPObject; +}; + +} // namespace WebKit + +#endif // ENABLE(PLUGIN_PROCESS) + +#endif // PluginControllerProxy_h diff --git a/Source/WebKit2/PluginProcess/PluginControllerProxy.messages.in b/Source/WebKit2/PluginProcess/PluginControllerProxy.messages.in new file mode 100644 index 000000000..dd9a4d67a --- /dev/null +++ b/Source/WebKit2/PluginProcess/PluginControllerProxy.messages.in @@ -0,0 +1,113 @@ +# Copyright (C) 2010 Apple Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#if ENABLE(PLUGIN_PROCESS) + +messages -> PluginControllerProxy { + # Sent when the plug-in geometry changes. + GeometryDidChange(WebCore::IntSize pluginSize, WebCore::IntRect clipRect, WebCore::AffineTransform pluginToRootViewTransform, float scaleFactor, WebKit::ShareableBitmap::Handle backingStoreHandle) + + # Sent when a frame has finished loading. + FrameDidFinishLoading(uint64_t requestID) + + # Sent when a frame dfailed to load. + FrameDidFail(uint64_t requestID, bool wasCancelled) + + # Sent when JavaScript that the plug-in asked to be evaluated has been evaluated. + DidEvaluateJavaScript(uint64_t requestID, WTF::String result) + + # Sent when the plug-in receives a response for a stream. + StreamDidReceiveResponse(uint64_t streamID, WTF::String responseURLString, uint32_t streamLength, uint32_t lastModifiedTime, WTF::String mimeType, WTF::String headers) + + # Sent when the plug-in receives data for a stream. + StreamDidReceiveData(uint64_t streamID, CoreIPC::DataReference data) + + # Sent when a plug-in stream has finishes loading. + StreamDidFinishLoading(uint64_t streamID) + + # Sent when a plug-in stream has failed to load. + StreamDidFail(uint64_t streamID, bool wasCancelled) + + # Sent when the plug-in receives a response for the manual stream. + ManualStreamDidReceiveResponse(WTF::String responseURLString, uint32_t streamLength, uint32_t lastModifiedTime, WTF::String mimeType, WTF::String headers) + + # Sent when the plug-in receives data for the manual stream. + ManualStreamDidReceiveData(CoreIPC::DataReference data) + + # Sent when the plug-in manual stream has finishes loading. + ManualStreamDidFinishLoading() + + # Sent when the plug-in manual stream has failed to load. + ManualStreamDidFail(bool wasCancelled) + + # Sent when a mouse event (that isn't a mouse enter/leave event or a wheel event) should be processed. + HandleMouseEvent(WebKit::WebMouseEvent mouseEvent) -> (bool handled) Delayed + + # Sent when a mouse wheel event should be processed. + HandleWheelEvent(WebKit::WebWheelEvent wheelEvent) -> (bool handled) + + # Sent when a mouse enter event should be processed. + HandleMouseEnterEvent(WebKit::WebMouseEvent mouseEvent) -> (bool handled) + + # Sent when a mouse leave event should be processed. + HandleMouseLeaveEvent(WebKit::WebMouseEvent mouseEvent) -> (bool handled) + + # Sent when a keyboard should be processed. + HandleKeyboardEvent(WebKit::WebKeyboardEvent keyboardEvent) -> (bool handled) + + # Sent when the plug-in focus changes. + SetFocus(bool isFocused) + + # Sent when the update requested by Update has been painted. + DidUpdate() + + # Paint the entire plug-in. + PaintEntirePlugin() -> () + + # Get a reference to the plug-in's scriptable NPObject. + GetPluginScriptableNPObject() -> (uint64_t pluginScriptableNPObjectID) + +#if PLATFORM(MAC) + # Send the complex text input to the plug-in. + SendComplexTextInput(WTF::String textInput) + + # Sent when the containing NSWindow's focus changes + WindowFocusChanged(bool hasFocus) + + # Sent when the containing NSWindow or NSView frame changes + WindowAndViewFramesChanged(WebCore::IntRect windowFrameInScreenCoordinates, WebCore::IntRect viewFrameInWindowCoordinates) + + # Sent when the containing NSWindow's visibility changes + WindowVisibilityChanged(bool isVisible) +#endif + + # Return a snapshot of the plugin + Snapshot() -> (WebKit::ShareableBitmap::Handle backingStoreHandle) + + # Sent when private browsing is enabled or disabled + PrivateBrowsingStateChanged(bool isPrivateBrowsingEnabled) + + # Gets the string representating the form value of the plug-in + GetFormValue() -> (bool returnValue, WTF::String formValue) +} + +#endif diff --git a/Source/WebKit2/PluginProcess/PluginCreationParameters.cpp b/Source/WebKit2/PluginProcess/PluginCreationParameters.cpp new file mode 100644 index 000000000..e29e9744c --- /dev/null +++ b/Source/WebKit2/PluginProcess/PluginCreationParameters.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PluginCreationParameters.h" + +#if ENABLE(PLUGIN_PROCESS) + +#include "ArgumentCoders.h" + +namespace WebKit { + +PluginCreationParameters::PluginCreationParameters() + : pluginInstanceID(0) + , windowNPObjectID(0) + , contentsScaleFactor(1) + , isPrivateBrowsingEnabled(false) +#if USE(ACCELERATED_COMPOSITING) + , isAcceleratedCompositingEnabled(false) +#endif +{ +} + +void PluginCreationParameters::encode(CoreIPC::ArgumentEncoder* encoder) const +{ + encoder->encode(pluginInstanceID); + encoder->encode(windowNPObjectID); + encoder->encode(parameters); + encoder->encode(userAgent); + encoder->encode(contentsScaleFactor); + encoder->encode(isPrivateBrowsingEnabled); + +#if USE(ACCELERATED_COMPOSITING) + encoder->encode(isAcceleratedCompositingEnabled); +#endif +} + +bool PluginCreationParameters::decode(CoreIPC::ArgumentDecoder* decoder, PluginCreationParameters& result) +{ + if (!decoder->decode(result.pluginInstanceID) || !result.pluginInstanceID) + return false; + + if (!decoder->decode(result.windowNPObjectID)) + return false; + + if (!decoder->decode(result.parameters)) + return false; + + if (!decoder->decode(result.userAgent)) + return false; + + if (!decoder->decode(result.contentsScaleFactor)) + return false; + + if (!decoder->decode(result.isPrivateBrowsingEnabled)) + return false; + +#if USE(ACCELERATED_COMPOSITING) + if (!decoder->decode(result.isAcceleratedCompositingEnabled)) + return false; +#endif + + return true; +} + + +} // namespace WebKit + +#endif // ENABLE(PLUGIN_PROCESS) diff --git a/Source/WebKit2/PluginProcess/PluginCreationParameters.h b/Source/WebKit2/PluginProcess/PluginCreationParameters.h new file mode 100644 index 000000000..fcd534963 --- /dev/null +++ b/Source/WebKit2/PluginProcess/PluginCreationParameters.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2011 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PluginCreationParameters_h +#define PluginCreationParameters_h + +#if ENABLE(PLUGIN_PROCESS) + +#include "Plugin.h" + +namespace CoreIPC { + class ArgumentDecoder; + class ArgumentEncoder; +} + +namespace WebKit { + +struct PluginCreationParameters { + PluginCreationParameters(); + + void encode(CoreIPC::ArgumentEncoder*) const; + static bool decode(CoreIPC::ArgumentDecoder*, PluginCreationParameters&); + + // The unique ID of this plug-in instance. + uint64_t pluginInstanceID; + + // The ID of the window NPObject. + uint64_t windowNPObjectID; + + // The parameters passed to the plug-in. + Plugin::Parameters parameters; + + // The browser user agent. + String userAgent; + + // The current contents scale factor that this plug-in should have. + float contentsScaleFactor; + + // Whether private browsing is enabled at the time of instantiation. + bool isPrivateBrowsingEnabled; + +#if USE(ACCELERATED_COMPOSITING) + // Whether accelerated compositing is enabled. + bool isAcceleratedCompositingEnabled; +#endif +}; + +} // namespace WebKit + +#endif // ENABLE(PLUGIN_PROCESS) + +#endif // PluginCreationParameters_h diff --git a/Source/WebKit2/PluginProcess/PluginProcess.cpp b/Source/WebKit2/PluginProcess/PluginProcess.cpp new file mode 100644 index 000000000..a366f5db7 --- /dev/null +++ b/Source/WebKit2/PluginProcess/PluginProcess.cpp @@ -0,0 +1,252 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PluginProcess.h" + +#if ENABLE(PLUGIN_PROCESS) + +#include "ArgumentCoders.h" +#include "Attachment.h" +#include "NetscapePlugin.h" +#include "NetscapePluginModule.h" +#include "PluginProcessProxyMessages.h" +#include "PluginProcessCreationParameters.h" +#include "WebProcessConnection.h" +#include <WebCore/NotImplemented.h> + +#if USE(UNIX_DOMAIN_SOCKETS) +#include <errno.h> +#include <fcntl.h> +#include <sys/resource.h> +#include <sys/socket.h> +#include <unistd.h> + +#ifdef SOCK_SEQPACKET +#define SOCKET_TYPE SOCK_SEQPACKET +#else +#if PLATFORM(GTK) +#define SOCKET_TYPE SOCK_STREAM +#else +#define SOCKET_TYPE SOCK_DGRAM +#endif +#endif // SOCK_SEQPACKET +#endif // USE(UNIX_DOMAIN_SOCKETS) + +namespace WebKit { + +static const double shutdownTimeout = 15.0; + +PluginProcess& PluginProcess::shared() +{ + DEFINE_STATIC_LOCAL(PluginProcess, pluginProcess, ()); + return pluginProcess; +} + +PluginProcess::PluginProcess() + : ChildProcess(shutdownTimeout) +#if PLATFORM(MAC) + , m_compositingRenderServerPort(MACH_PORT_NULL) +#endif +{ +} + +PluginProcess::~PluginProcess() +{ +} + +void PluginProcess::initialize(CoreIPC::Connection::Identifier serverIdentifier, RunLoop* runLoop) +{ + ASSERT(!m_connection); + + m_connection = CoreIPC::Connection::createClientConnection(serverIdentifier, this, runLoop); + m_connection->setDidCloseOnConnectionWorkQueueCallback(didCloseOnConnectionWorkQueue); + m_connection->open(); + + NetscapePlugin::setSetExceptionFunction(WebProcessConnection::setGlobalException); +} + +void PluginProcess::removeWebProcessConnection(WebProcessConnection* webProcessConnection) +{ + size_t vectorIndex = m_webProcessConnections.find(webProcessConnection); + ASSERT(vectorIndex != notFound); + + m_webProcessConnections.remove(vectorIndex); + + if (m_webProcessConnections.isEmpty() && m_pluginModule) { + // Decrement the load count. This is balanced by a call to incrementLoadCount in createWebProcessConnection. + m_pluginModule->decrementLoadCount(); + } + + enableTermination(); +} + +NetscapePluginModule* PluginProcess::netscapePluginModule() +{ + if (!m_pluginModule) { + ASSERT(!m_pluginPath.isNull()); + m_pluginModule = NetscapePluginModule::getOrCreate(m_pluginPath); + +#if PLATFORM(MAC) + if (m_pluginModule) { + if (m_pluginModule->pluginQuirks().contains(PluginQuirks::PrognameShouldBeWebKitPluginHost)) + setprogname("WebKitPluginHost"); + } +#endif + } + + return m_pluginModule.get(); +} + +bool PluginProcess::shouldTerminate() +{ + ASSERT(m_webProcessConnections.isEmpty()); + + return true; +} + +void PluginProcess::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + didReceivePluginProcessMessage(connection, messageID, arguments); +} + +void PluginProcess::didClose(CoreIPC::Connection*) +{ + // The UI process has crashed, just go ahead and quit. + // FIXME: If the plug-in is spinning in the main loop, we'll never get this message. + RunLoop::current()->stop(); +} + +void PluginProcess::didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::MessageID) +{ +} + +void PluginProcess::syncMessageSendTimedOut(CoreIPC::Connection*) +{ +} + +void PluginProcess::initializePluginProcess(const PluginProcessCreationParameters& parameters) +{ + ASSERT(!m_pluginModule); + + m_pluginPath = parameters.pluginPath; + + platformInitialize(parameters); +} + +void PluginProcess::createWebProcessConnection() +{ + bool didHaveAnyWebProcessConnections = !m_webProcessConnections.isEmpty(); + +#if PLATFORM(MAC) + // Create the listening port. + mach_port_t listeningPort; + mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &listeningPort); + + // Create a listening connection. + RefPtr<WebProcessConnection> connection = WebProcessConnection::create(listeningPort); + m_webProcessConnections.append(connection.release()); + + CoreIPC::Attachment clientPort(listeningPort, MACH_MSG_TYPE_MAKE_SEND); + m_connection->send(Messages::PluginProcessProxy::DidCreateWebProcessConnection(clientPort), 0); +#elif USE(UNIX_DOMAIN_SOCKETS) + int sockets[2]; + if (socketpair(AF_UNIX, SOCKET_TYPE, 0, sockets) == -1) { + ASSERT_NOT_REACHED(); + return; + } + + // Don't expose the plugin process socket to the web process. + while (fcntl(sockets[1], F_SETFD, FD_CLOEXEC) == -1) { + if (errno != EINTR) { + ASSERT_NOT_REACHED(); + while (close(sockets[0]) == -1 && errno == EINTR) { } + while (close(sockets[1]) == -1 && errno == EINTR) { } + return; + } + } + + // Don't expose the web process socket to possible future web processes. + while (fcntl(sockets[0], F_SETFD, FD_CLOEXEC) == -1) { + if (errno != EINTR) { + ASSERT_NOT_REACHED(); + while (close(sockets[0]) == -1 && errno == EINTR) { } + while (close(sockets[1]) == -1 && errno == EINTR) { } + return; + } + } + + RefPtr<WebProcessConnection> connection = WebProcessConnection::create(sockets[1]); + m_webProcessConnections.append(connection.release()); + + CoreIPC::Attachment clientSocket(sockets[0]); + m_connection->send(Messages::PluginProcessProxy::DidCreateWebProcessConnection(clientSocket), 0); +#else + notImplemented(); +#endif + + if (NetscapePluginModule* module = netscapePluginModule()) { + if (!didHaveAnyWebProcessConnections) { + // Increment the load count. This is matched by a call to decrementLoadCount in removeWebProcessConnection. + // We do this so that the plug-in module's NP_Shutdown won't be called until right before exiting. + module->incrementLoadCount(); + } + } + + disableTermination(); +} + +void PluginProcess::getSitesWithData(uint64_t callbackID) +{ + LocalTerminationDisabler terminationDisabler(*this); + + Vector<String> sites; + if (NetscapePluginModule* module = netscapePluginModule()) + sites = module->sitesWithData(); + + m_connection->send(Messages::PluginProcessProxy::DidGetSitesWithData(sites, callbackID), 0); +} + +void PluginProcess::clearSiteData(const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID) +{ + LocalTerminationDisabler terminationDisabler(*this); + + if (NetscapePluginModule* module = netscapePluginModule()) { + if (sites.isEmpty()) { + // Clear everything. + module->clearSiteData(String(), flags, maxAgeInSeconds); + } else { + for (size_t i = 0; i < sites.size(); ++i) + module->clearSiteData(sites[i], flags, maxAgeInSeconds); + } + } + + m_connection->send(Messages::PluginProcessProxy::DidClearSiteData(callbackID), 0); +} + +} // namespace WebKit + +#endif // ENABLE(PLUGIN_PROCESS) + diff --git a/Source/WebKit2/PluginProcess/PluginProcess.h b/Source/WebKit2/PluginProcess/PluginProcess.h new file mode 100644 index 000000000..a610326b4 --- /dev/null +++ b/Source/WebKit2/PluginProcess/PluginProcess.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PluginProcess_h +#define PluginProcess_h + +#if ENABLE(PLUGIN_PROCESS) + +#include "ChildProcess.h" +#include "RunLoop.h" +#include <wtf/Forward.h> +#include <wtf/text/WTFString.h> + +namespace WebKit { + +class NetscapePluginModule; +class WebProcessConnection; +struct PluginProcessCreationParameters; + +class PluginProcess : ChildProcess { + WTF_MAKE_NONCOPYABLE(PluginProcess); +public: + static PluginProcess& shared(); + + void initialize(CoreIPC::Connection::Identifier, RunLoop*); + void removeWebProcessConnection(WebProcessConnection* webProcessConnection); + + NetscapePluginModule* netscapePluginModule(); + +#if PLATFORM(MAC) + void initializeShim(); + + void setModalWindowIsShowing(bool); + void setFullscreenWindowIsShowing(bool); + +#if USE(ACCELERATED_COMPOSITING) + mach_port_t compositingRenderServerPort() const { return m_compositingRenderServerPort; } +#endif +#endif + +private: + PluginProcess(); + ~PluginProcess(); + + // ChildProcess + virtual bool shouldTerminate(); + + // CoreIPC::Connection::Client + virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + virtual void didClose(CoreIPC::Connection*); + virtual void didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::MessageID); + virtual void syncMessageSendTimedOut(CoreIPC::Connection*); + + // Message handlers. + void didReceivePluginProcessMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + void initializePluginProcess(const PluginProcessCreationParameters&); + void createWebProcessConnection(); + void getSitesWithData(uint64_t callbackID); + void clearSiteData(const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID); + + void platformInitialize(const PluginProcessCreationParameters&); + + // The connection to the UI process. + RefPtr<CoreIPC::Connection> m_connection; + + // Our web process connections. + Vector<RefPtr<WebProcessConnection> > m_webProcessConnections; + + // The plug-in path. + String m_pluginPath; + + // The plug-in module. + RefPtr<NetscapePluginModule> m_pluginModule; + +#if USE(ACCELERATED_COMPOSITING) && PLATFORM(MAC) + // The Mach port used for accelerated compositing. + mach_port_t m_compositingRenderServerPort; +#endif + +}; + +} // namespace WebKit + +#endif // ENABLE(PLUGIN_PROCESS) + +#endif // PluginProcess_h diff --git a/Source/WebKit2/PluginProcess/PluginProcess.messages.in b/Source/WebKit2/PluginProcess/PluginProcess.messages.in new file mode 100644 index 000000000..e4ef45072 --- /dev/null +++ b/Source/WebKit2/PluginProcess/PluginProcess.messages.in @@ -0,0 +1,43 @@ +# Copyright (C) 2010 Apple Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#if ENABLE(PLUGIN_PROCESS) + +messages -> PluginProcess { + # Initializes the plug-in process. + InitializePluginProcess(WebKit::PluginProcessCreationParameters processCreationParameters) + + # Creates a web process connection. When the connection has been created, + # The plug-in process sends back a DidCreateWebProcessConnection message with + # a connection identifier. + CreateWebProcessConnection() + + # Asks the plug-in process for sites with data. The plug-in process sends back a + # DidGetSitesWithData message with the sites. + GetSitesWithData(uint64_t callbackID) + + # Asks the plug-in to clear data for the given sites. The plug-in process sends back + # a DidClearSiteData message when done. + ClearSiteData(Vector<WTF::String> sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID) +} + +#endif diff --git a/Source/WebKit2/PluginProcess/PluginProcessMain.h b/Source/WebKit2/PluginProcess/PluginProcessMain.h new file mode 100644 index 000000000..3b3f38cb5 --- /dev/null +++ b/Source/WebKit2/PluginProcess/PluginProcessMain.h @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PluginProcessMain_h +#define PluginProcessMain_h + +#if ENABLE(PLUGIN_PROCESS) + +namespace WebKit { + +class CommandLine; + +int PluginProcessMain(const CommandLine&); + +} // namespace WebKit + +#endif // ENABLE(PLUGIN_PROCESS) + +#endif // PluginProcessMain_h diff --git a/Source/WebKit2/PluginProcess/WebProcessConnection.cpp b/Source/WebKit2/PluginProcess/WebProcessConnection.cpp new file mode 100644 index 000000000..ab63b05bb --- /dev/null +++ b/Source/WebKit2/PluginProcess/WebProcessConnection.cpp @@ -0,0 +1,250 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "WebProcessConnection.h" + +#if ENABLE(PLUGIN_PROCESS) + +#include "ArgumentCoders.h" +#include "NPRemoteObjectMap.h" +#include "PluginControllerProxy.h" +#include "PluginCreationParameters.h" +#include "PluginProcess.h" +#include "PluginProcessConnectionMessages.h" +#include "RunLoop.h" + +namespace WebKit { + + +class ConnectionStack { +public: + CoreIPC::Connection* current() + { + return m_connectionStack.last(); + } + + class CurrentConnectionPusher { + public: + CurrentConnectionPusher(ConnectionStack& connectionStack, CoreIPC::Connection* connection) + : m_connectionStack(connectionStack) +#if !ASSERT_DISABLED + , m_connection(connection) +#endif + { + m_connectionStack.m_connectionStack.append(connection); + } + + ~CurrentConnectionPusher() + { + ASSERT(m_connectionStack.current() == m_connection); + m_connectionStack.m_connectionStack.removeLast(); + } + + private: + ConnectionStack& m_connectionStack; +#if !ASSERT_DISABLED + CoreIPC::Connection* m_connection; +#endif + }; + +private: + // It's OK for these to be weak pointers because we only push object on the stack + // from within didReceiveMessage and didReceiveSyncMessage and the Connection objects are + // already ref'd for the duration of those functions. + Vector<CoreIPC::Connection*, 4> m_connectionStack; +}; + +static ConnectionStack& connectionStack() +{ + DEFINE_STATIC_LOCAL(ConnectionStack, connectionStack, ()); + + return connectionStack; +} + +PassRefPtr<WebProcessConnection> WebProcessConnection::create(CoreIPC::Connection::Identifier connectionIdentifier) +{ + return adoptRef(new WebProcessConnection(connectionIdentifier)); +} + +WebProcessConnection::~WebProcessConnection() +{ + ASSERT(m_pluginControllers.isEmpty()); + ASSERT(!m_npRemoteObjectMap); + ASSERT(!m_connection); +} + +WebProcessConnection::WebProcessConnection(CoreIPC::Connection::Identifier connectionIdentifier) +{ + m_connection = CoreIPC::Connection::createServerConnection(connectionIdentifier, this, RunLoop::main()); + m_npRemoteObjectMap = NPRemoteObjectMap::create(m_connection.get()); + + m_connection->setOnlySendMessagesAsDispatchWhenWaitingForSyncReplyWhenProcessingSuchAMessage(true); + m_connection->open(); +} + +void WebProcessConnection::addPluginControllerProxy(PassOwnPtr<PluginControllerProxy> pluginController) +{ + uint64_t pluginInstanceID = pluginController->pluginInstanceID(); + + ASSERT(!m_pluginControllers.contains(pluginInstanceID)); + m_pluginControllers.set(pluginInstanceID, pluginController.leakPtr()); +} + +void WebProcessConnection::destroyPluginControllerProxy(PluginControllerProxy* pluginController) +{ + // This may end up calling removePluginControllerProxy which ends up deleting + // the WebProcessConnection object if this was the last object. + pluginController->destroy(); +} + +void WebProcessConnection::removePluginControllerProxy(PluginControllerProxy* pluginController, Plugin* plugin) +{ + { + ASSERT(m_pluginControllers.contains(pluginController->pluginInstanceID())); + + OwnPtr<PluginControllerProxy> pluginControllerOwnPtr = adoptPtr(m_pluginControllers.take(pluginController->pluginInstanceID())); + ASSERT(pluginControllerOwnPtr == pluginController); + } + + // Invalidate all objects related to this plug-in. + if (plugin) + m_npRemoteObjectMap->pluginDestroyed(plugin); + + if (!m_pluginControllers.isEmpty()) + return; + + m_npRemoteObjectMap = nullptr; + + // The last plug-in went away, close this connection. + m_connection->invalidate(); + m_connection = nullptr; + + // This will cause us to be deleted. + PluginProcess::shared().removeWebProcessConnection(this); +} + +void WebProcessConnection::setGlobalException(const String& exceptionString) +{ + CoreIPC::Connection* connection = connectionStack().current(); + if (!connection) + return; + + connection->sendSync(Messages::PluginProcessConnection::SetException(exceptionString), Messages::PluginProcessConnection::SetException::Reply(), 0); +} + +void WebProcessConnection::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + ConnectionStack::CurrentConnectionPusher currentConnection(connectionStack(), connection); + + if (!arguments->destinationID()) { + ASSERT_NOT_REACHED(); + return; + } + + PluginControllerProxy* pluginControllerProxy = m_pluginControllers.get(arguments->destinationID()); + if (!pluginControllerProxy) + return; + + PluginController::PluginDestructionProtector protector(pluginControllerProxy->asPluginController()); + pluginControllerProxy->didReceivePluginControllerProxyMessage(connection, messageID, arguments); +} + +void WebProcessConnection::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, OwnPtr<CoreIPC::ArgumentEncoder>& reply) +{ + ConnectionStack::CurrentConnectionPusher currentConnection(connectionStack(), connection); + + uint64_t destinationID = arguments->destinationID(); + + if (!destinationID) { + didReceiveSyncWebProcessConnectionMessage(connection, messageID, arguments, reply); + return; + } + + if (messageID.is<CoreIPC::MessageClassNPObjectMessageReceiver>()) { + m_npRemoteObjectMap->didReceiveSyncMessage(connection, messageID, arguments, reply); + return; + } + + PluginControllerProxy* pluginControllerProxy = m_pluginControllers.get(arguments->destinationID()); + if (!pluginControllerProxy) + return; + + PluginController::PluginDestructionProtector protector(pluginControllerProxy->asPluginController()); + pluginControllerProxy->didReceiveSyncPluginControllerProxyMessage(connection, messageID, arguments, reply); +} + +void WebProcessConnection::didClose(CoreIPC::Connection*) +{ + // The web process crashed. Destroy all the plug-in controllers. Destroying the last plug-in controller + // will cause the web process connection itself to be destroyed. + Vector<PluginControllerProxy*> pluginControllers; + copyValuesToVector(m_pluginControllers, pluginControllers); + + for (size_t i = 0; i < pluginControllers.size(); ++i) + destroyPluginControllerProxy(pluginControllers[i]); +} + +void WebProcessConnection::destroyPlugin(uint64_t pluginInstanceID) +{ + PluginControllerProxy* pluginControllerProxy = m_pluginControllers.get(pluginInstanceID); + ASSERT(pluginControllerProxy); + + destroyPluginControllerProxy(pluginControllerProxy); +} + +void WebProcessConnection::didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::MessageID) +{ + // FIXME: Implement. +} + +void WebProcessConnection::syncMessageSendTimedOut(CoreIPC::Connection*) +{ +} + +void WebProcessConnection::createPlugin(const PluginCreationParameters& creationParameters, bool& result, uint32_t& remoteLayerClientID) +{ + OwnPtr<PluginControllerProxy> pluginControllerProxy = PluginControllerProxy::create(this, creationParameters); + + PluginControllerProxy* pluginControllerProxyPtr = pluginControllerProxy.get(); + + // Make sure to add the proxy to the map before initializing it, since the plug-in might call out to the web process from + // its NPP_New function. This will hand over ownership of the proxy to the web process connection. + addPluginControllerProxy(pluginControllerProxy.release()); + + // Now try to initialize the plug-in. + result = pluginControllerProxyPtr->initialize(creationParameters); + + if (!result) + return; + +#if PLATFORM(MAC) + remoteLayerClientID = pluginControllerProxyPtr->remoteLayerClientID(); +#endif +} + +} // namespace WebKit + +#endif // ENABLE(PLUGIN_PROCESS) diff --git a/Source/WebKit2/PluginProcess/WebProcessConnection.h b/Source/WebKit2/PluginProcess/WebProcessConnection.h new file mode 100644 index 000000000..4e2ea65df --- /dev/null +++ b/Source/WebKit2/PluginProcess/WebProcessConnection.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebProcessConnection_h +#define WebProcessConnection_h + +#if ENABLE(PLUGIN_PROCESS) + +#include "Connection.h" +#include "Plugin.h" +#include <wtf/RefCounted.h> + +namespace WebKit { + +class NPRemoteObjectMap; +class PluginControllerProxy; +struct PluginCreationParameters; + +// A connection from a plug-in process to a web process. + +class WebProcessConnection : public RefCounted<WebProcessConnection>, CoreIPC::Connection::Client { +public: + static PassRefPtr<WebProcessConnection> create(CoreIPC::Connection::Identifier); + virtual ~WebProcessConnection(); + + CoreIPC::Connection* connection() const { return m_connection.get(); } + NPRemoteObjectMap* npRemoteObjectMap() const { return m_npRemoteObjectMap.get(); } + + void removePluginControllerProxy(PluginControllerProxy*, Plugin*); + + static void setGlobalException(const String&); + +private: + WebProcessConnection(CoreIPC::Connection::Identifier); + + void addPluginControllerProxy(PassOwnPtr<PluginControllerProxy>); + + void destroyPluginControllerProxy(PluginControllerProxy*); + + // CoreIPC::Connection::Client + virtual void didReceiveMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*); + virtual void didReceiveSyncMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, OwnPtr<CoreIPC::ArgumentEncoder>&); + virtual void didClose(CoreIPC::Connection*); + virtual void didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::MessageID); + virtual void syncMessageSendTimedOut(CoreIPC::Connection*); + + // Message handlers. + void didReceiveSyncWebProcessConnectionMessage(CoreIPC::Connection*, CoreIPC::MessageID, CoreIPC::ArgumentDecoder*, OwnPtr<CoreIPC::ArgumentEncoder>&); + void createPlugin(const PluginCreationParameters&, bool& result, uint32_t& remoteLayerClientID); + void destroyPlugin(uint64_t pluginInstanceID); + + RefPtr<CoreIPC::Connection> m_connection; + + HashMap<uint64_t, PluginControllerProxy*> m_pluginControllers; + RefPtr<NPRemoteObjectMap> m_npRemoteObjectMap; +}; + +} // namespace WebKit + +#endif // ENABLE(PLUGIN_PROCESS) + + +#endif // WebProcessConnection_h diff --git a/Source/WebKit2/PluginProcess/WebProcessConnection.messages.in b/Source/WebKit2/PluginProcess/WebProcessConnection.messages.in new file mode 100644 index 000000000..1b11458da --- /dev/null +++ b/Source/WebKit2/PluginProcess/WebProcessConnection.messages.in @@ -0,0 +1,33 @@ +# Copyright (C) 2010 Apple Inc. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#if ENABLE(PLUGIN_PROCESS) + +messages -> WebProcessConnection { + # Creates a plug-in instance using the given creation parameters. + CreatePlugin(WebKit::PluginCreationParameters pluginCreationParameters) -> (bool result, uint32_t remoteLayerClientID) + + # Destroys the plug-in instance with the given instance ID. + DestroyPlugin(uint64_t pluginInstanceID) -> () +} + +#endif diff --git a/Source/WebKit2/PluginProcess/gtk/PluginControllerProxyGtk.cpp b/Source/WebKit2/PluginProcess/gtk/PluginControllerProxyGtk.cpp new file mode 100644 index 000000000..28304df2a --- /dev/null +++ b/Source/WebKit2/PluginProcess/gtk/PluginControllerProxyGtk.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2011 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PluginControllerProxy.h" + +#if ENABLE(PLUGIN_PROCESS) + +#include <WebCore/NotImplemented.h> + +using namespace WebCore; + +namespace WebKit { + +void PluginControllerProxy::platformInitialize() +{ + notImplemented(); +} + +void PluginControllerProxy::platformDestroy() +{ + notImplemented(); +} + +void PluginControllerProxy::platformGeometryDidChange() +{ + notImplemented(); +} + +} // namespace WebKit + +#endif // ENABLE(PLUGIN_PROCESS) diff --git a/Source/WebKit2/PluginProcess/gtk/PluginProcessGtk.cpp b/Source/WebKit2/PluginProcess/gtk/PluginProcessGtk.cpp new file mode 100644 index 000000000..ee78f9a7b --- /dev/null +++ b/Source/WebKit2/PluginProcess/gtk/PluginProcessGtk.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2011 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PluginProcess.h" + +#if ENABLE(PLUGIN_PROCESS) + +#include "PluginProcessCreationParameters.h" +#include <WebCore/NotImplemented.h> + +namespace WebKit { + +void PluginProcess::platformInitialize(const PluginProcessCreationParameters& parameters) +{ + notImplemented(); +} + +} // namespace WebKit + +#endif // ENABLE(PLUGIN_PROCESS) diff --git a/Source/WebKit2/PluginProcess/gtk/PluginProcessMainGtk.cpp b/Source/WebKit2/PluginProcess/gtk/PluginProcessMainGtk.cpp new file mode 100644 index 000000000..9942604e7 --- /dev/null +++ b/Source/WebKit2/PluginProcess/gtk/PluginProcessMainGtk.cpp @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2011 Igalia S.L. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PluginProcessMainGtk.h" + +#include "PluginProcess.h" +#include <WebKit2/RunLoop.h> +#include <gdk/gdkx.h> +#include <gtk/gtk.h> +#include <runtime/InitializeThreading.h> +#include <wtf/MainThread.h> + +namespace WebKit { + +static int webkitgtkXError(Display* xdisplay, XErrorEvent* error) +{ + gchar errorMessage[64]; + XGetErrorText(xdisplay, error->error_code, errorMessage, 63); + g_warning("The program '%s' received an X Window System error.\n" + "This probably reflects a bug in a browser plugin.\n" + "The error was '%s'.\n" + " (Details: serial %ld error_code %d request_code %d minor_code %d)\n", + g_get_prgname(), errorMessage, + error->serial, error->error_code, + error->request_code, error->minor_code); + return 0; +} + +WK_EXPORT int PluginProcessMainGtk(int argc, char* argv[]) +{ + ASSERT(argc == 2); + + gtk_init(&argc, &argv); + + JSC::initializeThreading(); + WTF::initializeMainThread(); + RunLoop::initializeMainRunLoop(); + + // Plugins can produce X errors that are handled by the GDK X error handler, which + // exits the process. Since we don't want to crash due to plugin bugs, we install a + // custom error handler to show a warning when a X error happens without aborting. + XSetErrorHandler(webkitgtkXError); + + int socket = atoi(argv[1]); + WebKit::PluginProcess::shared().initialize(socket, RunLoop::main()); + RunLoop::run(); + + return 0; +} + +} // namespace WebKit + + diff --git a/Source/WebKit2/PluginProcess/gtk/PluginProcessMainGtk.h b/Source/WebKit2/PluginProcess/gtk/PluginProcessMainGtk.h new file mode 100644 index 000000000..39cc6e659 --- /dev/null +++ b/Source/WebKit2/PluginProcess/gtk/PluginProcessMainGtk.h @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Portions Copyright (c) 2010 Motorola Mobility, Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PluginProcessMainGtk_h +#define PluginProcessMainGtk_h + +#include <WebKit2/WKBase.h> + +namespace WebKit { + +#ifdef __cplusplus +extern "C" { +WK_EXPORT int PluginProcessMainGtk(int argc, char* argv[]); +} // extern "C" +#endif // __cplusplus + +} // namespace WebKit + +#endif // PluginProcessMain_h diff --git a/Source/WebKit2/PluginProcess/mac/PluginControllerProxyMac.mm b/Source/WebKit2/PluginProcess/mac/PluginControllerProxyMac.mm new file mode 100644 index 000000000..95feaa56d --- /dev/null +++ b/Source/WebKit2/PluginProcess/mac/PluginControllerProxyMac.mm @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "config.h" +#import "PluginControllerProxy.h" + +#if ENABLE(PLUGIN_PROCESS) + +#import "PluginProcess.h" +#import "PluginProxyMessages.h" +#import "WebKitSystemInterface.h" +#import "WebProcessConnection.h" +#import <QuartzCore/QuartzCore.h> + +using namespace WebCore; + +namespace WebKit { + +void PluginControllerProxy::pluginFocusOrWindowFocusChanged(bool pluginHasFocusAndWindowHasFocus) +{ + m_connection->connection()->send(Messages::PluginProxy::PluginFocusOrWindowFocusChanged(pluginHasFocusAndWindowHasFocus), m_pluginInstanceID); +} + +void PluginControllerProxy::setComplexTextInputState(PluginComplexTextInputState pluginComplexTextInputState) +{ + m_connection->connection()->send(Messages::PluginProxy::SetComplexTextInputState(pluginComplexTextInputState), m_pluginInstanceID, CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply); +} + +mach_port_t PluginControllerProxy::compositingRenderServerPort() +{ + return PluginProcess::shared().compositingRenderServerPort(); +} + +void PluginControllerProxy::platformInitialize() +{ + CALayer * platformLayer = m_plugin->pluginLayer(); + if (!platformLayer) + return; + + ASSERT(!m_remoteLayerClient); + + m_remoteLayerClient = WKCARemoteLayerClientMakeWithServerPort(PluginProcess::shared().compositingRenderServerPort()); + ASSERT(m_remoteLayerClient); + + WKCARemoteLayerClientSetLayer(m_remoteLayerClient.get(), platformLayer); +} + +void PluginControllerProxy::platformDestroy() +{ + if (!m_remoteLayerClient) + return; + + WKCARemoteLayerClientInvalidate(m_remoteLayerClient.get()); + m_remoteLayerClient = nullptr; +} + +uint32_t PluginControllerProxy::remoteLayerClientID() const +{ + if (!m_remoteLayerClient) + return 0; + + return WKCARemoteLayerClientGetClientId(m_remoteLayerClient.get()); +} + +void PluginControllerProxy::platformGeometryDidChange() +{ + CALayer * pluginLayer = m_plugin->pluginLayer(); + + // We don't want to animate to the new size so we disable actions for this transaction. + [CATransaction begin]; + [CATransaction setValue:[NSNumber numberWithBool:YES] forKey:kCATransactionDisableActions]; + [pluginLayer setFrame:CGRectMake(0, 0, m_pluginSize.width(), m_pluginSize.height())]; + [CATransaction commit]; +} + +void PluginControllerProxy::windowFocusChanged(bool hasFocus) +{ + m_plugin->windowFocusChanged(hasFocus); +} + +void PluginControllerProxy::windowAndViewFramesChanged(const IntRect& windowFrameInScreenCoordinates, const IntRect& viewFrameInWindowCoordinates) +{ + m_plugin->windowAndViewFramesChanged(windowFrameInScreenCoordinates, viewFrameInWindowCoordinates); +} + +void PluginControllerProxy::windowVisibilityChanged(bool isVisible) +{ + m_plugin->windowVisibilityChanged(isVisible); +} + +void PluginControllerProxy::sendComplexTextInput(const String& textInput) +{ + m_plugin->sendComplexTextInput(textInput); +} + +} // namespace WebKit + +#endif // ENABLE(PLUGIN_PROCESS) diff --git a/Source/WebKit2/PluginProcess/mac/PluginProcessMac.mm b/Source/WebKit2/PluginProcess/mac/PluginProcessMac.mm new file mode 100644 index 000000000..fab921e75 --- /dev/null +++ b/Source/WebKit2/PluginProcess/mac/PluginProcessMac.mm @@ -0,0 +1,235 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "config.h" +#import "PluginProcess.h" + +#if ENABLE(PLUGIN_PROCESS) + +#import "NetscapePlugin.h" +#import "PluginProcessShim.h" +#import "PluginProcessProxyMessages.h" +#import "PluginProcessCreationParameters.h" +#import <WebCore/LocalizedStrings.h> +#import <WebKitSystemInterface.h> +#import <dlfcn.h> +#import <wtf/HashSet.h> + +namespace WebKit { + +static pthread_once_t shouldCallRealDebuggerOnce = PTHREAD_ONCE_INIT; + +class FullscreenWindowTracker { + WTF_MAKE_NONCOPYABLE(FullscreenWindowTracker); + +public: + FullscreenWindowTracker() { } + + template<typename T> void windowShown(T window); + template<typename T> void windowHidden(T window); + +private: + typedef HashSet<void*> WindowSet; + WindowSet m_windows; +}; + +static bool rectCoversAnyScreen(NSRect rect) +{ + for (NSScreen *screen in [NSScreen screens]) { + if (NSContainsRect(rect, [screen frame])) + return YES; + } + return NO; +} + +#ifndef NP_NO_CARBON +static bool windowCoversAnyScreen(WindowRef window) +{ + HIRect bounds; + HIWindowGetBounds(window, kWindowStructureRgn, kHICoordSpaceScreenPixel, &bounds); + + // Convert to Cocoa-style screen coordinates that use a Y offset relative to the zeroth screen's origin. + bounds.origin.y = NSHeight([(NSScreen *)[[NSScreen screens] objectAtIndex:0] frame]) - CGRectGetMaxY(bounds); + + return rectCoversAnyScreen(NSRectFromCGRect(bounds)); +} +#endif + +static bool windowCoversAnyScreen(NSWindow* window) +{ + return rectCoversAnyScreen([window frame]); +} + +template<typename T> void FullscreenWindowTracker::windowShown(T window) +{ + // If this window is already visible then there is nothing to do. + WindowSet::iterator it = m_windows.find(window); + if (it != m_windows.end()) + return; + + // If the window is not full-screen then we're not interested in it. + if (!windowCoversAnyScreen(window)) + return; + + bool windowSetWasEmpty = m_windows.isEmpty(); + + m_windows.add(window); + + // If this is the first full screen window to be shown, notify the UI process. + if (windowSetWasEmpty) + PluginProcess::shared().setFullscreenWindowIsShowing(true); +} + +template<typename T> void FullscreenWindowTracker::windowHidden(T window) +{ + // If this is not a window that we're tracking then there is nothing to do. + WindowSet::iterator it = m_windows.find(window); + if (it == m_windows.end()) + return; + + m_windows.remove(it); + + // If this was the last full screen window that was visible, notify the UI process. + if (m_windows.isEmpty()) + PluginProcess::shared().setFullscreenWindowIsShowing(false); +} + +static FullscreenWindowTracker& fullscreenWindowTracker() +{ + DEFINE_STATIC_LOCAL(FullscreenWindowTracker, fullscreenWindowTracker, ()); + return fullscreenWindowTracker; +} + +static bool isUserbreakSet = false; + +static void initShouldCallRealDebugger() +{ + char* var = getenv("USERBREAK"); + + if (var) + isUserbreakSet = atoi(var); +} + +static bool shouldCallRealDebugger() +{ + pthread_once(&shouldCallRealDebuggerOnce, initShouldCallRealDebugger); + + return isUserbreakSet; +} + +static bool isWindowActive(WindowRef windowRef, bool& result) +{ +#ifndef NP_NO_CARBON + if (NetscapePlugin* plugin = NetscapePlugin::netscapePluginFromWindow(windowRef)) { + result = plugin->isWindowActive(); + return true; + } +#endif + return false; +} + +static UInt32 getCurrentEventButtonState() +{ +#ifndef NP_NO_CARBON + return NetscapePlugin::buttonState(); +#else + ASSERT_NOT_REACHED(); + return 0; +#endif +} + +static void cocoaWindowShown(NSWindow *window) +{ + fullscreenWindowTracker().windowShown(window); +} + +static void cocoaWindowHidden(NSWindow *window) +{ + fullscreenWindowTracker().windowHidden(window); +} + +static void carbonWindowShown(WindowRef window) +{ +#ifndef NP_NO_CARBON + fullscreenWindowTracker().windowShown(window); +#endif +} + +static void carbonWindowHidden(WindowRef window) +{ +#ifndef NP_NO_CARBON + fullscreenWindowTracker().windowHidden(window); +#endif +} + +static void setModal(bool modalWindowIsShowing) +{ + PluginProcess::shared().setModalWindowIsShowing(modalWindowIsShowing); +} + +void PluginProcess::initializeShim() +{ + const PluginProcessShimCallbacks callbacks = { + shouldCallRealDebugger, + isWindowActive, + getCurrentEventButtonState, + cocoaWindowShown, + cocoaWindowHidden, + carbonWindowShown, + carbonWindowHidden, + setModal, + }; + + PluginProcessShimInitializeFunc initFunc = reinterpret_cast<PluginProcessShimInitializeFunc>(dlsym(RTLD_DEFAULT, "WebKitPluginProcessShimInitialize")); + initFunc(callbacks); +} + +void PluginProcess::setModalWindowIsShowing(bool modalWindowIsShowing) +{ + m_connection->send(Messages::PluginProcessProxy::SetModalWindowIsShowing(modalWindowIsShowing), 0); +} + +void PluginProcess::setFullscreenWindowIsShowing(bool fullscreenWindowIsShowing) +{ + m_connection->send(Messages::PluginProcessProxy::SetFullscreenWindowIsShowing(fullscreenWindowIsShowing), 0); +} + +void PluginProcess::platformInitialize(const PluginProcessCreationParameters& parameters) +{ + m_compositingRenderServerPort = parameters.acceleratedCompositingPort.port(); + + NSString *applicationName = [NSString stringWithFormat:WEB_UI_STRING("%@ (%@ Internet plug-in)", + "visible name of the plug-in host process. The first argument is the plug-in name " + "and the second argument is the application name."), + [[(NSString *)parameters.pluginPath lastPathComponent] stringByDeletingPathExtension], + (NSString *)parameters.parentProcessName]; + + WKSetVisibleApplicationName((CFStringRef)applicationName); +} + +} // namespace WebKit + +#endif // ENABLE(PLUGIN_PROCESS) diff --git a/Source/WebKit2/PluginProcess/mac/PluginProcessMainMac.mm b/Source/WebKit2/PluginProcess/mac/PluginProcessMainMac.mm new file mode 100644 index 000000000..5e93e2bdd --- /dev/null +++ b/Source/WebKit2/PluginProcess/mac/PluginProcessMainMac.mm @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2010, 2011 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import "config.h" +#import "PluginProcessMain.h" + +#if ENABLE(PLUGIN_PROCESS) + +#import "CommandLine.h" +#import "EnvironmentUtilities.h" +#import "NetscapePluginModule.h" +#import "PluginProcess.h" +#import "RunLoop.h" +#import <WebKitSystemInterface.h> +#import <mach/mach_error.h> +#import <runtime/InitializeThreading.h> +#import <servers/bootstrap.h> +#import <wtf/MainThread.h> +#import <wtf/RetainPtr.h> +#import <wtf/text/CString.h> +#import <wtf/text/WTFString.h> +#include <stdio.h> + +#define SHOW_CRASH_REPORTER 1 + +namespace WebKit { + +// FIXME: There is much code here that is duplicated in WebProcessMainMac.mm, we should add a shared base class where +// we can put everything. + +int PluginProcessMain(const CommandLine& commandLine) +{ + // Remove the PluginProcess shim from the DYLD_INSERT_LIBRARIES environment variable so any processes + // spawned by the PluginProcess don't try to insert the shim and crash. + EnvironmentUtilities::stripValuesEndingWithString("DYLD_INSERT_LIBRARIES", "/PluginProcessShim.dylib"); + + // Check if we're being spawned to write a MIME type preferences file. + String pluginPath = commandLine["createPluginMIMETypesPreferences"]; + if (!pluginPath.isEmpty()) { + JSC::initializeThreading(); + WTF::initializeMainThread(); + + if (!NetscapePluginModule::createPluginMIMETypesPreferences(pluginPath)) + return EXIT_FAILURE; + + return EXIT_SUCCESS; + } + + String serviceName = commandLine["servicename"]; + if (serviceName.isEmpty()) + return EXIT_FAILURE; + + // Get the server port. + mach_port_t serverPort; + kern_return_t kr = bootstrap_look_up(bootstrap_port, serviceName.utf8().data(), &serverPort); + if (kr) { + fprintf(stderr, "bootstrap_look_up result: %s (%x)\n", mach_error_string(kr), kr); + return EXIT_FAILURE; + } + + String localization = commandLine["localization"]; + RetainPtr<CFStringRef> cfLocalization(AdoptCF, CFStringCreateWithCharacters(0, reinterpret_cast<const UniChar*>(localization.characters()), localization.length())); + if (cfLocalization) + WKSetDefaultLocalization(cfLocalization.get()); + +#if !SHOW_CRASH_REPORTER + // Installs signal handlers that exit on a crash so that CrashReporter does not show up. + signal(SIGILL, _exit); + signal(SIGFPE, _exit); + signal(SIGBUS, _exit); + signal(SIGSEGV, _exit); +#endif + + // FIXME: It would be better to proxy set cursor calls over to the UI process instead of + // allowing plug-ins to change the mouse cursor at any time. + WKEnableSettingCursorWhenInBackground(); + + JSC::initializeThreading(); + WTF::initializeMainThread(); + RunLoop::initializeMainRunLoop(); + + // Initialize the shim. + PluginProcess::shared().initializeShim(); + + // Initialize the plug-in process connection. + PluginProcess::shared().initialize(serverPort, RunLoop::main()); + + [NSApplication sharedApplication]; + + RunLoop::run(); + + return 0; +} + +} + +#endif // ENABLE(PLUGIN_PROCESS) diff --git a/Source/WebKit2/PluginProcess/mac/PluginProcessShim.h b/Source/WebKit2/PluginProcess/mac/PluginProcessShim.h new file mode 100644 index 000000000..b021a3af2 --- /dev/null +++ b/Source/WebKit2/PluginProcess/mac/PluginProcessShim.h @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PluginProcessShim_h +#define PluginProcessShim_h + +@class NSWindow; + +#include <Carbon/Carbon.h> + +namespace WebKit { + +struct PluginProcessShimCallbacks { + bool (*shouldCallRealDebugger)(); + bool (*isWindowActive)(WindowRef, bool& result); + UInt32 (*getCurrentEventButtonState)(); + void (*cocoaWindowShown)(NSWindow *); + void (*cocoaWindowHidden)(NSWindow *); + void (*carbonWindowShown)(WindowRef); + void (*carbonWindowHidden)(WindowRef); + void (*setModal)(bool); +}; + +typedef void (*PluginProcessShimInitializeFunc)(const PluginProcessShimCallbacks&); + +} + +#endif // PluginProcessShim_h diff --git a/Source/WebKit2/PluginProcess/mac/PluginProcessShim.mm b/Source/WebKit2/PluginProcess/mac/PluginProcessShim.mm new file mode 100644 index 000000000..fceb99b37 --- /dev/null +++ b/Source/WebKit2/PluginProcess/mac/PluginProcessShim.mm @@ -0,0 +1,172 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#import <wtf/Platform.h> +#import "PluginProcessShim.h" + +#import <AppKit/AppKit.h> +#import <Carbon/Carbon.h> +#import <WebKitSystemInterface.h> +#import <stdio.h> +#import <objc/objc-runtime.h> + +#define DYLD_INTERPOSE(_replacement,_replacee) \ + __attribute__((used)) static struct{ const void* replacement; const void* replacee; } _interpose_##_replacee \ + __attribute__ ((section ("__DATA,__interpose"))) = { (const void*)(unsigned long)&_replacement, (const void*)(unsigned long)&_replacee }; + +namespace WebKit { + +extern "C" void WebKitPluginProcessShimInitialize(const PluginProcessShimCallbacks& callbacks); + +static PluginProcessShimCallbacks pluginProcessShimCallbacks; + +static IMP NSApplication_RunModalForWindow; +static unsigned modalCount = 0; + +static void beginModal() +{ + // Make sure to make ourselves the front process + ProcessSerialNumber psn; + GetCurrentProcess(&psn); + SetFrontProcess(&psn); + + if (!modalCount++) + pluginProcessShimCallbacks.setModal(true); +} + +static void endModal() +{ + if (!--modalCount) + pluginProcessShimCallbacks.setModal(false); +} + +static NSInteger shim_NSApplication_RunModalForWindow(id self, SEL _cmd, NSWindow* window) +{ + beginModal(); + NSInteger result = ((NSInteger (*)(id, SEL, NSWindow *))NSApplication_RunModalForWindow)(self, _cmd, window); + endModal(); + + return result; +} + +#ifndef __LP64__ + +#if COMPILER(CLANG) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#endif + +static void shimDebugger(void) +{ + if (!pluginProcessShimCallbacks.shouldCallRealDebugger()) + return; + + Debugger(); +} + +static UInt32 shimGetCurrentEventButtonState() +{ + return pluginProcessShimCallbacks.getCurrentEventButtonState(); +} + +static Boolean shimIsWindowActive(WindowRef window) +{ + bool result; + if (pluginProcessShimCallbacks.isWindowActive(window, result)) + return result; + + return IsWindowActive(window); +} + +static void shimModalDialog(ModalFilterUPP modalFilter, DialogItemIndex *itemHit) +{ + beginModal(); + ModalDialog(modalFilter, itemHit); + endModal(); +} + +static DialogItemIndex shimAlert(SInt16 alertID, ModalFilterUPP modalFilter) +{ + beginModal(); + DialogItemIndex index = Alert(alertID, modalFilter); + endModal(); + + return index; +} + +static void shimShowWindow(WindowRef window) +{ + pluginProcessShimCallbacks.carbonWindowShown(window); + ShowWindow(window); +} + +static void shimHideWindow(WindowRef window) +{ + pluginProcessShimCallbacks.carbonWindowHidden(window); + HideWindow(window); +} + +DYLD_INTERPOSE(shimDebugger, Debugger); +DYLD_INTERPOSE(shimGetCurrentEventButtonState, GetCurrentEventButtonState); +DYLD_INTERPOSE(shimIsWindowActive, IsWindowActive); +DYLD_INTERPOSE(shimModalDialog, ModalDialog); +DYLD_INTERPOSE(shimAlert, Alert); +DYLD_INTERPOSE(shimShowWindow, ShowWindow); +DYLD_INTERPOSE(shimHideWindow, HideWindow); + +#if COMPILER(CLANG) +#pragma clang diagnostic pop +#endif + +#endif + +__attribute__((visibility("default"))) +void WebKitPluginProcessShimInitialize(const PluginProcessShimCallbacks& callbacks) +{ + pluginProcessShimCallbacks = callbacks; + + // Override -[NSApplication runModalForWindow:] + Method runModalForWindowMethod = class_getInstanceMethod(objc_getClass("NSApplication"), @selector(runModalForWindow:)); + NSApplication_RunModalForWindow = method_setImplementation(runModalForWindowMethod, reinterpret_cast<IMP>(shim_NSApplication_RunModalForWindow)); + + NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter]; + + // Track when any Cocoa window is about to be be shown. + id orderOnScreenObserver = [defaultCenter addObserverForName:WKWindowWillOrderOnScreenNotification() + object:nil + queue:nil + usingBlock:^(NSNotification *notification) { pluginProcessShimCallbacks.cocoaWindowShown([notification object]); }]; + // Track when any cocoa window is about to be hidden. + id orderOffScreenObserver = [defaultCenter addObserverForName:WKWindowWillOrderOffScreenNotification() + object:nil + queue:nil + usingBlock:^(NSNotification *notification) { pluginProcessShimCallbacks.cocoaWindowHidden([notification object]); }]; + + // Leak the two observers so that they observe notifications for the lifetime of the process. + CFRetain(orderOnScreenObserver); + CFRetain(orderOffScreenObserver); +} + +} // namespace WebKit diff --git a/Source/WebKit2/PluginProcess/qt/PluginControllerProxyQt.cpp b/Source/WebKit2/PluginProcess/qt/PluginControllerProxyQt.cpp new file mode 100644 index 000000000..6c592425c --- /dev/null +++ b/Source/WebKit2/PluginProcess/qt/PluginControllerProxyQt.cpp @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2011 Nokia Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PluginControllerProxy.h" + +#if ENABLE(PLUGIN_PROCESS) + +#include "PluginProcess.h" +#include <WebCore/NotImplemented.h> + +using namespace WebCore; + +namespace WebKit { + +void PluginControllerProxy::platformInitialize() +{ + notImplemented(); +} + +void PluginControllerProxy::platformDestroy() +{ + notImplemented(); +} + +void PluginControllerProxy::platformGeometryDidChange() +{ + notImplemented(); +} + +} // namespace WebKit + +#endif // ENABLE(PLUGIN_PROCESS) diff --git a/Source/WebKit2/PluginProcess/qt/PluginProcessMainQt.cpp b/Source/WebKit2/PluginProcess/qt/PluginProcessMainQt.cpp new file mode 100644 index 000000000..3e0033ff0 --- /dev/null +++ b/Source/WebKit2/PluginProcess/qt/PluginProcessMainQt.cpp @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2010, 2011 Nokia Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PluginProcessMain.h" + +#if ENABLE(PLUGIN_PROCESS) + +#include "CommandLine.h" +#include "PluginProcess.h" +#include "RunLoop.h" +#include <WebCore/NotImplemented.h> +#include <runtime/InitializeThreading.h> +#include <wtf/MainThread.h> +#include <wtf/RetainPtr.h> +#include <wtf/text/CString.h> +#include <wtf/text/WTFString.h> + +#define SHOW_CRASH_REPORTER 1 + +namespace WebKit { + +int PluginProcessMain(const CommandLine& commandLine) +{ + String serviceName = commandLine["servicename"]; + if (serviceName.isEmpty()) + return EXIT_FAILURE; + +#if !SHOW_CRASH_REPORTER + // Installs signal handlers that exit on a crash so that CrashReporter does not show up. + signal(SIGILL, _exit); + signal(SIGFPE, _exit); + signal(SIGBUS, _exit); + signal(SIGSEGV, _exit); +#endif + + JSC::initializeThreading(); + WTF::initializeMainThread(); + RunLoop::initializeMainRunLoop(); + + RunLoop::run(); + + return 0; +} + +} + +#endif // ENABLE(PLUGIN_PROCESS) diff --git a/Source/WebKit2/PluginProcess/qt/PluginProcessQt.cpp b/Source/WebKit2/PluginProcess/qt/PluginProcessQt.cpp new file mode 100644 index 000000000..69f84025f --- /dev/null +++ b/Source/WebKit2/PluginProcess/qt/PluginProcessQt.cpp @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2010 Apple Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, + * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "PluginProcess.h" + +#if ENABLE(PLUGIN_PROCESS) + +#include "NetscapePlugin.h" +#include "PluginProcessCreationParameters.h" +#include <WebCore/NotImplemented.h> + +namespace WebKit { + +void PluginProcess::platformInitialize(const PluginProcessCreationParameters& parameters) +{ + notImplemented(); +} + +} // namespace WebKit + +#endif // ENABLE(PLUGIN_PROCESS) |
