API tests using permanent credentials should clear credentials left by previous tests
[WebKit-https.git] / Source / WebKit / UIProcess / API / Cocoa / WKProcessPool.mm
1 /*
2  * Copyright (C) 2014-2017 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 "WKProcessPoolInternal.h"
28
29 #import "AutomationClient.h"
30 #import "CacheModel.h"
31 #import "DownloadClient.h"
32 #import "Logging.h"
33 #import "PluginProcessManager.h"
34 #import "SandboxUtilities.h"
35 #import "UIGamepadProvider.h"
36 #import "WKObject.h"
37 #import "WKWebViewInternal.h"
38 #import "WebCertificateInfo.h"
39 #import "WebCookieManagerProxy.h"
40 #import "WebProcessCache.h"
41 #import "WebProcessMessages.h"
42 #import "WebProcessPool.h"
43 #import "_WKAutomationDelegate.h"
44 #import "_WKAutomationSessionInternal.h"
45 #import "_WKDownloadDelegate.h"
46 #import "_WKDownloadInternal.h"
47 #import "_WKProcessPoolConfigurationInternal.h"
48 #import <WebCore/CertificateInfo.h>
49 #import <WebCore/PluginData.h>
50 #import <pal/spi/cf/CFNetworkSPI.h>
51 #import <pal/spi/cocoa/NSKeyedArchiverSPI.h>
52 #import <wtf/BlockPtr.h>
53 #import <wtf/RetainPtr.h>
54 #import <wtf/WeakObjCPtr.h>
55
56 #if PLATFORM(IOS_FAMILY)
57 #import <WebCore/WebCoreThreadSystemInterface.h>
58 #import "WKGeolocationProviderIOS.h"
59 #endif
60
61 static WKProcessPool *sharedProcessPool;
62
63 @implementation WKProcessPool {
64     WeakObjCPtr<id <_WKAutomationDelegate>> _automationDelegate;
65     WeakObjCPtr<id <_WKDownloadDelegate>> _downloadDelegate;
66
67     RetainPtr<_WKAutomationSession> _automationSession;
68 #if PLATFORM(IOS_FAMILY)
69     RetainPtr<WKGeolocationProviderIOS> _geolocationProvider;
70     RetainPtr<id <_WKGeolocationCoreLocationProvider>> _coreLocationProvider;
71 #endif // PLATFORM(IOS_FAMILY)
72 }
73
74 - (instancetype)_initWithConfiguration:(_WKProcessPoolConfiguration *)configuration
75 {
76     if (!(self = [super init]))
77         return nil;
78
79     API::Object::constructInWrapper<WebKit::WebProcessPool>(self, *configuration->_processPoolConfiguration);
80
81     return self;
82 }
83
84 - (instancetype)init
85 {
86     return [self _initWithConfiguration:adoptNS([[_WKProcessPoolConfiguration alloc] init]).get()];
87 }
88
89 - (void)dealloc
90 {
91     _processPool->~WebProcessPool();
92
93     [super dealloc];
94 }
95
96 + (BOOL)supportsSecureCoding
97 {
98     return YES;
99 }
100
101 - (void)encodeWithCoder:(NSCoder *)coder
102 {
103     if (self == sharedProcessPool) {
104         [coder encodeBool:YES forKey:@"isSharedProcessPool"];
105         return;
106     }
107 }
108
109 - (instancetype)initWithCoder:(NSCoder *)coder
110 {
111     if (!(self = [self init]))
112         return nil;
113
114     if ([coder decodeBoolForKey:@"isSharedProcessPool"]) {
115         [self release];
116
117         return [[WKProcessPool _sharedProcessPool] retain];
118     }
119
120     return self;
121 }
122
123 - (NSString *)description
124 {
125     return [NSString stringWithFormat:@"<%@: %p; configuration = %@>", NSStringFromClass(self.class), self, wrapper(_processPool->configuration())];
126 }
127
128 - (_WKProcessPoolConfiguration *)_configuration
129 {
130     return wrapper(_processPool->configuration().copy());
131 }
132
133 - (API::Object&)_apiObject
134 {
135     return *_processPool;
136 }
137
138 #if PLATFORM(IOS_FAMILY)
139 - (WKGeolocationProviderIOS *)_geolocationProvider
140 {
141     if (!_geolocationProvider)
142         _geolocationProvider = adoptNS([[WKGeolocationProviderIOS alloc] initWithProcessPool:*_processPool]);
143     return _geolocationProvider.get();
144 }
145 #endif // PLATFORM(IOS_FAMILY)
146
147 @end
148
149 @implementation WKProcessPool (WKPrivate)
150
151 + (WKProcessPool *)_sharedProcessPool
152 {
153     static dispatch_once_t onceToken;
154     dispatch_once(&onceToken, ^{
155         sharedProcessPool = [[WKProcessPool alloc] init];
156     });
157
158     return sharedProcessPool;
159 }
160
161 + (NSArray<WKProcessPool *> *)_allProcessPoolsForTesting
162 {
163     auto& allPools = WebKit::WebProcessPool::allProcessPools();
164     auto nsAllPools = adoptNS([[NSMutableArray alloc] initWithCapacity:allPools.size()]);
165     for (auto* pool : allPools)
166         [nsAllPools addObject:wrapper(*pool)];
167     return nsAllPools.autorelease();
168 }
169
170 + (NSURL *)_websiteDataURLForContainerWithURL:(NSURL *)containerURL
171 {
172     return [WKProcessPool _websiteDataURLForContainerWithURL:containerURL bundleIdentifierIfNotInContainer:nil];
173 }
174
175 + (NSURL *)_websiteDataURLForContainerWithURL:(NSURL *)containerURL bundleIdentifierIfNotInContainer:(NSString *)bundleIdentifier
176 {
177     NSURL *url = [containerURL URLByAppendingPathComponent:@"Library" isDirectory:YES];
178     url = [url URLByAppendingPathComponent:@"WebKit" isDirectory:YES];
179
180     if (!WebKit::processHasContainer() && bundleIdentifier)
181         url = [url URLByAppendingPathComponent:bundleIdentifier isDirectory:YES];
182
183     return [url URLByAppendingPathComponent:@"WebsiteData" isDirectory:YES];
184 }
185
186 - (void)_setAllowsSpecificHTTPSCertificate:(NSArray *)certificateChain forHost:(NSString *)host
187 {
188     _processPool->allowSpecificHTTPSCertificateForHost(WebKit::WebCertificateInfo::create(WebCore::CertificateInfo((__bridge CFArrayRef)certificateChain)).ptr(), host);
189 }
190
191 - (void)_registerURLSchemeServiceWorkersCanHandle:(NSString *)scheme
192 {
193     _processPool->registerURLSchemeServiceWorkersCanHandle(scheme);
194 }
195
196 - (void)_registerURLSchemeAsCanDisplayOnlyIfCanRequest:(NSString *)scheme
197 {
198     _processPool->registerURLSchemeAsCanDisplayOnlyIfCanRequest(scheme);
199 }
200
201 - (void)_setCanHandleHTTPSServerTrustEvaluation:(BOOL)value
202 {
203     _processPool->setCanHandleHTTPSServerTrustEvaluation(value);
204 }
205
206 static WebKit::HTTPCookieAcceptPolicy toHTTPCookieAcceptPolicy(NSHTTPCookieAcceptPolicy policy)
207 {
208     switch (static_cast<NSUInteger>(policy)) {
209     case NSHTTPCookieAcceptPolicyAlways:
210         return WebKit::HTTPCookieAcceptPolicy::AlwaysAccept;
211     case NSHTTPCookieAcceptPolicyNever:
212         return WebKit::HTTPCookieAcceptPolicy::Never;
213     case NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain:
214         return WebKit::HTTPCookieAcceptPolicy::OnlyFromMainDocumentDomain;
215     case NSHTTPCookieAcceptPolicyExclusivelyFromMainDocumentDomain:
216         return WebKit::HTTPCookieAcceptPolicy::ExclusivelyFromMainDocumentDomain;
217     }
218
219     ASSERT_NOT_REACHED();
220     return WebKit::HTTPCookieAcceptPolicy::AlwaysAccept;
221 }
222
223 - (void)_setCookieAcceptPolicy:(NSHTTPCookieAcceptPolicy)policy
224 {
225     _processPool->supplement<WebKit::WebCookieManagerProxy>()->setHTTPCookieAcceptPolicy(PAL::SessionID::defaultSessionID(), toHTTPCookieAcceptPolicy(policy), [](WebKit::CallbackBase::Error){});
226 }
227
228 - (id)_objectForBundleParameter:(NSString *)parameter
229 {
230     return [_processPool->bundleParameters() objectForKey:parameter];
231 }
232
233 - (void)_setObject:(id <NSCopying, NSSecureCoding>)object forBundleParameter:(NSString *)parameter
234 {
235     auto copy = adoptNS([(NSObject *)object copy]);
236     auto keyedArchiver = secureArchiver();
237
238     @try {
239         [keyedArchiver encodeObject:copy.get() forKey:@"parameter"];
240         [keyedArchiver finishEncoding];
241     } @catch (NSException *exception) {
242         LOG_ERROR("Failed to encode bundle parameter: %@", exception);
243     }
244
245     if (copy)
246         [_processPool->ensureBundleParameters() setObject:copy.get() forKey:parameter];
247     else
248         [_processPool->ensureBundleParameters() removeObjectForKey:parameter];
249
250     auto data = keyedArchiver.get().encodedData;
251     _processPool->sendToAllProcesses(Messages::WebProcess::SetInjectedBundleParameter(parameter, IPC::DataReference(static_cast<const uint8_t*>([data bytes]), [data length])));
252 }
253
254 - (void)_setObjectsForBundleParametersWithDictionary:(NSDictionary *)dictionary
255 {
256     auto copy = adoptNS([[NSDictionary alloc] initWithDictionary:dictionary copyItems:YES]);
257     auto keyedArchiver = secureArchiver();
258
259     @try {
260         [keyedArchiver encodeObject:copy.get() forKey:@"parameters"];
261         [keyedArchiver finishEncoding];
262     } @catch (NSException *exception) {
263         LOG_ERROR("Failed to encode bundle parameters: %@", exception);
264     }
265
266     [_processPool->ensureBundleParameters() setValuesForKeysWithDictionary:copy.get()];
267
268     auto data = keyedArchiver.get().encodedData;
269     _processPool->sendToAllProcesses(Messages::WebProcess::SetInjectedBundleParameters(IPC::DataReference(static_cast<const uint8_t*>([data bytes]), [data length])));
270 }
271
272 #if !TARGET_OS_IPHONE
273
274 #if ENABLE(NETSCAPE_PLUGIN_API)
275
276 static bool isPluginLoadClientPolicyAcceptable(unsigned policy)
277 {
278     return policy <= WebCore::PluginLoadClientPolicyMaximum;
279 }
280 static HashMap<String, HashMap<String, HashMap<String, uint8_t>>> toPluginLoadClientPoliciesHashMap(NSDictionary* dictionary)
281 {
282     __block HashMap<String, HashMap<String, HashMap<String, uint8_t>>> pluginLoadClientPolicies;
283     [dictionary enumerateKeysAndObjectsUsingBlock:^(id nsHost, id nsPoliciesForHost, BOOL *stop) {
284         if (![nsHost isKindOfClass:[NSString class]]) {
285             RELEASE_LOG_ERROR(Plugins, "_resetPluginLoadClientPolicies was called with dictionary in wrong format");
286             return;
287         }
288         if (![nsPoliciesForHost isKindOfClass:[NSDictionary class]]) {
289             RELEASE_LOG_ERROR(Plugins, "_resetPluginLoadClientPolicies was called with dictionary in wrong format");
290             return;
291         }
292
293         String host = (NSString *)nsHost;
294         __block HashMap<String, HashMap<String, uint8_t>> policiesForHost;
295         [nsPoliciesForHost enumerateKeysAndObjectsUsingBlock:^(id nsIdentifier, id nsVersionsToPolicies, BOOL *stop) {
296             if (![nsIdentifier isKindOfClass:[NSString class]]) {
297                 RELEASE_LOG_ERROR(Plugins, "_resetPluginLoadClientPolicies was called with dictionary in wrong format");
298                 return;
299             }
300             if (![nsVersionsToPolicies isKindOfClass:[NSDictionary class]]) {
301                 RELEASE_LOG_ERROR(Plugins, "_resetPluginLoadClientPolicies was called with dictionary in wrong format");
302                 return;
303             }
304
305             String bundleIdentifier = (NSString *)nsIdentifier;
306             __block HashMap<String, uint8_t> versionsToPolicies;
307             [nsVersionsToPolicies enumerateKeysAndObjectsUsingBlock:^(id nsVersion, id nsPolicy, BOOL *stop) {
308                 if (![nsVersion isKindOfClass:[NSString class]]) {
309                     RELEASE_LOG_ERROR(Plugins, "_resetPluginLoadClientPolicies was called with dictionary in wrong format");
310                     return;
311                 }
312                 if (![nsPolicy isKindOfClass:[NSNumber class]]) {
313                     RELEASE_LOG_ERROR(Plugins, "_resetPluginLoadClientPolicies was called with dictionary in wrong format");
314                     return;
315                 }
316                 unsigned policy = ((NSNumber *)nsPolicy).unsignedIntValue;
317                 if (!isPluginLoadClientPolicyAcceptable(policy)) {
318                     RELEASE_LOG_ERROR(Plugins, "_resetPluginLoadClientPolicies was called with dictionary in wrong format");
319                     return;
320                 }
321                 String version = (NSString *)nsVersion;
322                 versionsToPolicies.add(version, static_cast<uint8_t>(policy));
323             }];
324             if (!versionsToPolicies.isEmpty())
325                 policiesForHost.add(bundleIdentifier, WTFMove(versionsToPolicies));
326         }];
327         if (!policiesForHost.isEmpty())
328             pluginLoadClientPolicies.add(host, WTFMove(policiesForHost));
329     }];
330     return pluginLoadClientPolicies;
331 }
332
333 static NSDictionary *policiesHashMapToDictionary(const HashMap<String, HashMap<String, HashMap<String, uint8_t>>>& map)
334 {
335     auto policies = adoptNS([[NSMutableDictionary alloc] initWithCapacity:map.size()]);
336     for (auto& hostPair : map) {
337         NSString *host = hostPair.key;
338         policies.get()[host] = adoptNS([[NSMutableDictionary alloc] initWithCapacity:hostPair.value.size()]).get();
339         for (auto& bundleIdentifierPair : hostPair.value) {
340             NSString *bundlerIdentifier = bundleIdentifierPair.key;
341             policies.get()[host][bundlerIdentifier] = adoptNS([[NSMutableDictionary alloc] initWithCapacity:bundleIdentifierPair.value.size()]).get();
342             for (auto& versionPair : bundleIdentifierPair.value) {
343                 NSString *version = versionPair.key;
344                 policies.get()[host][bundlerIdentifier][version] = adoptNS([[NSNumber alloc] initWithUnsignedInt:versionPair.value]).get();
345             }
346         }
347     }
348     return policies.autorelease();
349 }
350
351 #endif
352
353 - (void)_resetPluginLoadClientPolicies:(NSDictionary *)policies
354 {
355 #if ENABLE(NETSCAPE_PLUGIN_API)
356     _processPool->resetPluginLoadClientPolicies(toPluginLoadClientPoliciesHashMap(policies));
357 #endif
358 }
359
360 -(NSDictionary *)_pluginLoadClientPolicies
361 {
362     auto& map = _processPool->pluginLoadClientPolicies();
363     return policiesHashMapToDictionary(map);
364 }
365 #endif
366
367
368 - (id <_WKDownloadDelegate>)_downloadDelegate
369 {
370     return _downloadDelegate.getAutoreleased();
371 }
372
373 - (void)_setDownloadDelegate:(id <_WKDownloadDelegate>)downloadDelegate
374 {
375     _downloadDelegate = downloadDelegate;
376     _processPool->setDownloadClient(std::make_unique<WebKit::DownloadClient>(downloadDelegate));
377 }
378
379 - (id <_WKAutomationDelegate>)_automationDelegate
380 {
381     return _automationDelegate.getAutoreleased();
382 }
383
384 - (void)_setAutomationDelegate:(id <_WKAutomationDelegate>)automationDelegate
385 {
386     _automationDelegate = automationDelegate;
387     _processPool->setAutomationClient(std::make_unique<WebKit::AutomationClient>(self, automationDelegate));
388 }
389
390 - (void)_warmInitialProcess
391 {
392     _processPool->prewarmProcess();
393 }
394
395 - (void)_automationCapabilitiesDidChange
396 {
397     _processPool->updateAutomationCapabilities();
398 }
399
400 - (void)_setAutomationSession:(_WKAutomationSession *)automationSession
401 {
402     _automationSession = automationSession;
403     _processPool->setAutomationSession(automationSession ? automationSession->_session.get() : nullptr);
404 }
405
406 - (NSURL *)_javaScriptConfigurationDirectory
407 {
408     return [NSURL fileURLWithPath:_processPool->javaScriptConfigurationDirectory() isDirectory:YES];
409 }
410
411 - (void)_setJavaScriptConfigurationDirectory:(NSURL *)directory
412 {
413     if (directory && ![directory isFileURL])
414         [NSException raise:NSInvalidArgumentException format:@"%@ is not a file URL", directory];
415     _processPool->setJavaScriptConfigurationDirectory(directory.path);
416 }
417
418 - (void)_addSupportedPlugin:(NSString *) domain named:(NSString *) name withMimeTypes: (NSSet<NSString *> *) nsMimeTypes withExtensions: (NSSet<NSString *> *) nsExtensions
419 {
420     HashSet<String> mimeTypes;
421     for (NSString *mimeType in nsMimeTypes)
422         mimeTypes.add(mimeType);
423     HashSet<String> extensions;
424     for (NSString *extension in nsExtensions)
425         extensions.add(extension);
426
427     _processPool->addSupportedPlugin(domain, name, WTFMove(mimeTypes), WTFMove(extensions));
428 }
429
430 - (void)_clearSupportedPlugins
431 {
432     _processPool->clearSupportedPlugins();
433 }
434
435 - (void)_terminateNetworkProcess
436 {
437     _processPool->terminateNetworkProcess();
438 }
439
440 - (void)_sendNetworkProcessWillSuspendImminently
441 {
442     _processPool->sendNetworkProcessWillSuspendImminentlyForTesting();
443 }
444
445 - (void)_sendNetworkProcessDidResume
446 {
447     _processPool->sendNetworkProcessDidResume();
448 }
449
450 - (void)_terminateServiceWorkerProcesses
451 {
452     _processPool->terminateServiceWorkerProcesses();
453 }
454
455 - (void)_disableServiceWorkerProcessTerminationDelay
456 {
457     _processPool->disableServiceWorkerProcessTerminationDelay();
458 }
459
460 - (pid_t)_networkProcessIdentifier
461 {
462     return _processPool->networkProcessIdentifier();
463 }
464
465 - (pid_t)_prewarmedProcessIdentifier
466 {
467     return _processPool->prewarmedProcessIdentifier();
468 }
469
470
471 - (void)_syncNetworkProcessCookies
472 {
473     _processPool->syncNetworkProcessCookies();
474 }
475
476 - (size_t)_webProcessCount
477 {
478     return _processPool->processes().size();
479 }
480
481 - (void)_makeNextWebProcessLaunchFailForTesting
482 {
483     _processPool->setShouldMakeNextWebProcessLaunchFailForTesting(true);
484 }
485
486 - (void)_makeNextNetworkProcessLaunchFailForTesting
487 {
488     _processPool->setShouldMakeNextNetworkProcessLaunchFailForTesting(true);
489 }
490
491 - (BOOL)_hasPrewarmedWebProcess
492 {
493     for (auto& process : _processPool->processes()) {
494         if (process->isPrewarmed())
495             return YES;
496     }
497     return NO;
498 }
499
500 - (size_t)_webProcessCountIgnoringPrewarmed
501 {
502     return [self _webProcessCount] - ([self _hasPrewarmedWebProcess] ? 1 : 0);
503 }
504
505 - (size_t)_webProcessCountIgnoringPrewarmedAndCached
506 {
507     size_t count = 0;
508     for (auto& process : _processPool->processes()) {
509         if (!process->isInProcessCache() && !process->isPrewarmed())
510             ++count;
511     }
512     return count;
513 }
514
515 - (size_t)_webPageContentProcessCount
516 {
517     auto allWebProcesses = _processPool->processes();
518 #if ENABLE(SERVICE_WORKER)
519     auto& serviceWorkerProcesses = _processPool->serviceWorkerProxies();
520     if (serviceWorkerProcesses.isEmpty())
521         return allWebProcesses.size();
522
523     return allWebProcesses.size() - serviceWorkerProcesses.size();
524 #else
525     return allWebProcesses.size();
526 #endif
527 }
528
529 - (void)_preconnectToServer:(NSURL *)serverURL
530 {
531     _processPool->preconnectToServer(serverURL);
532 }
533
534 - (size_t)_pluginProcessCount
535 {
536 #if !PLATFORM(IOS_FAMILY)
537     return WebKit::PluginProcessManager::singleton().pluginProcesses().size();
538 #else
539     return 0;
540 #endif
541 }
542
543 - (NSUInteger)_maximumSuspendedPageCount
544 {
545     return _processPool->maxSuspendedPageCount();
546 }
547
548 - (NSUInteger)_processCacheCapacity
549 {
550     return _processPool->webProcessCache().capacity();
551 }
552
553 - (NSUInteger)_processCacheSize
554 {
555     return _processPool->webProcessCache().size();
556 }
557
558 - (size_t)_serviceWorkerProcessCount
559 {
560 #if ENABLE(SERVICE_WORKER)
561     return _processPool->serviceWorkerProxies().size();
562 #else
563     return 0;
564 #endif
565 }
566
567 + (void)_forceGameControllerFramework
568 {
569 #if ENABLE(GAMEPAD)
570     WebKit::UIGamepadProvider::setUsesGameControllerFramework();
571 #endif
572 }
573
574 - (BOOL)_isCookieStoragePartitioningEnabled
575 {
576     return _processPool->cookieStoragePartitioningEnabled();
577 }
578
579 - (void)_setCookieStoragePartitioningEnabled:(BOOL)enabled
580 {
581     _processPool->setCookieStoragePartitioningEnabled(enabled);
582 }
583
584 - (BOOL)_isStorageAccessAPIEnabled
585 {
586     return _processPool->storageAccessAPIEnabled();
587 }
588
589 - (void)_setStorageAccessAPIEnabled:(BOOL)enabled
590 {
591     _processPool->setStorageAccessAPIEnabled(enabled);
592 }
593
594 - (void)_synthesizeAppIsBackground:(BOOL)background
595 {
596     _processPool->synthesizeAppIsBackground(background);
597 }
598
599 - (void)_setAllowsAnySSLCertificateForServiceWorker:(BOOL)allows
600 {
601 #if ENABLE(SERVICE_WORKER)
602     _processPool->setAllowsAnySSLCertificateForServiceWorker(allows);
603 #endif
604 }
605
606 #if PLATFORM(IOS_FAMILY)
607 - (id <_WKGeolocationCoreLocationProvider>)_coreLocationProvider
608 {
609     return _coreLocationProvider.get();
610 }
611
612 - (void)_setCoreLocationProvider:(id<_WKGeolocationCoreLocationProvider>)coreLocationProvider
613 {
614     if (_geolocationProvider)
615         [NSException raise:NSGenericException format:@"Changing the location provider is not supported after a web view in the process pool has begun servicing geolocation requests."];
616
617     _coreLocationProvider = coreLocationProvider;
618 }
619 #endif // PLATFORM(IOS_FAMILY)
620
621 - (_WKDownload *)_downloadURLRequest:(NSURLRequest *)request originatingWebView:(WKWebView *)webView
622 {
623     return (_WKDownload *)_processPool->download([webView _page], request).wrapper();
624 }
625
626 - (_WKDownload *)_resumeDownloadFromData:(NSData *)resumeData path:(NSString *)path originatingWebView:(WKWebView *)webView
627 {
628     return wrapper(_processPool->resumeDownload([webView _page], API::Data::createWithoutCopying(resumeData).ptr(), path));
629 }
630
631 - (void)_getActivePagesOriginsInWebProcessForTesting:(pid_t)pid completionHandler:(void(^)(NSArray<NSString *> *))completionHandler
632 {
633     _processPool->activePagesOriginsInWebProcessForTesting(pid, [completionHandler = makeBlockPtr(completionHandler)] (Vector<String>&& activePagesOrigins) {
634         NSMutableArray<NSString *> *array = [[[NSMutableArray alloc] initWithCapacity:activePagesOrigins.size()] autorelease];
635         for (auto& origin : activePagesOrigins)
636             [array addObject:origin];
637         completionHandler(array);
638     });
639 }
640
641 - (BOOL)_networkProcessHasEntitlementForTesting:(NSString *)entitlement
642 {
643     return _processPool->networkProcessHasEntitlementForTesting(entitlement);
644 }
645
646 - (void)_clearPermanentCredentialsForProtectionSpace:(NSURLProtectionSpace *)protectionSpace
647 {
648     _processPool->clearPermanentCredentialsForProtectionSpace(WebCore::ProtectionSpace(protectionSpace));
649 }
650
651 @end