Drop NetworkCacheStatistics code
[WebKit-https.git] / Source / WebKit / UIProcess / Cocoa / WebProcessPoolCocoa.mm
1 /*
2  * Copyright (C) 2010-2019 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 #import "config.h"
27 #import "WebProcessPool.h"
28
29 #import "AccessibilitySupportSPI.h"
30 #import "CookieStorageUtilsCF.h"
31 #import "LegacyCustomProtocolManagerClient.h"
32 #import "NetworkProcessCreationParameters.h"
33 #import "NetworkProcessMessages.h"
34 #import "NetworkProcessProxy.h"
35 #import "PluginProcessManager.h"
36 #import "SandboxUtilities.h"
37 #import "TextChecker.h"
38 #import "VersionChecks.h"
39 #import "WKBrowsingContextControllerInternal.h"
40 #import "WebMemoryPressureHandler.h"
41 #import "WebPageGroup.h"
42 #import "WebPreferencesKeys.h"
43 #import "WebProcessCreationParameters.h"
44 #import "WebProcessMessages.h"
45 #import "WindowServerConnection.h"
46 #import <WebCore/Color.h>
47 #import <WebCore/NetworkStorageSession.h>
48 #import <WebCore/NotImplemented.h>
49 #import <WebCore/PlatformPasteboard.h>
50 #import <WebCore/RuntimeApplicationChecks.h>
51 #import <WebCore/SharedBuffer.h>
52 #import <pal/spi/cf/CFNetworkSPI.h>
53 #import <pal/spi/cocoa/NSKeyedArchiverSPI.h>
54 #import <sys/param.h>
55 #import <wtf/FileSystem.h>
56 #import <wtf/ProcessPrivilege.h>
57 #import <wtf/SoftLinking.h>
58 #import <wtf/cocoa/Entitlements.h>
59 #import <wtf/spi/darwin/dyldSPI.h>
60
61 #if PLATFORM(MAC)
62 #import <QuartzCore/CARemoteLayerServer.h>
63 #else
64 #import "UIKitSPI.h"
65 #endif
66
67 #if PLATFORM(IOS)
68 #import "UIKitSPI.h"
69 #import <wtf/SoftLinking.h>
70 #endif
71
72 NSString *WebServiceWorkerRegistrationDirectoryDefaultsKey = @"WebServiceWorkerRegistrationDirectory";
73 NSString *WebKitLocalCacheDefaultsKey = @"WebKitLocalCache";
74 NSString *WebKitJSCJITEnabledDefaultsKey = @"WebKitJSCJITEnabledDefaultsKey";
75 NSString *WebKitJSCFTLJITEnabledDefaultsKey = @"WebKitJSCFTLJITEnabledDefaultsKey";
76
77 #if !PLATFORM(IOS_FAMILY)
78 static NSString *WebKitApplicationDidChangeAccessibilityEnhancedUserInterfaceNotification = @"NSApplicationDidChangeAccessibilityEnhancedUserInterfaceNotification";
79 #endif
80
81 static NSString * const WebKitSuppressMemoryPressureHandlerDefaultsKey = @"WebKitSuppressMemoryPressureHandler";
82
83 #if ENABLE(RESOURCE_LOAD_STATISTICS) && !RELEASE_LOG_DISABLED
84 static NSString * const WebKitLogCookieInformationDefaultsKey = @"WebKitLogCookieInformation";
85 #endif
86
87 #if PLATFORM(IOS)
88 SOFT_LINK_PRIVATE_FRAMEWORK(BackBoardServices)
89 SOFT_LINK(BackBoardServices, BKSDisplayBrightnessGetCurrent, float, (), ());
90 #endif
91
92 namespace WebKit {
93 using namespace WebCore;
94
95 static void registerUserDefaultsIfNeeded()
96 {
97     static bool didRegister;
98     if (didRegister)
99         return;
100
101     didRegister = true;
102     NSMutableDictionary *registrationDictionary = [NSMutableDictionary dictionary];
103     
104     [registrationDictionary setObject:@YES forKey:WebKitJSCJITEnabledDefaultsKey];
105     [registrationDictionary setObject:@YES forKey:WebKitJSCFTLJITEnabledDefaultsKey];
106
107     [[NSUserDefaults standardUserDefaults] registerDefaults:registrationDictionary];
108 }
109
110 void WebProcessPool::updateProcessSuppressionState()
111 {
112     if (m_networkProcess)
113         m_networkProcess->setProcessSuppressionEnabled(processSuppressionEnabled());
114
115 #if ENABLE(NETSCAPE_PLUGIN_API)
116     if (!m_processSuppressionDisabledForPageCounter.value())
117         m_pluginProcessManagerProcessSuppressionDisabledToken = nullptr;
118     else if (!m_pluginProcessManagerProcessSuppressionDisabledToken)
119         m_pluginProcessManagerProcessSuppressionDisabledToken = PluginProcessManager::singleton().processSuppressionDisabledToken();
120 #endif
121 }
122
123 NSMutableDictionary *WebProcessPool::ensureBundleParameters()
124 {
125     if (!m_bundleParameters)
126         m_bundleParameters = adoptNS([[NSMutableDictionary alloc] init]);
127
128     return m_bundleParameters.get();
129 }
130
131 void WebProcessPool::platformInitialize()
132 {
133     registerUserDefaultsIfNeeded();
134     registerNotificationObservers();
135
136     // FIXME: This should be able to share code with WebCore's MemoryPressureHandler (and be platform independent).
137     // Right now it cannot because WebKit1 and WebKit2 need to be able to coexist in the UI process,
138     // and you can only have one WebCore::MemoryPressureHandler.
139
140     if (![[NSUserDefaults standardUserDefaults] boolForKey:@"WebKitSuppressMemoryPressureHandler"])
141         installMemoryPressureHandler();
142
143     setLegacyCustomProtocolManagerClient(std::make_unique<LegacyCustomProtocolManagerClient>());
144 }
145
146 #if PLATFORM(IOS_FAMILY)
147 String WebProcessPool::cookieStorageDirectory() const
148 {
149     String path = pathForProcessContainer();
150     if (path.isEmpty())
151         path = NSHomeDirectory();
152
153     path = path + "/Library/Cookies";
154     path = stringByResolvingSymlinksInPath(path);
155     return path;
156 }
157 #endif
158
159 void WebProcessPool::platformResolvePathsForSandboxExtensions()
160 {
161     m_resolvedPaths.uiProcessBundleResourcePath = resolvePathForSandboxExtension([[NSBundle mainBundle] resourcePath]);
162
163 #if PLATFORM(IOS_FAMILY)
164     m_resolvedPaths.cookieStorageDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(cookieStorageDirectory());
165     m_resolvedPaths.containerCachesDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(webContentCachesDirectory());
166     m_resolvedPaths.containerTemporaryDirectory = resolveAndCreateReadWriteDirectoryForSandboxExtension(containerTemporaryDirectory());
167 #endif
168 }
169
170 void WebProcessPool::platformInitializeWebProcess(WebProcessCreationParameters& parameters)
171 {
172 #if PLATFORM(MAC)
173     ALLOW_DEPRECATED_DECLARATIONS_BEGIN
174     ASSERT(hasProcessPrivilege(ProcessPrivilege::CanCommunicateWithWindowServer));
175     parameters.accessibilityEnhancedUserInterfaceEnabled = [[NSApp accessibilityAttributeValue:@"AXEnhancedUserInterface"] boolValue];
176     ALLOW_DEPRECATED_DECLARATIONS_END
177 #else
178     parameters.accessibilityEnhancedUserInterfaceEnabled = false;
179 #endif
180
181     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
182
183     parameters.shouldEnableJIT = [defaults boolForKey:WebKitJSCJITEnabledDefaultsKey];
184     parameters.shouldEnableFTLJIT = [defaults boolForKey:WebKitJSCFTLJITEnabledDefaultsKey];
185     parameters.shouldEnableMemoryPressureReliefLogging = [defaults boolForKey:@"LogMemoryJetsamDetails"];
186     parameters.shouldSuppressMemoryPressureHandler = [defaults boolForKey:WebKitSuppressMemoryPressureHandlerDefaultsKey];
187
188 #if HAVE(HOSTED_CORE_ANIMATION)
189 #if !PLATFORM(IOS_FAMILY)
190     parameters.acceleratedCompositingPort = MachSendRight::create([CARemoteLayerServer sharedServer].serverPort);
191 #endif
192 #endif
193
194     // FIXME: This should really be configurable; we shouldn't just blindly allow read access to the UI process bundle.
195     parameters.uiProcessBundleResourcePath = m_resolvedPaths.uiProcessBundleResourcePath;
196     SandboxExtension::createHandleWithoutResolvingPath(parameters.uiProcessBundleResourcePath, SandboxExtension::Type::ReadOnly, parameters.uiProcessBundleResourcePathExtensionHandle);
197
198     parameters.uiProcessBundleIdentifier = String([[NSBundle mainBundle] bundleIdentifier]);
199     parameters.uiProcessSDKVersion = dyld_get_program_sdk_version();
200
201 #if PLATFORM(IOS_FAMILY)
202     if (!m_resolvedPaths.cookieStorageDirectory.isEmpty())
203         SandboxExtension::createHandleWithoutResolvingPath(m_resolvedPaths.cookieStorageDirectory, SandboxExtension::Type::ReadWrite, parameters.cookieStorageDirectoryExtensionHandle);
204
205     if (!m_resolvedPaths.containerCachesDirectory.isEmpty())
206         SandboxExtension::createHandleWithoutResolvingPath(m_resolvedPaths.containerCachesDirectory, SandboxExtension::Type::ReadWrite, parameters.containerCachesDirectoryExtensionHandle);
207
208     if (!m_resolvedPaths.containerTemporaryDirectory.isEmpty())
209         SandboxExtension::createHandleWithoutResolvingPath(m_resolvedPaths.containerTemporaryDirectory, SandboxExtension::Type::ReadWrite, parameters.containerTemporaryDirectoryExtensionHandle);
210 #endif
211
212     parameters.fontWhitelist = m_fontWhitelist;
213
214     if (m_bundleParameters) {
215         auto keyedArchiver = secureArchiver();
216
217         @try {
218             [keyedArchiver encodeObject:m_bundleParameters.get() forKey:@"parameters"];
219             [keyedArchiver finishEncoding];
220         } @catch (NSException *exception) {
221             LOG_ERROR("Failed to encode bundle parameters: %@", exception);
222         }
223
224         auto data = keyedArchiver.get().encodedData;
225
226         parameters.bundleParameterData = API::Data::createWithoutCopying(WTFMove(data));
227     }
228     parameters.networkATSContext = adoptCF(_CFNetworkCopyATSContext());
229
230 #if ENABLE(MEDIA_STREAM)
231     // Allow microphone access if either preference is set because WebRTC requires microphone access.
232     bool mediaDevicesEnabled = m_defaultPageGroup->preferences().mediaDevicesEnabled();
233     bool webRTCEnabled = m_defaultPageGroup->preferences().peerConnectionEnabled();
234     if ([defaults objectForKey:@"ExperimentalPeerConnectionEnabled"])
235         webRTCEnabled = [defaults boolForKey:@"ExperimentalPeerConnectionEnabled"];
236
237     bool isSafari = false;
238 #if PLATFORM(IOS_FAMILY)
239     if (WebCore::IOSApplication::isMobileSafari())
240         isSafari = true;
241 #elif PLATFORM(MAC)
242     if (WebCore::MacApplication::isSafari())
243         isSafari = true;
244 #endif
245
246 #if !LOG_DISABLED || !RELEASE_LOG_DISABLED
247     parameters.webCoreLoggingChannels = [[NSUserDefaults standardUserDefaults] stringForKey:@"WebCoreLogging"];
248     parameters.webKitLoggingChannels = [[NSUserDefaults standardUserDefaults] stringForKey:@"WebKit2Logging"];
249 #endif
250
251     // FIXME: Remove this and related parameter when <rdar://problem/29448368> is fixed.
252     if (isSafari && !parameters.shouldCaptureAudioInUIProcess && mediaDevicesEnabled)
253         SandboxExtension::createHandleForGenericExtension("com.apple.webkit.microphone", parameters.audioCaptureExtensionHandle);
254 #endif
255
256 #if ENABLE(RESOURCE_LOAD_STATISTICS) && !RELEASE_LOG_DISABLED
257     parameters.shouldLogUserInteraction = [defaults boolForKey:WebKitLogCookieInformationDefaultsKey];
258 #endif
259     
260 #if PLATFORM(MAC)
261     auto screenProperties = WebCore::collectScreenProperties();
262     parameters.screenProperties = WTFMove(screenProperties);
263     parameters.useOverlayScrollbars = ([NSScroller preferredScrollerStyle] == NSScrollerStyleOverlay);
264 #endif
265 }
266
267 void WebProcessPool::platformInitializeNetworkProcess(NetworkProcessCreationParameters& parameters)
268 {
269     parameters.uiProcessBundleIdentifier = [[NSBundle mainBundle] bundleIdentifier];
270     parameters.uiProcessSDKVersion = dyld_get_program_sdk_version();
271
272     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
273
274     {
275         bool isSafari = false;
276 #if PLATFORM(IOS_FAMILY)
277         isSafari = WebCore::IOSApplication::isMobileSafari();
278 #elif PLATFORM(MAC)
279         isSafari = WebCore::MacApplication::isSafari();
280 #endif
281         if (isSafari) {
282             parameters.defaultDataStoreParameters.networkSessionParameters.httpProxy = URL(URL(), [defaults stringForKey:(NSString *)WebKit2HTTPProxyDefaultsKey]);
283             parameters.defaultDataStoreParameters.networkSessionParameters.httpsProxy = URL(URL(), [defaults stringForKey:(NSString *)WebKit2HTTPSProxyDefaultsKey]);
284         }
285     }
286
287     parameters.networkATSContext = adoptCF(_CFNetworkCopyATSContext());
288
289 #if PLATFORM(IOS_FAMILY)
290     parameters.ctDataConnectionServiceType = m_configuration->ctDataConnectionServiceType();
291 #endif
292
293     parameters.shouldSuppressMemoryPressureHandler = [defaults boolForKey:WebKitSuppressMemoryPressureHandlerDefaultsKey];
294
295 #if PLATFORM(MAC)
296     ASSERT(parameters.uiProcessCookieStorageIdentifier.isEmpty());
297     ASSERT(hasProcessPrivilege(ProcessPrivilege::CanAccessRawCookies));
298     parameters.uiProcessCookieStorageIdentifier = identifyingDataFromCookieStorage([[NSHTTPCookieStorage sharedHTTPCookieStorage] _cookieStorage]);
299 #endif
300
301     parameters.storageAccessAPIEnabled = storageAccessAPIEnabled();
302     parameters.suppressesConnectionTerminationOnSystemChange = m_configuration->suppressesConnectionTerminationOnSystemChange();
303
304 #if ENABLE(PROXIMITY_NETWORKING)
305     parameters.wirelessContextIdentifier = m_configuration->wirelessContextIdentifier();
306 #endif
307
308     parameters.shouldEnableITPDatabase = [defaults boolForKey:[NSString stringWithFormat:@"InternalDebug%@", WebPreferencesKey::isITPDatabaseEnabledKey().createCFString().get()]];
309     parameters.downloadMonitorSpeedMultiplier = m_configuration->downloadMonitorSpeedMultiplier();
310 }
311
312 void WebProcessPool::platformInvalidateContext()
313 {
314     unregisterNotificationObservers();
315 }
316
317 #if PLATFORM(IOS_FAMILY)
318 String WebProcessPool::parentBundleDirectory() const
319 {
320     return [[[NSBundle mainBundle] bundlePath] stringByStandardizingPath];
321 }
322
323 String WebProcessPool::networkingCachesDirectory() const
324 {
325     String path = pathForProcessContainer();
326     if (path.isEmpty())
327         path = NSHomeDirectory();
328
329     path = path + "/Library/Caches/com.apple.WebKit.Networking/";
330     path = stringByResolvingSymlinksInPath(path);
331
332     NSError *error = nil;
333     NSString* nsPath = path;
334     if (![[NSFileManager defaultManager] createDirectoryAtPath:nsPath withIntermediateDirectories:YES attributes:nil error:&error]) {
335         NSLog(@"could not create networking caches directory \"%@\", error %@", nsPath, error);
336         return String();
337     }
338
339     return path;
340 }
341
342 String WebProcessPool::webContentCachesDirectory() const
343 {
344     String path = pathForProcessContainer();
345     if (path.isEmpty())
346         path = NSHomeDirectory();
347
348     path = path + "/Library/Caches/com.apple.WebKit.WebContent/";
349     path = stringByResolvingSymlinksInPath(path);
350
351     NSError *error = nil;
352     NSString* nsPath = path;
353     if (![[NSFileManager defaultManager] createDirectoryAtPath:nsPath withIntermediateDirectories:YES attributes:nil error:&error]) {
354         NSLog(@"could not create web content caches directory \"%@\", error %@", nsPath, error);
355         return String();
356     }
357
358     return path;
359 }
360
361 String WebProcessPool::containerTemporaryDirectory() const
362 {
363     String path = NSTemporaryDirectory();
364     return stringByResolvingSymlinksInPath(path);
365 }
366 #endif
367
368 #if PLATFORM(IOS_FAMILY)
369 void WebProcessPool::setJavaScriptConfigurationFileEnabledFromDefaults()
370 {
371     NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
372
373     setJavaScriptConfigurationFileEnabled([defaults boolForKey:@"WebKitJavaScriptCoreUseConfigFile"]);
374 }
375 #endif
376
377 bool WebProcessPool::omitPDFSupport()
378 {
379     // Since this is a "secret default" we don't bother registering it.
380     return [[NSUserDefaults standardUserDefaults] boolForKey:@"WebKitOmitPDFSupport"];
381 }
382
383 bool WebProcessPool::processSuppressionEnabled() const
384 {
385     return !m_userObservablePageCounter.value() && !m_processSuppressionDisabledForPageCounter.value();
386 }
387
388 bool WebProcessPool::networkProcessHasEntitlementForTesting(const String& entitlement)
389 {
390     return WTF::hasEntitlement(ensureNetworkProcess().connection()->xpcConnection(), entitlement.utf8().data());
391 }
392
393 #if PLATFORM(IOS)
394 float WebProcessPool::displayBrightness()
395 {
396     return BKSDisplayBrightnessGetCurrent();
397 }
398     
399 void WebProcessPool::backlightLevelDidChangeCallback(CFNotificationCenterRef center, void *observer, CFStringRef name, const void *object, CFDictionaryRef userInfo)
400 {
401     WebProcessPool* pool = reinterpret_cast<WebProcessPool*>(observer);
402     pool->sendToAllProcesses(Messages::WebProcess::BacklightLevelDidChange(BKSDisplayBrightnessGetCurrent()));
403 }
404 #endif
405
406 void WebProcessPool::registerNotificationObservers()
407 {
408 #if !PLATFORM(IOS_FAMILY)
409     // Listen for enhanced accessibility changes and propagate them to the WebProcess.
410     m_enhancedAccessibilityObserver = [[NSNotificationCenter defaultCenter] addObserverForName:WebKitApplicationDidChangeAccessibilityEnhancedUserInterfaceNotification object:nil queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *note) {
411         setEnhancedAccessibility([[[note userInfo] objectForKey:@"AXEnhancedUserInterface"] boolValue]);
412     }];
413
414     m_automaticTextReplacementNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSSpellCheckerDidChangeAutomaticTextReplacementNotification object:nil queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *notification) {
415         TextChecker::didChangeAutomaticTextReplacementEnabled();
416         textCheckerStateChanged();
417     }];
418     
419     m_automaticSpellingCorrectionNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSSpellCheckerDidChangeAutomaticSpellingCorrectionNotification object:nil queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *notification) {
420         TextChecker::didChangeAutomaticSpellingCorrectionEnabled();
421         textCheckerStateChanged();
422     }];
423
424     m_automaticQuoteSubstitutionNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSSpellCheckerDidChangeAutomaticQuoteSubstitutionNotification object:nil queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *notification) {
425         TextChecker::didChangeAutomaticQuoteSubstitutionEnabled();
426         textCheckerStateChanged();
427     }];
428
429     m_automaticDashSubstitutionNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSSpellCheckerDidChangeAutomaticDashSubstitutionNotification object:nil queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *notification) {
430         TextChecker::didChangeAutomaticDashSubstitutionEnabled();
431         textCheckerStateChanged();
432     }];
433
434     m_accessibilityDisplayOptionsNotificationObserver = [[NSWorkspace.sharedWorkspace notificationCenter] addObserverForName:NSWorkspaceAccessibilityDisplayOptionsDidChangeNotification object:nil queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *notification) {
435         screenPropertiesStateChanged();
436     }];
437
438 #if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
439     m_scrollerStyleNotificationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSPreferredScrollerStyleDidChangeNotification object:nil queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *notification) {
440         auto scrollbarStyle = [NSScroller preferredScrollerStyle];
441         sendToAllProcesses(Messages::WebProcess::ScrollerStylePreferenceChanged(scrollbarStyle));
442     }];
443 #endif
444
445     m_activationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSApplicationDidBecomeActiveNotification object:NSApp queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *notification) {
446         setApplicationIsActive(true);
447     }];
448
449     m_deactivationObserver = [[NSNotificationCenter defaultCenter] addObserverForName:NSApplicationDidResignActiveNotification object:NSApp queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *notification) {
450         setApplicationIsActive(false);
451     }];
452 #elif PLATFORM(IOS)
453     CFNotificationCenterAddObserver(CFNotificationCenterGetDarwinNotifyCenter(), this, backlightLevelDidChangeCallback, static_cast<CFStringRef>(UIBacklightLevelChangedNotification), nullptr, CFNotificationSuspensionBehaviorCoalesce);
454     m_accessibilityEnabledObserver = [[NSNotificationCenter defaultCenter] addObserverForName:(__bridge id)kAXSApplicationAccessibilityEnabledNotification object:nil queue:[NSOperationQueue currentQueue] usingBlock:^(NSNotification *) {
455         for (size_t i = 0; i < m_processes.size(); ++i)
456             m_processes[i]->unblockAccessibilityServerIfNeeded();
457     }];
458 #endif // !PLATFORM(IOS_FAMILY)
459 }
460
461 void WebProcessPool::unregisterNotificationObservers()
462 {
463 #if !PLATFORM(IOS_FAMILY)
464     [[NSNotificationCenter defaultCenter] removeObserver:m_enhancedAccessibilityObserver.get()];
465     [[NSNotificationCenter defaultCenter] removeObserver:m_automaticTextReplacementNotificationObserver.get()];
466     [[NSNotificationCenter defaultCenter] removeObserver:m_automaticSpellingCorrectionNotificationObserver.get()];
467     [[NSNotificationCenter defaultCenter] removeObserver:m_automaticQuoteSubstitutionNotificationObserver.get()];
468     [[NSNotificationCenter defaultCenter] removeObserver:m_automaticDashSubstitutionNotificationObserver.get()];
469     [[NSWorkspace.sharedWorkspace notificationCenter] removeObserver:m_accessibilityDisplayOptionsNotificationObserver.get()];
470 #if ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
471     [[NSNotificationCenter defaultCenter] removeObserver:m_scrollerStyleNotificationObserver.get()];
472 #endif
473     [[NSNotificationCenter defaultCenter] removeObserver:m_activationObserver.get()];
474     [[NSNotificationCenter defaultCenter] removeObserver:m_deactivationObserver.get()];
475 #elif PLATFORM(IOS)
476     CFNotificationCenterRemoveObserver(CFNotificationCenterGetDarwinNotifyCenter(), this, static_cast<CFStringRef>(UIBacklightLevelChangedNotification) , nullptr);
477     [[NSNotificationCenter defaultCenter] removeObserver:m_accessibilityEnabledObserver.get()];
478 #endif // !PLATFORM(IOS_FAMILY)
479 }
480
481 static CFURLStorageSessionRef privateBrowsingSession()
482 {
483     static CFURLStorageSessionRef session;
484     static dispatch_once_t once;
485     dispatch_once(&once, ^{
486         NSString *identifier = [NSString stringWithFormat:@"%@.PrivateBrowsing", [[NSBundle mainBundle] bundleIdentifier]];
487         session = createPrivateStorageSession((__bridge CFStringRef)identifier);
488     });
489
490     return session;
491 }
492
493 bool WebProcessPool::isURLKnownHSTSHost(const String& urlString, bool privateBrowsingEnabled) const
494 {
495     RetainPtr<CFURLRef> url = URL(URL(), urlString).createCFURL();
496
497     return _CFNetworkIsKnownHSTSHostWithSession(url.get(), privateBrowsingEnabled ? privateBrowsingSession() : nullptr);
498 }
499
500 void WebProcessPool::resetHSTSHosts()
501 {
502     _CFNetworkResetHSTSHostsWithSession(nullptr);
503     _CFNetworkResetHSTSHostsWithSession(privateBrowsingSession());
504 }
505
506 void WebProcessPool::resetHSTSHostsAddedAfterDate(double startDateIntervalSince1970)
507 {
508     NSDate *startDate = [NSDate dateWithTimeIntervalSince1970:startDateIntervalSince1970];
509     _CFNetworkResetHSTSHostsSinceDate(nullptr, (__bridge CFDateRef)startDate);
510     _CFNetworkResetHSTSHostsSinceDate(privateBrowsingSession(), (__bridge CFDateRef)startDate);
511 }
512
513 #if PLATFORM(MAC) && ENABLE(WEBPROCESS_WINDOWSERVER_BLOCKING)
514 void WebProcessPool::startDisplayLink(IPC::Connection& connection, unsigned observerID, uint32_t displayID)
515 {
516     for (auto& displayLink : m_displayLinks) {
517         if (displayLink->displayID() == displayID) {
518             displayLink->addObserver(connection, observerID);
519             return;
520         }
521     }
522     auto displayLink = std::make_unique<DisplayLink>(displayID);
523     displayLink->addObserver(connection, observerID);
524     m_displayLinks.append(WTFMove(displayLink));
525 }
526
527 void WebProcessPool::stopDisplayLink(IPC::Connection& connection, unsigned observerID, uint32_t displayID)
528 {
529     for (auto& displayLink : m_displayLinks) {
530         if (displayLink->displayID() == displayID) {
531             displayLink->removeObserver(connection, observerID);
532             return;
533         }
534     }
535 }
536
537 void WebProcessPool::stopDisplayLinks(IPC::Connection& connection)
538 {
539     for (auto& displayLink : m_displayLinks)
540         displayLink->removeObservers(connection);
541 }
542 #endif
543
544 // FIXME: Deprecated. Left here until a final decision is made.
545 void WebProcessPool::setCookieStoragePartitioningEnabled(bool enabled)
546 {
547     m_cookieStoragePartitioningEnabled = enabled;
548 }
549
550 void WebProcessPool::setStorageAccessAPIEnabled(bool enabled)
551 {
552     m_storageAccessAPIEnabled = enabled;
553     sendToNetworkingProcess(Messages::NetworkProcess::SetStorageAccessAPIEnabled(enabled));
554 }
555
556 int networkProcessLatencyQOS()
557 {
558     static const int qos = [[NSUserDefaults standardUserDefaults] integerForKey:@"WebKitNetworkProcessLatencyQOS"];
559     return qos;
560 }
561
562 int networkProcessThroughputQOS()
563 {
564     static const int qos = [[NSUserDefaults standardUserDefaults] integerForKey:@"WebKitNetworkProcessThroughputQOS"];
565     return qos;
566 }
567
568 int webProcessLatencyQOS()
569 {
570     static const int qos = [[NSUserDefaults standardUserDefaults] integerForKey:@"WebKitWebProcessLatencyQOS"];
571     return qos;
572 }
573
574 int webProcessThroughputQOS()
575 {
576     static const int qos = [[NSUserDefaults standardUserDefaults] integerForKey:@"WebKitWebProcessThroughputQOS"];
577     return qos;
578 }
579
580 } // namespace WebKit