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 --- Source/WebKit2/UIProcess/WebProcessPool.h | 594 ++++++++++++++++++++++++++++++ 1 file changed, 594 insertions(+) create mode 100644 Source/WebKit2/UIProcess/WebProcessPool.h (limited to 'Source/WebKit2/UIProcess/WebProcessPool.h') diff --git a/Source/WebKit2/UIProcess/WebProcessPool.h b/Source/WebKit2/UIProcess/WebProcessPool.h new file mode 100644 index 000000000..f2b441f9a --- /dev/null +++ b/Source/WebKit2/UIProcess/WebProcessPool.h @@ -0,0 +1,594 @@ +/* + * Copyright (C) 2010, 2011, 2012, 2013 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 WebProcessPool_h +#define WebProcessPool_h + +#include "APIDictionary.h" +#include "APIObject.h" +#include "APIProcessPoolConfiguration.h" +#include "APIWebsiteDataStore.h" +#include "DownloadProxyMap.h" +#include "GenericCallback.h" +#include "MessageReceiver.h" +#include "MessageReceiverMap.h" +#include "NetworkProcessProxy.h" +#include "PlugInAutoStartProvider.h" +#include "PluginInfoStore.h" +#include "ProcessThrottler.h" +#include "StatisticsRequest.h" +#include "VisitedLinkStore.h" +#include "WebContextClient.h" +#include "WebContextConnectionClient.h" +#include "WebContextInjectedBundleClient.h" +#include "WebProcessProxy.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if ENABLE(DATABASE_PROCESS) +#include "DatabaseProcessProxy.h" +#endif + +#if ENABLE(MEDIA_SESSION) +#include "WebMediaSessionFocusManager.h" +#endif + +#if PLATFORM(COCOA) +OBJC_CLASS NSMutableDictionary; +OBJC_CLASS NSObject; +OBJC_CLASS NSString; +#endif + +namespace API { +class AutomationClient; +class DownloadClient; +class LegacyContextHistoryClient; +class PageConfiguration; +} + +namespace WebKit { + +class DownloadProxy; +class WebAutomationSession; +class WebContextSupplement; +class WebIconDatabase; +class WebPageGroup; +class WebPageProxy; +struct NetworkProcessCreationParameters; +struct StatisticsData; +struct WebProcessCreationParameters; + +typedef GenericCallback DictionaryCallback; + +#if PLATFORM(COCOA) +int networkProcessLatencyQOS(); +int networkProcessThroughputQOS(); +int webProcessLatencyQOS(); +int webProcessThroughputQOS(); +#endif + +class WebProcessPool final : public API::ObjectImpl, private IPC::MessageReceiver +#if ENABLE(NETSCAPE_PLUGIN_API) + , private PluginInfoStoreClient +#endif + { +public: + static Ref create(API::ProcessPoolConfiguration&); + + explicit WebProcessPool(API::ProcessPoolConfiguration&); + virtual ~WebProcessPool(); + + API::ProcessPoolConfiguration& configuration() { return m_configuration.get(); } + + static const Vector& allProcessPools(); + + template + T* supplement() + { + return static_cast(m_supplements.get(T::supplementName())); + } + + template + void addSupplement() + { + m_supplements.add(T::supplementName(), T::create(this)); + } + + void addMessageReceiver(IPC::StringReference messageReceiverName, IPC::MessageReceiver&); + void addMessageReceiver(IPC::StringReference messageReceiverName, uint64_t destinationID, IPC::MessageReceiver&); + void removeMessageReceiver(IPC::StringReference messageReceiverName, uint64_t destinationID); + + bool dispatchMessage(IPC::Connection&, IPC::MessageDecoder&); + bool dispatchSyncMessage(IPC::Connection&, IPC::MessageDecoder&, std::unique_ptr&); + + void initializeClient(const WKContextClientBase*); + void initializeInjectedBundleClient(const WKContextInjectedBundleClientBase*); + void initializeConnectionClient(const WKContextConnectionClientBase*); + void setHistoryClient(std::unique_ptr); + void setDownloadClient(std::unique_ptr); + void setAutomationClient(std::unique_ptr); + + void setMaximumNumberOfProcesses(unsigned); // Can only be called when there are no processes running. + unsigned maximumNumberOfProcesses() const { return !m_configuration->maximumProcessCount() ? UINT_MAX : m_configuration->maximumProcessCount(); } + + const Vector>& processes() const { return m_processes; } + + // WebProcess or NetworkProcess as approporiate for current process model. The connection must be non-null. + IPC::Connection* networkingProcessConnection(); + + template void sendToAllProcesses(const T& message); + template void sendToAllProcessesRelaunchingThemIfNecessary(const T& message); + template void sendToOneProcess(T&& message); + + // Sends the message to WebProcess or NetworkProcess as approporiate for current process model. + template void sendToNetworkingProcess(T&& message); + template void sendToNetworkingProcessRelaunchingIfNecessary(T&& message); + + // Sends the message to WebProcess or DatabaseProcess as approporiate for current process model. + template void sendToDatabaseProcessRelaunchingIfNecessary(T&& message); + + void processDidFinishLaunching(WebProcessProxy*); + + // Disconnect the process from the context. + void disconnectProcess(WebProcessProxy*); + + API::WebsiteDataStore* websiteDataStore() const { return m_websiteDataStore.get(); } + + Ref createWebPage(PageClient&, Ref&&); + + const String& injectedBundlePath() const { return m_configuration->injectedBundlePath(); } + + DownloadProxy* download(WebPageProxy* initiatingPage, const WebCore::ResourceRequest&); + DownloadProxy* resumeDownload(const API::Data* resumeData, const String& path); + + void setInjectedBundleInitializationUserData(PassRefPtr userData) { m_injectedBundleInitializationUserData = userData; } + + void postMessageToInjectedBundle(const String&, API::Object*); + + void populateVisitedLinks(); + +#if ENABLE(NETSCAPE_PLUGIN_API) + void setAdditionalPluginsDirectory(const String&); + + PluginInfoStore& pluginInfoStore() { return m_pluginInfoStore; } + + void setPluginLoadClientPolicy(WebCore::PluginLoadClientPolicy, const String& host, const String& bundleIdentifier, const String& versionString); + void clearPluginClientPolicies(); +#endif + + PlatformProcessIdentifier networkProcessIdentifier(); + + void setAlwaysUsesComplexTextCodePath(bool); + void setShouldUseFontSmoothing(bool); + + void registerURLSchemeAsEmptyDocument(const String&); + void registerURLSchemeAsSecure(const String&); + void registerURLSchemeAsBypassingContentSecurityPolicy(const String&); + void setDomainRelaxationForbiddenForURLScheme(const String&); + void setCanHandleHTTPSServerTrustEvaluation(bool); + void registerURLSchemeAsLocal(const String&); + void registerURLSchemeAsNoAccess(const String&); + void registerURLSchemeAsDisplayIsolated(const String&); + void registerURLSchemeAsCORSEnabled(const String&); +#if ENABLE(CACHE_PARTITIONING) + void registerURLSchemeAsCachePartitioned(const String&); +#endif + + VisitedLinkStore& visitedLinkStore() { return m_visitedLinkStore.get(); } + + void setCacheModel(CacheModel); + CacheModel cacheModel() const { return m_configuration->cacheModel(); } + + void setDefaultRequestTimeoutInterval(double); + + void startMemorySampler(const double interval); + void stopMemorySampler(); + +#if USE(SOUP) + void setInitialHTTPCookieAcceptPolicy(HTTPCookieAcceptPolicy policy) { m_initialHTTPCookieAcceptPolicy = policy; } +#endif + void setEnhancedAccessibility(bool); + + // Downloads. + DownloadProxy* createDownloadProxy(const WebCore::ResourceRequest&); + API::DownloadClient& downloadClient() { return *m_downloadClient; } + + API::LegacyContextHistoryClient& historyClient() { return *m_historyClient; } + WebContextClient& client() { return m_client; } + + WebIconDatabase* iconDatabase() const { return m_iconDatabase.get(); } + + struct Statistics { + unsigned wkViewCount; + unsigned wkPageCount; + unsigned wkFrameCount; + }; + static Statistics& statistics(); + + void setIconDatabasePath(const String&); + String iconDatabasePath() const; + void setCookieStorageDirectory(const String& dir) { m_overrideCookieStorageDirectory = dir; } + + void useTestingNetworkSession(); + bool isUsingTestingNetworkSession() const { return m_shouldUseTestingNetworkSession; } + + void clearCachedCredentials(); + void terminateDatabaseProcess(); + + void allowSpecificHTTPSCertificateForHost(const WebCertificateInfo*, const String& host); + + WebProcessProxy& createNewWebProcessRespectingProcessCountLimit(); // Will return an existing one if limit is met. + void warmInitialProcess(); + + bool shouldTerminate(WebProcessProxy*); + + void disableProcessTermination() { m_processTerminationEnabled = false; } + void enableProcessTermination(); + + void updateAutomationCapabilities() const; + void setAutomationSession(RefPtr&&); + + // Defaults to false. + void setHTTPPipeliningEnabled(bool); + bool httpPipeliningEnabled() const; + + void getStatistics(uint32_t statisticsMask, std::function); + + void garbageCollectJavaScriptObjects(); + void setJavaScriptGarbageCollectorTimerEnabled(bool flag); + +#if PLATFORM(COCOA) + static bool omitPDFSupport(); +#endif + + void fullKeyboardAccessModeChanged(bool fullKeyboardAccessEnabled); + + void textCheckerStateChanged(); + + PassRefPtr plugInAutoStartOriginHashes() const; + void setPlugInAutoStartOriginHashes(API::Dictionary&); + void setPlugInAutoStartOrigins(API::Array&); + void setPlugInAutoStartOriginsFilteringOutEntriesAddedAfterTime(API::Dictionary&, double time); + + // Network Process Management + NetworkProcessProxy& ensureNetworkProcess(); + NetworkProcessProxy* networkProcess() { return m_networkProcess.get(); } + void networkProcessCrashed(NetworkProcessProxy*); + + void getNetworkProcessConnection(PassRefPtr); + +#if ENABLE(DATABASE_PROCESS) + void ensureDatabaseProcess(); + DatabaseProcessProxy* databaseProcess() { return m_databaseProcess.get(); } + void getDatabaseProcessConnection(PassRefPtr); + void databaseProcessCrashed(DatabaseProcessProxy*); +#endif + +#if PLATFORM(COCOA) + bool processSuppressionEnabled() const; +#endif + + void windowServerConnectionStateChanged(); + + static void willStartUsingPrivateBrowsing(); + static void willStopUsingPrivateBrowsing(); + +#if USE(SOUP) + void setIgnoreTLSErrors(bool); + bool ignoreTLSErrors() const { return m_ignoreTLSErrors; } +#endif + + static void setInvalidMessageCallback(void (*)(WKStringRef)); + static void didReceiveInvalidMessage(const IPC::StringReference& messageReceiverName, const IPC::StringReference& messageName); + + void processDidCachePage(WebProcessProxy*); + + bool isURLKnownHSTSHost(const String& urlString, bool privateBrowsingEnabled) const; + void resetHSTSHosts(); + void resetHSTSHostsAddedAfterDate(double startDateIntervalSince1970); + + void registerSchemeForCustomProtocol(const String&); + void unregisterSchemeForCustomProtocol(const String&); + + static HashSet& globalURLSchemesWithCustomProtocolHandlers(); + static void registerGlobalURLSchemeAsHavingCustomProtocolHandlers(const String&); + static void unregisterGlobalURLSchemeAsHavingCustomProtocolHandlers(const String&); + +#if PLATFORM(COCOA) + void updateProcessSuppressionState(); + + NSMutableDictionary *ensureBundleParameters(); + NSMutableDictionary *bundleParameters() { return m_bundleParameters.get(); } +#else + void updateProcessSuppressionState() const { } +#endif + + void setMemoryCacheDisabled(bool); + void setFontWhitelist(API::Array*); + + UserObservablePageToken userObservablePageCount() + { + return m_userObservablePageCounter.token(); + } + + ProcessSuppressionDisabledToken processSuppressionDisabledForPageCount() + { + return m_processSuppressionDisabledForPageCounter.token(); + } + + // FIXME: Move these to API::WebsiteDataStore. + static String legacyPlatformDefaultLocalStorageDirectory(); + static String legacyPlatformDefaultIndexedDBDatabaseDirectory(); + static String legacyPlatformDefaultWebSQLDatabaseDirectory(); + static String legacyPlatformDefaultMediaKeysStorageDirectory(); + static String legacyPlatformDefaultApplicationCacheDirectory(); + static String legacyPlatformDefaultNetworkCacheDirectory(); + static bool isNetworkCacheEnabled(); + +private: + void platformInitialize(); + + void platformInitializeWebProcess(WebProcessCreationParameters&); + void platformInvalidateContext(); + + WebProcessProxy& createNewWebProcess(); + + void requestWebContentStatistics(StatisticsRequest*); + void requestNetworkingStatistics(StatisticsRequest*); + + void platformInitializeNetworkProcess(NetworkProcessCreationParameters&); + + void handleMessage(IPC::Connection&, const String& messageName, const UserData& messageBody); + void handleSynchronousMessage(IPC::Connection&, const String& messageName, const UserData& messageBody, UserData& returnUserData); + + void didGetStatistics(const StatisticsData&, uint64_t callbackID); + + // IPC::MessageReceiver. + // Implemented in generated WebProcessPoolMessageReceiver.cpp + virtual void didReceiveMessage(IPC::Connection&, IPC::MessageDecoder&) override; + virtual void didReceiveSyncMessage(IPC::Connection&, IPC::MessageDecoder&, std::unique_ptr&) override; + + static void languageChanged(void* context); + void languageChanged(); + + String platformDefaultIconDatabasePath() const; + +#if PLATFORM(IOS) || ENABLE(SECCOMP_FILTERS) + String cookieStorageDirectory() const; +#endif + +#if PLATFORM(IOS) + String parentBundleDirectory() const; + String networkingCachesDirectory() const; + String webContentCachesDirectory() const; + String containerTemporaryDirectory() const; +#endif + +#if PLATFORM(COCOA) + void registerNotificationObservers(); + void unregisterNotificationObservers(); +#endif + + void addPlugInAutoStartOriginHash(const String& pageOrigin, unsigned plugInOriginHash, WebCore::SessionID); + void plugInDidReceiveUserInteraction(unsigned plugInOriginHash, WebCore::SessionID); + + void setAnyPageGroupMightHavePrivateBrowsingEnabled(bool); + +#if ENABLE(NETSCAPE_PLUGIN_API) + // PluginInfoStoreClient: + virtual void pluginInfoStoreDidLoadPlugins(PluginInfoStore*) override; +#endif + + Ref m_configuration; + + IPC::MessageReceiverMap m_messageReceiverMap; + + Vector> m_processes; + bool m_haveInitialEmptyProcess; + + WebProcessProxy* m_processWithPageCache; + + Ref m_defaultPageGroup; + + RefPtr m_injectedBundleInitializationUserData; + WebContextInjectedBundleClient m_injectedBundleClient; + + WebContextClient m_client; + WebContextConnectionClient m_connectionClient; + std::unique_ptr m_automationClient; + std::unique_ptr m_downloadClient; + std::unique_ptr m_historyClient; + + RefPtr m_automationSession; + +#if ENABLE(NETSCAPE_PLUGIN_API) + PluginInfoStore m_pluginInfoStore; +#endif + Ref m_visitedLinkStore; + bool m_visitedLinksPopulated; + + PlugInAutoStartProvider m_plugInAutoStartProvider; + + HashSet m_schemesToRegisterAsEmptyDocument; + HashSet m_schemesToRegisterAsSecure; + HashSet m_schemesToRegisterAsBypassingContentSecurityPolicy; + HashSet m_schemesToSetDomainRelaxationForbiddenFor; + HashSet m_schemesToRegisterAsLocal; + HashSet m_schemesToRegisterAsNoAccess; + HashSet m_schemesToRegisterAsDisplayIsolated; + HashSet m_schemesToRegisterAsCORSEnabled; + HashSet m_schemesToRegisterAsAlwaysRevalidated; +#if ENABLE(CACHE_PARTITIONING) + HashSet m_schemesToRegisterAsCachePartitioned; +#endif + + bool m_alwaysUsesComplexTextCodePath; + bool m_shouldUseFontSmoothing; + + Vector m_fontWhitelist; + + // Messages that were posted before any pages were created. + // The client should use initialization messages instead, so that a restarted process would get the same state. + Vector>> m_messagesToInjectedBundlePostedToEmptyContext; + + bool m_memorySamplerEnabled; + double m_memorySamplerInterval; + + RefPtr m_iconDatabase; + + const RefPtr m_websiteDataStore; + + typedef HashMap, PtrHash> WebContextSupplementMap; + WebContextSupplementMap m_supplements; + +#if USE(SOUP) + HTTPCookieAcceptPolicy m_initialHTTPCookieAcceptPolicy; +#endif + +#if PLATFORM(MAC) + RetainPtr m_enhancedAccessibilityObserver; + RetainPtr m_automaticTextReplacementNotificationObserver; + RetainPtr m_automaticSpellingCorrectionNotificationObserver; + RetainPtr m_automaticQuoteSubstitutionNotificationObserver; + RetainPtr m_automaticDashSubstitutionNotificationObserver; +#endif + + String m_overrideIconDatabasePath; + String m_overrideCookieStorageDirectory; + + bool m_shouldUseTestingNetworkSession; + + bool m_processTerminationEnabled; + + bool m_canHandleHTTPSServerTrustEvaluation; + bool m_didNetworkProcessCrash; + RefPtr m_networkProcess; + +#if ENABLE(DATABASE_PROCESS) + RefPtr m_databaseProcess; +#endif + + HashMap> m_dictionaryCallbacks; + HashMap> m_statisticsRequests; + +#if USE(SOUP) + bool m_ignoreTLSErrors { true }; +#endif + + bool m_memoryCacheDisabled; + + RefCounter m_userObservablePageCounter; + RefCounter m_processSuppressionDisabledForPageCounter; + +#if PLATFORM(COCOA) + RetainPtr m_bundleParameters; + ProcessSuppressionDisabledToken m_pluginProcessManagerProcessSuppressionDisabledToken; +#endif + +#if ENABLE(CONTENT_EXTENSIONS) + HashMap m_encodedContentExtensions; +#endif + +#if ENABLE(NETSCAPE_PLUGIN_API) + HashMap>> m_pluginLoadClientPolicies; +#endif +}; + +template +void WebProcessPool::sendToNetworkingProcess(T&& message) +{ + if (m_networkProcess && m_networkProcess->canSendMessage()) + m_networkProcess->send(std::forward(message), 0); +} + +template +void WebProcessPool::sendToNetworkingProcessRelaunchingIfNecessary(T&& message) +{ + ensureNetworkProcess(); + m_networkProcess->send(std::forward(message), 0); +} + +template +void WebProcessPool::sendToDatabaseProcessRelaunchingIfNecessary(T&& message) +{ +#if ENABLE(DATABASE_PROCESS) + ensureDatabaseProcess(); + m_databaseProcess->send(std::forward(message), 0); +#else + sendToAllProcessesRelaunchingThemIfNecessary(std::forward(message)); +#endif +} + +template +void WebProcessPool::sendToAllProcesses(const T& message) +{ + size_t processCount = m_processes.size(); + for (size_t i = 0; i < processCount; ++i) { + WebProcessProxy* process = m_processes[i].get(); + if (process->canSendMessage()) + process->send(T(message), 0); + } +} + +template +void WebProcessPool::sendToAllProcessesRelaunchingThemIfNecessary(const T& message) +{ + // FIXME (Multi-WebProcess): WebProcessPool doesn't track processes that have exited, so it cannot relaunch these. Perhaps this functionality won't be needed in this mode. + sendToAllProcesses(message); +} + +template +void WebProcessPool::sendToOneProcess(T&& message) +{ + bool messageSent = false; + size_t processCount = m_processes.size(); + for (size_t i = 0; i < processCount; ++i) { + WebProcessProxy* process = m_processes[i].get(); + if (process->canSendMessage()) { + process->send(std::forward(message), 0); + messageSent = true; + break; + } + } + + if (!messageSent) { + warmInitialProcess(); + RefPtr process = m_processes.last(); + if (process->canSendMessage()) + process->send(std::forward(message), 0); + } +} + +} // namespace WebKit + +#endif // UIProcessPool_h -- cgit v1.2.1