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/WebProcess/Plugins/PluginProcessConnection.cpp | |
download | qtwebkit-40736c5763bf61337c8c14e16d8587db021a87d4.tar.gz |
Imported WebKit commit 2ea9d364d0f6efa8fa64acf19f451504c59be0e4 (http://svn.webkit.org/repository/webkit/trunk@104285)
Diffstat (limited to 'Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.cpp')
-rw-r--r-- | Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.cpp | 178 |
1 files changed, 178 insertions, 0 deletions
diff --git a/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.cpp b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.cpp new file mode 100644 index 000000000..b2152713b --- /dev/null +++ b/Source/WebKit2/WebProcess/Plugins/PluginProcessConnection.cpp @@ -0,0 +1,178 @@ +/* + * 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 "PluginProcessConnection.h" + +#if ENABLE(PLUGIN_PROCESS) + +#include "NPRemoteObjectMap.h" +#include "NPRuntimeObjectMap.h" +#include "PluginProcessConnectionManager.h" +#include "PluginProxy.h" +#include "WebProcess.h" +#include "WebProcessProxyMessages.h" +#include <WebCore/FileSystem.h> + +using namespace WebCore; + +namespace WebKit { + +// The timeout, in seconds, when sending sync messages to the plug-in. +static const double syncMessageTimeout = 45; + +static double defaultSyncMessageTimeout(const String& pluginPath) +{ + // FIXME: We should key this off something other than the path. + + // We don't want a message timeout for the AppleConnect plug-in. + if (pathGetFileName(pluginPath) == "AppleConnect.plugin") + return CoreIPC::Connection::NoTimeout; + + // We don't want a message timeout for the Microsoft SharePoint plug-in + // since it can spin a nested run loop in response to an NPN_Invoke, making it seem like + // the plug-in process is hung. See <rdar://problem/9536303>. + // FIXME: Instead of changing the default sync message timeout, CoreIPC could send an + // asynchronous message which the other process would have to reply to on the main thread. + // This way we could check if the plug-in process is actually hung or not. + if (pathGetFileName(pluginPath) == "SharePointBrowserPlugin.plugin") + return CoreIPC::Connection::NoTimeout; + + // We don't want a message timeout for the BankID plug-in since it can spin a nested + // run loop when it's waiting for a reply to an AppleEvent. + if (pathGetFileName(pluginPath) == "PersonalPlugin.bundle") + return CoreIPC::Connection::NoTimeout; + + if (WebProcess::shared().disablePluginProcessMessageTimeout()) + return CoreIPC::Connection::NoTimeout; + + return syncMessageTimeout; +} + +PluginProcessConnection::PluginProcessConnection(PluginProcessConnectionManager* pluginProcessConnectionManager, const String& pluginPath, CoreIPC::Connection::Identifier connectionIdentifier) + : m_pluginProcessConnectionManager(pluginProcessConnectionManager) + , m_pluginPath(pluginPath) +{ + m_connection = CoreIPC::Connection::createClientConnection(connectionIdentifier, this, WebProcess::shared().runLoop()); + + m_connection->setDefaultSyncMessageTimeout(defaultSyncMessageTimeout(m_pluginPath)); + m_npRemoteObjectMap = NPRemoteObjectMap::create(m_connection.get()); + + m_connection->open(); +} + +PluginProcessConnection::~PluginProcessConnection() +{ + ASSERT(!m_connection); + ASSERT(!m_npRemoteObjectMap); +} + +void PluginProcessConnection::addPluginProxy(PluginProxy* plugin) +{ + ASSERT(!m_plugins.contains(plugin->pluginInstanceID())); + m_plugins.set(plugin->pluginInstanceID(), plugin); +} + +void PluginProcessConnection::removePluginProxy(PluginProxy* plugin) +{ + ASSERT(m_plugins.contains(plugin->pluginInstanceID())); + m_plugins.remove(plugin->pluginInstanceID()); + + // Invalidate all objects related to this plug-in. + m_npRemoteObjectMap->pluginDestroyed(plugin); + + if (!m_plugins.isEmpty()) + return; + + m_npRemoteObjectMap = nullptr; + + // We have no more plug-ins, invalidate the connection to the plug-in process. + ASSERT(m_connection); + m_connection->invalidate(); + m_connection = nullptr; + + // This will cause us to be deleted. + m_pluginProcessConnectionManager->removePluginProcessConnection(this); +} + +void PluginProcessConnection::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments) +{ + ASSERT(arguments->destinationID()); + + PluginProxy* pluginProxy = m_plugins.get(arguments->destinationID()); + if (!pluginProxy) + return; + + pluginProxy->didReceivePluginProxyMessage(connection, messageID, arguments); +} + +void PluginProcessConnection::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments, OwnPtr<CoreIPC::ArgumentEncoder>& reply) +{ + if (messageID.is<CoreIPC::MessageClassNPObjectMessageReceiver>()) { + m_npRemoteObjectMap->didReceiveSyncMessage(connection, messageID, arguments, reply); + return; + } + + uint64_t destinationID = arguments->destinationID(); + + if (!destinationID) { + didReceiveSyncPluginProcessConnectionMessage(connection, messageID, arguments, reply); + return; + } + + PluginProxy* pluginProxy = m_plugins.get(destinationID); + if (!pluginProxy) + return; + + pluginProxy->didReceiveSyncPluginProxyMessage(connection, messageID, arguments, reply); +} + +void PluginProcessConnection::didClose(CoreIPC::Connection*) +{ + // The plug-in process must have crashed. + for (HashMap<uint64_t, PluginProxy*>::const_iterator::Values it = m_plugins.begin().values(), end = m_plugins.end().values(); it != end; ++it) { + PluginProxy* pluginProxy = (*it); + + pluginProxy->pluginProcessCrashed(); + } +} + +void PluginProcessConnection::didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::MessageID) +{ +} + +void PluginProcessConnection::syncMessageSendTimedOut(CoreIPC::Connection*) +{ + WebProcess::shared().connection()->send(Messages::WebProcessProxy::PluginSyncMessageSendTimedOut(m_pluginPath), 0); +} + +void PluginProcessConnection::setException(const String& exceptionString) +{ + NPRuntimeObjectMap::setGlobalException(exceptionString); +} + +} // namespace WebKit + +#endif // ENABLE(PLUGIN_PROCESS) |