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