Access MemoryPressureHandler global instance via a singleton() static member function
[WebKit-https.git] / Source / WebKit2 / NetworkProcess / NetworkProcess.cpp
1 /*
2  * Copyright (C) 2012 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "NetworkProcess.h"
28
29 #if ENABLE(NETWORK_PROCESS)
30
31 #include "ArgumentCoders.h"
32 #include "Attachment.h"
33 #include "AuthenticationManager.h"
34 #include "CustomProtocolManager.h"
35 #include "Logging.h"
36 #include "NetworkConnectionToWebProcess.h"
37 #include "NetworkProcessCreationParameters.h"
38 #include "NetworkProcessPlatformStrategies.h"
39 #include "NetworkProcessProxyMessages.h"
40 #include "NetworkResourceLoader.h"
41 #include "RemoteNetworkingContext.h"
42 #include "SessionTracker.h"
43 #include "StatisticsData.h"
44 #include "WebCookieManager.h"
45 #include "WebProcessPoolMessages.h"
46 #include "WebsiteDataTypes.h"
47 #include <WebCore/Logging.h>
48 #include <WebCore/MemoryPressureHandler.h>
49 #include <WebCore/PlatformCookieJar.h>
50 #include <WebCore/ResourceRequest.h>
51 #include <WebCore/SessionID.h>
52 #include <wtf/RunLoop.h>
53 #include <wtf/text/CString.h>
54
55 #if ENABLE(SEC_ITEM_SHIM)
56 #include "SecItemShim.h"
57 #endif
58
59 using namespace WebCore;
60
61 namespace WebKit {
62
63 NetworkProcess& NetworkProcess::singleton()
64 {
65     static NeverDestroyed<NetworkProcess> networkProcess;
66     return networkProcess;
67 }
68
69 NetworkProcess::NetworkProcess()
70     : m_hasSetCacheModel(false)
71     , m_cacheModel(CacheModelDocumentViewer)
72     , m_diskCacheIsDisabledForTesting(false)
73     , m_canHandleHTTPSServerTrustEvaluation(true)
74 #if PLATFORM(COCOA)
75     , m_clearCacheDispatchGroup(0)
76 #endif
77 {
78     NetworkProcessPlatformStrategies::initialize();
79
80     addSupplement<AuthenticationManager>();
81     addSupplement<WebCookieManager>();
82     addSupplement<CustomProtocolManager>();
83 }
84
85 NetworkProcess::~NetworkProcess()
86 {
87 }
88
89 AuthenticationManager& NetworkProcess::authenticationManager()
90 {
91     return *supplement<AuthenticationManager>();
92 }
93
94 DownloadManager& NetworkProcess::downloadManager()
95 {
96     static NeverDestroyed<DownloadManager> downloadManager(this);
97     return downloadManager;
98 }
99
100 void NetworkProcess::removeNetworkConnectionToWebProcess(NetworkConnectionToWebProcess* connection)
101 {
102     size_t vectorIndex = m_webProcessConnections.find(connection);
103     ASSERT(vectorIndex != notFound);
104
105     m_webProcessConnections.remove(vectorIndex);
106 }
107
108 bool NetworkProcess::shouldTerminate()
109 {
110     // Network process keeps session cookies and credentials, so it should never terminate (as long as UI process connection is alive).
111     return false;
112 }
113
114 void NetworkProcess::didReceiveMessage(IPC::Connection& connection, IPC::MessageDecoder& decoder)
115 {
116     if (messageReceiverMap().dispatchMessage(connection, decoder))
117         return;
118
119     didReceiveNetworkProcessMessage(connection, decoder);
120 }
121
122 void NetworkProcess::didReceiveSyncMessage(IPC::Connection& connection, IPC::MessageDecoder& decoder, std::unique_ptr<IPC::MessageEncoder>& replyEncoder)
123 {
124     messageReceiverMap().dispatchSyncMessage(connection, decoder, replyEncoder);
125 }
126
127 void NetworkProcess::didClose(IPC::Connection&)
128 {
129     // The UIProcess just exited.
130     RunLoop::current().stop();
131 }
132
133 void NetworkProcess::didReceiveInvalidMessage(IPC::Connection&, IPC::StringReference, IPC::StringReference)
134 {
135     RunLoop::current().stop();
136 }
137
138 void NetworkProcess::didCreateDownload()
139 {
140     disableTermination();
141 }
142
143 void NetworkProcess::didDestroyDownload()
144 {
145     enableTermination();
146 }
147
148 IPC::Connection* NetworkProcess::downloadProxyConnection()
149 {
150     return parentProcessConnection();
151 }
152
153 AuthenticationManager& NetworkProcess::downloadsAuthenticationManager()
154 {
155     return authenticationManager();
156 }
157
158 void NetworkProcess::initializeNetworkProcess(const NetworkProcessCreationParameters& parameters)
159 {
160     platformInitializeNetworkProcess(parameters);
161
162     WTF::setCurrentThreadIsUserInitiated();
163
164     auto& memoryPressureHandler = MemoryPressureHandler::singleton();
165     memoryPressureHandler.setLowMemoryHandler([this] (bool critical) {
166         platformLowMemoryHandler(critical);
167         WTF::releaseFastMallocFreeMemory();
168     });
169     memoryPressureHandler.install();
170
171     m_diskCacheIsDisabledForTesting = parameters.shouldUseTestingNetworkSession;
172     setCacheModel(static_cast<uint32_t>(parameters.cacheModel));
173
174     setCanHandleHTTPSServerTrustEvaluation(parameters.canHandleHTTPSServerTrustEvaluation);
175
176 #if PLATFORM(MAC) || USE(CFNETWORK)
177     SessionTracker::setIdentifierBase(parameters.uiProcessBundleIdentifier);
178 #endif
179
180     // FIXME: instead of handling this here, a message should be sent later (scales to multiple sessions)
181     if (parameters.privateBrowsingEnabled)
182         RemoteNetworkingContext::ensurePrivateBrowsingSession(SessionID::legacyPrivateSessionID());
183
184     if (parameters.shouldUseTestingNetworkSession)
185         NetworkStorageSession::switchToNewTestingSession();
186
187     NetworkProcessSupplementMap::const_iterator it = m_supplements.begin();
188     NetworkProcessSupplementMap::const_iterator end = m_supplements.end();
189     for (; it != end; ++it)
190         it->value->initialize(parameters);
191 }
192
193 void NetworkProcess::initializeConnection(IPC::Connection* connection)
194 {
195     ChildProcess::initializeConnection(connection);
196
197 #if ENABLE(SEC_ITEM_SHIM)
198     SecItemShim::singleton().initializeConnection(connection);
199 #endif
200
201     NetworkProcessSupplementMap::const_iterator it = m_supplements.begin();
202     NetworkProcessSupplementMap::const_iterator end = m_supplements.end();
203     for (; it != end; ++it)
204         it->value->initializeConnection(connection);
205 }
206
207 void NetworkProcess::createNetworkConnectionToWebProcess()
208 {
209 #if OS(DARWIN)
210     // Create the listening port.
211     mach_port_t listeningPort;
212     mach_port_allocate(mach_task_self(), MACH_PORT_RIGHT_RECEIVE, &listeningPort);
213
214     // Create a listening connection.
215     RefPtr<NetworkConnectionToWebProcess> connection = NetworkConnectionToWebProcess::create(IPC::Connection::Identifier(listeningPort));
216     m_webProcessConnections.append(connection.release());
217
218     IPC::Attachment clientPort(listeningPort, MACH_MSG_TYPE_MAKE_SEND);
219     parentProcessConnection()->send(Messages::NetworkProcessProxy::DidCreateNetworkConnectionToWebProcess(clientPort), 0);
220 #elif USE(UNIX_DOMAIN_SOCKETS)
221     IPC::Connection::SocketPair socketPair = IPC::Connection::createPlatformConnection();
222
223     RefPtr<NetworkConnectionToWebProcess> connection = NetworkConnectionToWebProcess::create(socketPair.server);
224     m_webProcessConnections.append(connection.release());
225
226     IPC::Attachment clientSocket(socketPair.client);
227     parentProcessConnection()->send(Messages::NetworkProcessProxy::DidCreateNetworkConnectionToWebProcess(clientSocket), 0);
228 #else
229     notImplemented();
230 #endif
231 }
232
233 void NetworkProcess::ensurePrivateBrowsingSession(SessionID sessionID)
234 {
235     RemoteNetworkingContext::ensurePrivateBrowsingSession(sessionID);
236 }
237
238 void NetworkProcess::destroyPrivateBrowsingSession(SessionID sessionID)
239 {
240     SessionTracker::destroySession(sessionID);
241 }
242
243 void NetworkProcess::deleteWebsiteData(WebCore::SessionID sessionID, uint64_t websiteDataTypes, std::chrono::system_clock::time_point modifiedSince, uint64_t callbackID)
244 {
245     if (websiteDataTypes & WebsiteDataTypeCookies) {
246         if (auto* networkStorageSession = SessionTracker::session(sessionID))
247             deleteAllCookiesModifiedSince(*networkStorageSession, modifiedSince);
248     }
249
250     auto completionHandler = [this, callbackID] {
251         parentProcessConnection()->send(Messages::NetworkProcessProxy::DidDeleteWebsiteData(callbackID), 0);
252     };
253
254     if ((websiteDataTypes & WebsiteDataTypeDiskCache) & !sessionID.isEphemeral()) {
255         clearDiskCache(modifiedSince, WTF::move(completionHandler));
256         return;
257     }
258
259     completionHandler();
260 }
261
262 void NetworkProcess::downloadRequest(uint64_t downloadID, const ResourceRequest& request)
263 {
264     downloadManager().startDownload(downloadID, request);
265 }
266
267 void NetworkProcess::resumeDownload(uint64_t downloadID, const IPC::DataReference& resumeData, const String& path, const WebKit::SandboxExtension::Handle& sandboxExtensionHandle)
268 {
269     downloadManager().resumeDownload(downloadID, resumeData, path, sandboxExtensionHandle);
270 }
271
272 void NetworkProcess::cancelDownload(uint64_t downloadID)
273 {
274     downloadManager().cancelDownload(downloadID);
275 }
276
277 void NetworkProcess::setCacheModel(uint32_t cm)
278 {
279     CacheModel cacheModel = static_cast<CacheModel>(cm);
280
281     if (!m_hasSetCacheModel || cacheModel != m_cacheModel) {
282         m_hasSetCacheModel = true;
283         m_cacheModel = cacheModel;
284         platformSetCacheModel(cacheModel);
285     }
286 }
287
288 void NetworkProcess::setCanHandleHTTPSServerTrustEvaluation(bool value)
289 {
290     m_canHandleHTTPSServerTrustEvaluation = value;
291 }
292
293 void NetworkProcess::getNetworkProcessStatistics(uint64_t callbackID)
294 {
295     NetworkResourceLoadScheduler& scheduler = NetworkProcess::singleton().networkResourceLoadScheduler();
296
297     StatisticsData data;
298
299     auto& networkProcess = NetworkProcess::singleton();
300     data.statisticsNumbers.set("LoadsPendingCount", scheduler.loadsPendingCount());
301     data.statisticsNumbers.set("LoadsActiveCount", scheduler.loadsActiveCount());
302     data.statisticsNumbers.set("DownloadsActiveCount", networkProcess.downloadManager().activeDownloadCount());
303     data.statisticsNumbers.set("OutstandingAuthenticationChallengesCount", networkProcess.authenticationManager().outstandingAuthenticationChallengeCount());
304
305     parentProcessConnection()->send(Messages::WebProcessPool::DidGetStatistics(data, callbackID), 0);
306 }
307
308 void NetworkProcess::logDiagnosticMessage(uint64_t webPageID, const String& message, const String& description)
309 {
310     parentProcessConnection()->send(Messages::NetworkProcessProxy::LogDiagnosticMessage(webPageID, message, description), 0);
311 }
312
313 void NetworkProcess::logDiagnosticMessageWithResult(uint64_t webPageID, const String& message, const String& description, WebCore::DiagnosticLoggingResultType result)
314 {
315     parentProcessConnection()->send(Messages::NetworkProcessProxy::LogDiagnosticMessageWithResult(webPageID, message, description, result), 0);
316 }
317
318 void NetworkProcess::logDiagnosticMessageWithValue(uint64_t webPageID, const String& message, const String& description, const String& value)
319 {
320     parentProcessConnection()->send(Messages::NetworkProcessProxy::LogDiagnosticMessageWithValue(webPageID, message, description, value), 0);
321 }
322
323 void NetworkProcess::terminate()
324 {
325     platformTerminate();
326     ChildProcess::terminate();
327 }
328
329 #if !PLATFORM(COCOA)
330 void NetworkProcess::initializeProcess(const ChildProcessInitializationParameters&)
331 {
332 }
333
334 void NetworkProcess::initializeProcessName(const ChildProcessInitializationParameters&)
335 {
336 }
337
338 void NetworkProcess::initializeSandbox(const ChildProcessInitializationParameters&, SandboxInitializationParameters&)
339 {
340 }
341
342 void NetworkProcess::platformLowMemoryHandler(bool)
343 {
344 }
345 #endif
346
347 } // namespace WebKit
348
349 #endif // ENABLE(NETWORK_PROCESS)