From 6882a04fb36642862b11efe514251d32070c3d65 Mon Sep 17 00:00:00 2001 From: Konstantin Tokarev Date: Thu, 25 Aug 2016 19:20:41 +0300 Subject: Imported QtWebKit TP3 (git b57bc6801f1876c3220d5a4bfea33d620d477443) Change-Id: I3b1d8a2808782c9f34d50240000e20cb38d3680f Reviewed-by: Konstantin Tokarev --- .../UIProcess/Network/NetworkProcessProxy.cpp | 256 +++++++++++++++++---- 1 file changed, 216 insertions(+), 40 deletions(-) (limited to 'Source/WebKit2/UIProcess/Network/NetworkProcessProxy.cpp') diff --git a/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.cpp b/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.cpp index f15bdb442..3fb4855d8 100644 --- a/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.cpp +++ b/Source/WebKit2/UIProcess/Network/NetworkProcessProxy.cpp @@ -26,81 +26,139 @@ #include "config.h" #include "NetworkProcessProxy.h" -#if ENABLE(NETWORK_PROCESS) - #include "AuthenticationChallengeProxy.h" #include "CustomProtocolManagerProxyMessages.h" #include "DownloadProxyMessages.h" #include "NetworkProcessCreationParameters.h" #include "NetworkProcessMessages.h" -#include "WebContext.h" #include "WebProcessMessages.h" -#include +#include "WebProcessPool.h" +#include "WebsiteData.h" +#include -#if USE(SECURITY_FRAMEWORK) +#if ENABLE(SEC_ITEM_SHIM) #include "SecItemShimProxy.h" #endif +#if PLATFORM(IOS) +#include +#endif + #define MESSAGE_CHECK(assertion) MESSAGE_CHECK_BASE(assertion, connection()) using namespace WebCore; namespace WebKit { -PassRefPtr NetworkProcessProxy::create(WebContext* webContext) +static uint64_t generateCallbackID() { - return adoptRef(new NetworkProcessProxy(webContext)); + static uint64_t callbackID; + + return ++callbackID; } -NetworkProcessProxy::NetworkProcessProxy(WebContext* webContext) - : m_webContext(webContext) +Ref NetworkProcessProxy::create(WebProcessPool& processPool) +{ + return adoptRef(*new NetworkProcessProxy(processPool)); +} + +NetworkProcessProxy::NetworkProcessProxy(WebProcessPool& processPool) + : m_processPool(processPool) , m_numPendingConnectionRequests(0) -#if ENABLE(CUSTOM_PROTOCOLS) - , m_customProtocolManagerProxy(this) -#endif + , m_customProtocolManagerProxy(this, processPool) + , m_throttler(*this) { connect(); } NetworkProcessProxy::~NetworkProcessProxy() { + ASSERT(m_pendingFetchWebsiteDataCallbacks.isEmpty()); + ASSERT(m_pendingDeleteWebsiteDataCallbacks.isEmpty()); + ASSERT(m_pendingDeleteWebsiteDataForOriginsCallbacks.isEmpty()); } void NetworkProcessProxy::getLaunchOptions(ProcessLauncher::LaunchOptions& launchOptions) { - launchOptions.processType = ProcessLauncher::NetworkProcess; - platformGetLaunchOptions(launchOptions); + launchOptions.processType = ProcessLauncher::ProcessType::Network; + ChildProcessProxy::getLaunchOptions(launchOptions); } -void NetworkProcessProxy::connectionWillOpen(CoreIPC::Connection* connection) +void NetworkProcessProxy::connectionWillOpen(IPC::Connection& connection) { -#if USE(SECURITY_FRAMEWORK) - SecItemShimProxy::shared().initializeConnection(connection); +#if ENABLE(SEC_ITEM_SHIM) + SecItemShimProxy::singleton().initializeConnection(connection); +#else + UNUSED_PARAM(connection); #endif } -void NetworkProcessProxy::connectionWillClose(CoreIPC::Connection*) +void NetworkProcessProxy::processWillShutDown(IPC::Connection& connection) { + ASSERT_UNUSED(connection, this->connection() == &connection); } void NetworkProcessProxy::getNetworkProcessConnection(PassRefPtr reply) { m_pendingConnectionReplies.append(reply); - if (isLaunching()) { + if (state() == State::Launching) { m_numPendingConnectionRequests++; return; } - connection()->send(Messages::NetworkProcess::CreateNetworkConnectionToWebProcess(), 0, CoreIPC::DispatchMessageEvenWhenWaitingForSyncReply); + connection()->send(Messages::NetworkProcess::CreateNetworkConnectionToWebProcess(), 0, IPC::DispatchMessageEvenWhenWaitingForSyncReply); } -DownloadProxy* NetworkProcessProxy::createDownloadProxy() +DownloadProxy* NetworkProcessProxy::createDownloadProxy(const ResourceRequest& resourceRequest) { if (!m_downloadProxyMap) - m_downloadProxyMap = adoptPtr(new DownloadProxyMap(this)); + m_downloadProxyMap = std::make_unique(this); + + return m_downloadProxyMap->createDownloadProxy(m_processPool, resourceRequest); +} - return m_downloadProxyMap->createDownloadProxy(m_webContext); +void NetworkProcessProxy::fetchWebsiteData(SessionID sessionID, WebsiteDataTypes dataTypes, std::function completionHandler) +{ + ASSERT(canSendMessage()); + + uint64_t callbackID = generateCallbackID(); + auto token = throttler().backgroundActivityToken(); + + m_pendingFetchWebsiteDataCallbacks.add(callbackID, [token, completionHandler](WebsiteData websiteData) { + completionHandler(WTFMove(websiteData)); + }); + + send(Messages::WebProcess::FetchWebsiteData(sessionID, dataTypes, callbackID), 0); +} + +void NetworkProcessProxy::deleteWebsiteData(WebCore::SessionID sessionID, WebsiteDataTypes dataTypes, std::chrono::system_clock::time_point modifiedSince, std::function completionHandler) +{ + auto callbackID = generateCallbackID(); + auto token = throttler().backgroundActivityToken(); + + m_pendingDeleteWebsiteDataCallbacks.add(callbackID, [token, completionHandler] { + completionHandler(); + }); + send(Messages::NetworkProcess::DeleteWebsiteData(sessionID, dataTypes, modifiedSince, callbackID), 0); +} + +void NetworkProcessProxy::deleteWebsiteDataForOrigins(SessionID sessionID, WebsiteDataTypes dataTypes, const Vector>& origins, const Vector& cookieHostNames, std::function completionHandler) +{ + ASSERT(canSendMessage()); + + uint64_t callbackID = generateCallbackID(); + auto token = throttler().backgroundActivityToken(); + + m_pendingDeleteWebsiteDataForOriginsCallbacks.add(callbackID, [token, completionHandler] { + completionHandler(); + }); + + Vector originData; + for (auto& origin : origins) + originData.append(SecurityOriginData::fromSecurityOrigin(*origin)); + + send(Messages::NetworkProcess::DeleteWebsiteDataForOrigins(sessionID, dataTypes, originData, cookieHostNames, callbackID), 0); } void NetworkProcessProxy::networkProcessCrashedOrFailedToLaunch() @@ -109,29 +167,43 @@ void NetworkProcessProxy::networkProcessCrashedOrFailedToLaunch() while (!m_pendingConnectionReplies.isEmpty()) { RefPtr reply = m_pendingConnectionReplies.takeFirst(); -#if PLATFORM(MAC) - reply->send(CoreIPC::Attachment(0, MACH_MSG_TYPE_MOVE_SEND)); +#if USE(UNIX_DOMAIN_SOCKETS) + reply->send(IPC::Attachment()); +#elif OS(DARWIN) + reply->send(IPC::Attachment(0, MACH_MSG_TYPE_MOVE_SEND)); #else notImplemented(); #endif } + for (const auto& callback : m_pendingFetchWebsiteDataCallbacks.values()) + callback(WebsiteData()); + m_pendingFetchWebsiteDataCallbacks.clear(); + + for (const auto& callback : m_pendingDeleteWebsiteDataCallbacks.values()) + callback(); + m_pendingDeleteWebsiteDataCallbacks.clear(); + + for (const auto& callback : m_pendingDeleteWebsiteDataForOriginsCallbacks.values()) + callback(); + m_pendingDeleteWebsiteDataForOriginsCallbacks.clear(); + // Tell the network process manager to forget about this network process proxy. This may cause us to be deleted. - m_webContext->networkProcessCrashed(this); + m_processPool.networkProcessCrashed(this); } -void NetworkProcessProxy::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::MessageDecoder& decoder) +void NetworkProcessProxy::didReceiveMessage(IPC::Connection& connection, IPC::MessageDecoder& decoder) { if (dispatchMessage(connection, decoder)) return; - if (m_webContext->dispatchMessage(connection, decoder)) + if (m_processPool.dispatchMessage(connection, decoder)) return; didReceiveNetworkProcessProxyMessage(connection, decoder); } -void NetworkProcessProxy::didReceiveSyncMessage(CoreIPC::Connection* connection, CoreIPC::MessageDecoder& decoder, OwnPtr& replyEncoder) +void NetworkProcessProxy::didReceiveSyncMessage(IPC::Connection& connection, IPC::MessageDecoder& decoder, std::unique_ptr& replyEncoder) { if (dispatchSyncMessage(connection, decoder, replyEncoder)) return; @@ -139,28 +211,32 @@ void NetworkProcessProxy::didReceiveSyncMessage(CoreIPC::Connection* connection, ASSERT_NOT_REACHED(); } -void NetworkProcessProxy::didClose(CoreIPC::Connection*) +void NetworkProcessProxy::didClose(IPC::Connection&) { if (m_downloadProxyMap) m_downloadProxyMap->processDidClose(); + m_tokenForHoldingLockedFiles = nullptr; + // This may cause us to be deleted. networkProcessCrashedOrFailedToLaunch(); } -void NetworkProcessProxy::didReceiveInvalidMessage(CoreIPC::Connection*, CoreIPC::StringReference, CoreIPC::StringReference) +void NetworkProcessProxy::didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference) { } -void NetworkProcessProxy::didCreateNetworkConnectionToWebProcess(const CoreIPC::Attachment& connectionIdentifier) +void NetworkProcessProxy::didCreateNetworkConnectionToWebProcess(const IPC::Attachment& connectionIdentifier) { ASSERT(!m_pendingConnectionReplies.isEmpty()); // Grab the first pending connection reply. RefPtr reply = m_pendingConnectionReplies.takeFirst(); -#if PLATFORM(MAC) - reply->send(CoreIPC::Attachment(connectionIdentifier.port(), MACH_MSG_TYPE_MOVE_SEND)); +#if USE(UNIX_DOMAIN_SOCKETS) + reply->send(connectionIdentifier); +#elif OS(DARWIN) + reply->send(IPC::Attachment(connectionIdentifier.port(), MACH_MSG_TYPE_MOVE_SEND)); #else notImplemented(); #endif @@ -175,11 +251,29 @@ void NetworkProcessProxy::didReceiveAuthenticationChallenge(uint64_t pageID, uin page->didReceiveAuthenticationChallengeProxy(frameID, authenticationChallenge.release()); } -void NetworkProcessProxy::didFinishLaunching(ProcessLauncher* launcher, CoreIPC::Connection::Identifier connectionIdentifier) +void NetworkProcessProxy::didFetchWebsiteData(uint64_t callbackID, const WebsiteData& websiteData) +{ + auto callback = m_pendingFetchWebsiteDataCallbacks.take(callbackID); + callback(websiteData); +} + +void NetworkProcessProxy::didDeleteWebsiteData(uint64_t callbackID) +{ + auto callback = m_pendingDeleteWebsiteDataCallbacks.take(callbackID); + callback(); +} + +void NetworkProcessProxy::didDeleteWebsiteDataForOrigins(uint64_t callbackID) +{ + auto callback = m_pendingDeleteWebsiteDataForOriginsCallbacks.take(callbackID); + callback(); +} + +void NetworkProcessProxy::didFinishLaunching(ProcessLauncher* launcher, IPC::Connection::Identifier connectionIdentifier) { ChildProcessProxy::didFinishLaunching(launcher, connectionIdentifier); - if (CoreIPC::Connection::identifierIsNull(connectionIdentifier)) { + if (IPC::Connection::identifierIsNull(connectionIdentifier)) { // FIXME: Do better cleanup here. return; } @@ -189,12 +283,94 @@ void NetworkProcessProxy::didFinishLaunching(ProcessLauncher* launcher, CoreIPC: m_numPendingConnectionRequests = 0; -#if PLATFORM(MAC) - if (m_webContext->canEnableProcessSuppressionForNetworkProcess()) +#if PLATFORM(COCOA) + if (m_processPool.processSuppressionEnabled()) setProcessSuppressionEnabled(true); #endif + +#if PLATFORM(IOS) + if (xpc_connection_t connection = this->connection()->xpcConnection()) + m_throttler.didConnectToProcess(xpc_connection_get_pid(connection)); +#endif } -} // namespace WebKit +void NetworkProcessProxy::logSampledDiagnosticMessage(uint64_t pageID, const String& message, const String& description) +{ + WebPageProxy* page = WebProcessProxy::webPage(pageID); + // FIXME: We do this null-check because by the time the decision to log is made, the page may be gone. We should refactor to avoid this, + // but for now we simply drop the message in the rare case this happens. + if (!page) + return; + + page->logSampledDiagnosticMessage(message, description); +} + +void NetworkProcessProxy::logSampledDiagnosticMessageWithResult(uint64_t pageID, const String& message, const String& description, uint32_t result) +{ + WebPageProxy* page = WebProcessProxy::webPage(pageID); + // FIXME: We do this null-check because by the time the decision to log is made, the page may be gone. We should refactor to avoid this, + // but for now we simply drop the message in the rare case this happens. + if (!page) + return; + + page->logSampledDiagnosticMessageWithResult(message, description, result); +} + +void NetworkProcessProxy::logSampledDiagnosticMessageWithValue(uint64_t pageID, const String& message, const String& description, const String& value) +{ + WebPageProxy* page = WebProcessProxy::webPage(pageID); + // FIXME: We do this null-check because by the time the decision to log is made, the page may be gone. We should refactor to avoid this, + // but for now we simply drop the message in the rare case this happens. + if (!page) + return; + + page->logSampledDiagnosticMessageWithValue(message, description, value); +} + +void NetworkProcessProxy::sendProcessWillSuspendImminently() +{ + if (!canSendMessage()) + return; + + bool handled = false; + sendSync(Messages::NetworkProcess::ProcessWillSuspendImminently(), Messages::NetworkProcess::ProcessWillSuspendImminently::Reply(handled), 0, std::chrono::seconds(1)); +} + +void NetworkProcessProxy::sendPrepareToSuspend() +{ + if (canSendMessage()) + send(Messages::NetworkProcess::PrepareToSuspend(), 0); +} + +void NetworkProcessProxy::sendCancelPrepareToSuspend() +{ + if (canSendMessage()) + send(Messages::NetworkProcess::CancelPrepareToSuspend(), 0); +} -#endif // ENABLE(NETWORK_PROCESS) +void NetworkProcessProxy::sendProcessDidResume() +{ + if (canSendMessage()) + send(Messages::NetworkProcess::ProcessDidResume(), 0); +} + +void NetworkProcessProxy::processReadyToSuspend() +{ + m_throttler.processReadyToSuspend(); +} + +void NetworkProcessProxy::didSetAssertionState(AssertionState) +{ +} + +void NetworkProcessProxy::setIsHoldingLockedFiles(bool isHoldingLockedFiles) +{ + if (!isHoldingLockedFiles) { + m_tokenForHoldingLockedFiles = nullptr; + return; + } + if (!m_tokenForHoldingLockedFiles) + m_tokenForHoldingLockedFiles = m_throttler.backgroundActivityToken(); +} + +} // namespace WebKit -- cgit v1.2.1