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