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