Unreviewed, fix iOS build with recent SDKs.
[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::HTTPCookieAcceptPolicyAlways;
211     case NSHTTPCookieAcceptPolicyNever:
212         return WebKit::HTTPCookieAcceptPolicyNever;
213     case NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain:
214         return WebKit::HTTPCookieAcceptPolicyOnlyFromMainDocumentDomain;
215     case NSHTTPCookieAcceptPolicyExclusivelyFromMainDocumentDomain:
216         return WebKit::HTTPCookieAcceptPolicyExclusivelyFromMainDocumentDomain;
217     }
218
219     ASSERT_NOT_REACHED();
220     return WebKit::HTTPCookieAcceptPolicyAlways;
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 - (void)_addSupportedPlugin:(NSString *) domain named:(NSString *) name withMimeTypes: (NSSet<NSString *> *) nsMimeTypes withExtensions: (NSSet<NSString *> *) nsExtensions
407 {
408     HashSet<String> mimeTypes;
409     for (NSString *mimeType in nsMimeTypes)
410         mimeTypes.add(mimeType);
411     HashSet<String> extensions;
412     for (NSString *extension in nsExtensions)
413         extensions.add(extension);
414
415     _processPool->addSupportedPlugin(domain, name, WTFMove(mimeTypes), WTFMove(extensions));
416 }
417
418 - (void)_clearSupportedPlugins
419 {
420     _processPool->clearSupportedPlugins();
421 }
422
423 - (void)_terminateNetworkProcess
424 {
425     _processPool->terminateNetworkProcess();
426 }
427
428 - (void)_sendNetworkProcessWillSuspendImminently
429 {
430     _processPool->sendNetworkProcessWillSuspendImminently();
431 }
432
433 - (void)_sendNetworkProcessDidResume
434 {
435     _processPool->sendNetworkProcessDidResume();
436 }
437
438 - (void)_terminateServiceWorkerProcesses
439 {
440     _processPool->terminateServiceWorkerProcesses();
441 }
442
443 - (void)_disableServiceWorkerProcessTerminationDelay
444 {
445     _processPool->disableServiceWorkerProcessTerminationDelay();
446 }
447
448 - (pid_t)_networkProcessIdentifier
449 {
450     return _processPool->networkProcessIdentifier();
451 }
452
453 - (pid_t)_prewarmedProcessIdentifier
454 {
455     return _processPool->prewarmedProcessIdentifier();
456 }
457
458
459 - (void)_syncNetworkProcessCookies
460 {
461     _processPool->syncNetworkProcessCookies();
462 }
463
464 - (size_t)_webProcessCount
465 {
466     return _processPool->processes().size();
467 }
468
469 - (void)_makeNextWebProcessLaunchFailForTesting
470 {
471     _processPool->setShouldMakeNextWebProcessLaunchFailForTesting(true);
472 }
473
474 - (void)_makeNextNetworkProcessLaunchFailForTesting
475 {
476     _processPool->setShouldMakeNextNetworkProcessLaunchFailForTesting(true);
477 }
478
479 - (BOOL)_hasPrewarmedWebProcess
480 {
481     for (auto& process : _processPool->processes()) {
482         if (process->isPrewarmed())
483             return YES;
484     }
485     return NO;
486 }
487
488 - (size_t)_webProcessCountIgnoringPrewarmed
489 {
490     return [self _webProcessCount] - ([self _hasPrewarmedWebProcess] ? 1 : 0);
491 }
492
493 - (size_t)_webProcessCountIgnoringPrewarmedAndCached
494 {
495     size_t count = 0;
496     for (auto& process : _processPool->processes()) {
497         if (!process->isInProcessCache() && !process->isPrewarmed())
498             ++count;
499     }
500     return count;
501 }
502
503 - (size_t)_webPageContentProcessCount
504 {
505     auto allWebProcesses = _processPool->processes();
506 #if ENABLE(SERVICE_WORKER)
507     auto& serviceWorkerProcesses = _processPool->serviceWorkerProxies();
508     if (serviceWorkerProcesses.isEmpty())
509         return allWebProcesses.size();
510
511     return allWebProcesses.size() - serviceWorkerProcesses.size();
512 #else
513     return allWebProcesses.size();
514 #endif
515 }
516
517 - (void)_preconnectToServer:(NSURL *)serverURL
518 {
519     _processPool->preconnectToServer(serverURL);
520 }
521
522 - (size_t)_pluginProcessCount
523 {
524 #if !PLATFORM(IOS_FAMILY)
525     return WebKit::PluginProcessManager::singleton().pluginProcesses().size();
526 #else
527     return 0;
528 #endif
529 }
530
531 - (NSUInteger)_maximumSuspendedPageCount
532 {
533     return _processPool->maxSuspendedPageCount();
534 }
535
536 - (NSUInteger)_processCacheCapacity
537 {
538     return _processPool->webProcessCache().capacity();
539 }
540
541 - (NSUInteger)_processCacheSize
542 {
543     return _processPool->webProcessCache().size();
544 }
545
546 - (size_t)_serviceWorkerProcessCount
547 {
548 #if ENABLE(SERVICE_WORKER)
549     return _processPool->serviceWorkerProxies().size();
550 #else
551     return 0;
552 #endif
553 }
554
555 + (void)_forceGameControllerFramework
556 {
557 #if ENABLE(GAMEPAD)
558     WebKit::UIGamepadProvider::setUsesGameControllerFramework();
559 #endif
560 }
561
562 - (BOOL)_isCookieStoragePartitioningEnabled
563 {
564     return _processPool->cookieStoragePartitioningEnabled();
565 }
566
567 - (void)_setCookieStoragePartitioningEnabled:(BOOL)enabled
568 {
569     _processPool->setCookieStoragePartitioningEnabled(enabled);
570 }
571
572 - (BOOL)_isStorageAccessAPIEnabled
573 {
574     return _processPool->storageAccessAPIEnabled();
575 }
576
577 - (void)_setStorageAccessAPIEnabled:(BOOL)enabled
578 {
579     _processPool->setStorageAccessAPIEnabled(enabled);
580 }
581
582 - (void)_synthesizeAppIsBackground:(BOOL)background
583 {
584     _processPool->synthesizeAppIsBackground(background);
585 }
586
587 - (void)_setAllowsAnySSLCertificateForServiceWorker:(BOOL) allows
588 {
589 #if ENABLE(SERVICE_WORKER)
590     _processPool->setAllowsAnySSLCertificateForServiceWorker(allows);
591 #endif
592 }
593
594 #if PLATFORM(IOS_FAMILY)
595 - (id <_WKGeolocationCoreLocationProvider>)_coreLocationProvider
596 {
597     return _coreLocationProvider.get();
598 }
599
600 - (void)_setCoreLocationProvider:(id<_WKGeolocationCoreLocationProvider>)coreLocationProvider
601 {
602     if (_geolocationProvider)
603         [NSException raise:NSGenericException format:@"Changing the location provider is not supported after a web view in the process pool has begun servicing geolocation requests."];
604
605     _coreLocationProvider = coreLocationProvider;
606 }
607 #endif // PLATFORM(IOS_FAMILY)
608
609 - (_WKDownload *)_downloadURLRequest:(NSURLRequest *)request originatingWebView:(WKWebView *)webView
610 {
611     return (_WKDownload *)_processPool->download([webView _page], request).wrapper();
612 }
613
614 - (_WKDownload *)_resumeDownloadFromData:(NSData *)resumeData path:(NSString *)path originatingWebView:(WKWebView *)webView
615 {
616     return wrapper(_processPool->resumeDownload([webView _page], API::Data::createWithoutCopying(resumeData).ptr(), path));
617 }
618
619 - (void)_getActivePagesOriginsInWebProcessForTesting:(pid_t)pid completionHandler:(void(^)(NSArray<NSString *> *))completionHandler
620 {
621     _processPool->activePagesOriginsInWebProcessForTesting(pid, [completionHandler = makeBlockPtr(completionHandler)] (Vector<String>&& activePagesOrigins) {
622         NSMutableArray<NSString *> *array = [[[NSMutableArray alloc] initWithCapacity:activePagesOrigins.size()] autorelease];
623         for (auto& origin : activePagesOrigins)
624             [array addObject:origin];
625         completionHandler(array);
626     });
627 }
628
629 - (BOOL)_networkProcessHasEntitlementForTesting:(NSString *)entitlement
630 {
631     return _processPool->networkProcessHasEntitlementForTesting(entitlement);
632 }
633
634 @end