PluginProcessProxy.cpp [plain text]
#include "config.h"
#include "PluginProcessProxy.h"
#if ENABLE(PLUGIN_PROCESS)
#include "PluginProcessCreationParameters.h"
#include "PluginProcessManager.h"
#include "PluginProcessMessages.h"
#include "RunLoop.h"
#include "WebContext.h"
#include "WebCoreArgumentCoders.h"
#include "WebPluginSiteDataManager.h"
#include "WebProcessMessages.h"
#include "WebProcessProxy.h"
#if PLATFORM(MAC)
#include "MachPort.h"
#endif
namespace WebKit {
PassOwnPtr<PluginProcessProxy> PluginProcessProxy::create(PluginProcessManager* PluginProcessManager, const PluginInfoStore::Plugin& pluginInfo)
{
return adoptPtr(new PluginProcessProxy(PluginProcessManager, pluginInfo));
}
PluginProcessProxy::PluginProcessProxy(PluginProcessManager* PluginProcessManager, const PluginInfoStore::Plugin& pluginInfo)
: m_pluginProcessManager(PluginProcessManager)
, m_pluginInfo(pluginInfo)
, m_numPendingConnectionRequests(0)
#if PLATFORM(MAC)
, m_modalWindowIsShowing(false)
, m_fullscreenWindowIsShowing(false)
, m_preFullscreenAppPresentationOptions(0)
#endif
{
ProcessLauncher::LaunchOptions launchOptions;
launchOptions.processType = ProcessLauncher::PluginProcess;
#if PLATFORM(MAC)
launchOptions.architecture = pluginInfo.pluginArchitecture;
launchOptions.executableHeap = PluginProcessProxy::pluginNeedsExecutableHeap(pluginInfo);
#endif
m_processLauncher = ProcessLauncher::create(this, launchOptions);
}
PluginProcessProxy::~PluginProcessProxy()
{
}
void PluginProcessProxy::getPluginProcessConnection(PassRefPtr<Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply> reply)
{
m_pendingConnectionReplies.append(reply);
if (m_processLauncher->isLaunching()) {
m_numPendingConnectionRequests++;
return;
}
m_connection->send(Messages::PluginProcess::CreateWebProcessConnection(), 0, CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply);
}
void PluginProcessProxy::getSitesWithData(WebPluginSiteDataManager* webPluginSiteDataManager, uint64_t callbackID)
{
ASSERT(!m_pendingGetSitesReplies.contains(callbackID));
m_pendingGetSitesReplies.set(callbackID, webPluginSiteDataManager);
if (m_processLauncher->isLaunching()) {
m_pendingGetSitesRequests.append(callbackID);
return;
}
m_connection->send(Messages::PluginProcess::GetSitesWithData(callbackID), 0);
}
void PluginProcessProxy::clearSiteData(WebPluginSiteDataManager* webPluginSiteDataManager, const Vector<String>& sites, uint64_t flags, uint64_t maxAgeInSeconds, uint64_t callbackID)
{
ASSERT(!m_pendingClearSiteDataReplies.contains(callbackID));
m_pendingClearSiteDataReplies.set(callbackID, webPluginSiteDataManager);
if (m_processLauncher->isLaunching()) {
ClearSiteDataRequest request;
request.sites = sites;
request.flags = flags;
request.maxAgeInSeconds = maxAgeInSeconds;
request.callbackID = callbackID;
m_pendingClearSiteDataRequests.append(request);
return;
}
m_connection->send(Messages::PluginProcess::ClearSiteData(sites, flags, maxAgeInSeconds, callbackID), 0);
}
void PluginProcessProxy::terminate()
{
m_processLauncher->terminateProcess();
}
void PluginProcessProxy::pluginProcessCrashedOrFailedToLaunch()
{
while (!m_pendingConnectionReplies.isEmpty()) {
RefPtr<Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply> reply = m_pendingConnectionReplies.takeFirst();
#if PLATFORM(MAC)
reply->send(CoreIPC::MachPort(0, MACH_MSG_TYPE_MOVE_SEND));
#else
ASSERT_NOT_REACHED();
#endif
}
while (!m_pendingGetSitesReplies.isEmpty())
didGetSitesWithData(Vector<String>(), m_pendingGetSitesReplies.begin()->first);
while (!m_pendingClearSiteDataReplies.isEmpty())
didClearSiteData(m_pendingClearSiteDataReplies.begin()->first);
m_pluginProcessManager->removePluginProcessProxy(this);
delete this;
}
void PluginProcessProxy::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageID messageID, CoreIPC::ArgumentDecoder* arguments)
{
didReceivePluginProcessProxyMessage(connection, messageID, arguments);
}
void PluginProcessProxy::didClose(CoreIPC::Connection*)
{
#if PLATFORM(MAC)
if (m_modalWindowIsShowing)
endModal();
if (m_fullscreenWindowIsShowing)
exitFullscreen();
#endif
const Vector<WebContext*>& contexts = WebContext::allContexts();
for (size_t i = 0; i < contexts.size(); ++i)
contexts[i]->sendToAllProcesses(Messages::WebProcess::PluginProcessCrashed(m_pluginInfo.path));
pluginProcessCrashedOrFailedToLaunch();
}
void PluginProcessProxy::didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::MessageID)
{
}
void PluginProcessProxy::syncMessageSendTimedOut(CoreIPC::Connection*)
{
}
void PluginProcessProxy::didFinishLaunching(ProcessLauncher*, CoreIPC::Connection::Identifier connectionIdentifier)
{
ASSERT(!m_connection);
if (!connectionIdentifier) {
pluginProcessCrashedOrFailedToLaunch();
return;
}
m_connection = CoreIPC::Connection::createServerConnection(connectionIdentifier, this, RunLoop::main());
#if PLATFORM(MAC)
m_connection->setShouldCloseConnectionOnMachExceptions();
#endif
m_connection->open();
PluginProcessCreationParameters parameters;
parameters.pluginPath = m_pluginInfo.path;
platformInitializePluginProcess(parameters);
m_connection->send(Messages::PluginProcess::InitializePluginProcess(parameters), 0);
for (size_t i = 0; i < m_pendingGetSitesRequests.size(); ++i)
m_connection->send(Messages::PluginProcess::GetSitesWithData(m_pendingGetSitesRequests[i]), 0);
m_pendingGetSitesRequests.clear();
for (size_t i = 0; i < m_pendingClearSiteDataRequests.size(); ++i) {
const ClearSiteDataRequest& request = m_pendingClearSiteDataRequests[i];
m_connection->send(Messages::PluginProcess::ClearSiteData(request.sites, request.flags, request.maxAgeInSeconds, request.callbackID), 0);
}
m_pendingClearSiteDataRequests.clear();
for (unsigned i = 0; i < m_numPendingConnectionRequests; ++i)
m_connection->send(Messages::PluginProcess::CreateWebProcessConnection(), 0);
m_numPendingConnectionRequests = 0;
}
#if PLATFORM(MAC)
void PluginProcessProxy::didCreateWebProcessConnection(const CoreIPC::MachPort& machPort)
{
ASSERT(!m_pendingConnectionReplies.isEmpty());
RefPtr<Messages::WebProcessProxy::GetPluginProcessConnection::DelayedReply> reply = m_pendingConnectionReplies.takeFirst();
reply->send(CoreIPC::MachPort(machPort.port(), MACH_MSG_TYPE_MOVE_SEND));
}
#endif
void PluginProcessProxy::didGetSitesWithData(const Vector<String>& sites, uint64_t callbackID)
{
RefPtr<WebPluginSiteDataManager> webPluginSiteDataManager = m_pendingGetSitesReplies.take(callbackID);
ASSERT(webPluginSiteDataManager);
webPluginSiteDataManager->didGetSitesWithDataForSinglePlugin(sites, callbackID);
}
void PluginProcessProxy::didClearSiteData(uint64_t callbackID)
{
RefPtr<WebPluginSiteDataManager> webPluginSiteDataManager = m_pendingClearSiteDataReplies.take(callbackID);
ASSERT(webPluginSiteDataManager);
webPluginSiteDataManager->didClearSiteDataForSinglePlugin(callbackID);
}
}
#endif // ENABLE(PLUGIN_PROCESS)