| /* |
| * Copyright (C) 2014, 2016 Apple Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' |
| * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, |
| * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS |
| * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
| * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
| * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
| * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
| * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
| * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
| * THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #import "config.h" |
| #import "WKProcessPoolInternal.h" |
| |
| #if WK_API_ENABLED |
| |
| #import "AutomationClient.h" |
| #import "CacheModel.h" |
| #import "DownloadClient.h" |
| #import "SandboxUtilities.h" |
| #import "UIGamepadProvider.h" |
| #import "WKObject.h" |
| #import "WeakObjCPtr.h" |
| #import "WebCertificateInfo.h" |
| #import "WebCookieManagerProxy.h" |
| #import "WebProcessMessages.h" |
| #import "WebProcessPool.h" |
| #import "_WKAutomationDelegate.h" |
| #import "_WKAutomationSessionInternal.h" |
| #import "_WKDownloadDelegate.h" |
| #import "_WKProcessPoolConfigurationInternal.h" |
| #import <WebCore/CFNetworkSPI.h> |
| #import <WebCore/CertificateInfo.h> |
| #import <wtf/RetainPtr.h> |
| |
| #if PLATFORM(IOS) |
| #import <WebCore/WebCoreThreadSystemInterface.h> |
| #import "WKGeolocationProviderIOS.h" |
| #endif |
| |
| static WKProcessPool *sharedProcessPool; |
| |
| @implementation WKProcessPool { |
| WebKit::WeakObjCPtr<id <_WKAutomationDelegate>> _automationDelegate; |
| WebKit::WeakObjCPtr<id <_WKDownloadDelegate>> _downloadDelegate; |
| |
| RetainPtr<_WKAutomationSession> _automationSession; |
| #if PLATFORM(IOS) |
| RetainPtr<WKGeolocationProviderIOS> _geolocationProvider; |
| #endif // PLATFORM(IOS) |
| } |
| |
| - (instancetype)_initWithConfiguration:(_WKProcessPoolConfiguration *)configuration |
| { |
| if (!(self = [super init])) |
| return nil; |
| |
| #if PLATFORM(IOS) |
| // FIXME: Remove once <rdar://problem/15256572> is fixed. |
| InitWebCoreThreadSystemInterface(); |
| #endif |
| |
| API::Object::constructInWrapper<WebKit::WebProcessPool>(self, *configuration->_processPoolConfiguration); |
| |
| return self; |
| } |
| |
| - (instancetype)init |
| { |
| return [self _initWithConfiguration:adoptNS([[_WKProcessPoolConfiguration alloc] init]).get()]; |
| } |
| |
| - (void)dealloc |
| { |
| _processPool->~WebProcessPool(); |
| |
| [super dealloc]; |
| } |
| |
| - (void)encodeWithCoder:(NSCoder *)coder |
| { |
| if (self == sharedProcessPool) { |
| [coder encodeBool:YES forKey:@"isSharedProcessPool"]; |
| return; |
| } |
| } |
| |
| - (instancetype)initWithCoder:(NSCoder *)coder |
| { |
| if (!(self = [self init])) |
| return nil; |
| |
| if ([coder decodeBoolForKey:@"isSharedProcessPool"]) { |
| [self release]; |
| |
| return [[WKProcessPool _sharedProcessPool] retain]; |
| } |
| |
| return self; |
| } |
| |
| - (NSString *)description |
| { |
| return [NSString stringWithFormat:@"<%@: %p; configuration = %@>", NSStringFromClass(self.class), self, wrapper(_processPool->configuration())]; |
| } |
| |
| - (_WKProcessPoolConfiguration *)_configuration |
| { |
| return wrapper(_processPool->configuration().copy().leakRef()); |
| } |
| |
| - (API::Object&)_apiObject |
| { |
| return *_processPool; |
| } |
| |
| #if PLATFORM(IOS) |
| - (WKGeolocationProviderIOS *)_geolocationProvider |
| { |
| if (!_geolocationProvider) |
| _geolocationProvider = adoptNS([[WKGeolocationProviderIOS alloc] initWithProcessPool:*_processPool]); |
| return _geolocationProvider.get(); |
| } |
| #endif // PLATFORM(IOS) |
| |
| @end |
| |
| @implementation WKProcessPool (WKPrivate) |
| |
| + (WKProcessPool *)_sharedProcessPool |
| { |
| static dispatch_once_t onceToken; |
| dispatch_once(&onceToken, ^{ |
| sharedProcessPool = [[WKProcessPool alloc] init]; |
| }); |
| |
| return sharedProcessPool; |
| } |
| |
| + (NSURL *)_websiteDataURLForContainerWithURL:(NSURL *)containerURL |
| { |
| return [WKProcessPool _websiteDataURLForContainerWithURL:containerURL bundleIdentifierIfNotInContainer:nil]; |
| } |
| |
| + (NSURL *)_websiteDataURLForContainerWithURL:(NSURL *)containerURL bundleIdentifierIfNotInContainer:(NSString *)bundleIdentifier |
| { |
| NSURL *url = [containerURL URLByAppendingPathComponent:@"Library" isDirectory:YES]; |
| url = [url URLByAppendingPathComponent:@"WebKit" isDirectory:YES]; |
| |
| if (!WebKit::processHasContainer() && bundleIdentifier) |
| url = [url URLByAppendingPathComponent:bundleIdentifier isDirectory:YES]; |
| |
| return [url URLByAppendingPathComponent:@"WebsiteData" isDirectory:YES]; |
| } |
| |
| - (void)_setAllowsSpecificHTTPSCertificate:(NSArray *)certificateChain forHost:(NSString *)host |
| { |
| _processPool->allowSpecificHTTPSCertificateForHost(WebKit::WebCertificateInfo::create(WebCore::CertificateInfo((CFArrayRef)certificateChain)).ptr(), host); |
| } |
| |
| - (void)_setCanHandleHTTPSServerTrustEvaluation:(BOOL)value |
| { |
| _processPool->setCanHandleHTTPSServerTrustEvaluation(value); |
| } |
| |
| static WebKit::HTTPCookieAcceptPolicy toHTTPCookieAcceptPolicy(NSHTTPCookieAcceptPolicy policy) |
| { |
| switch (static_cast<NSUInteger>(policy)) { |
| case NSHTTPCookieAcceptPolicyAlways: |
| return WebKit::HTTPCookieAcceptPolicyAlways; |
| case NSHTTPCookieAcceptPolicyNever: |
| return WebKit::HTTPCookieAcceptPolicyNever; |
| case NSHTTPCookieAcceptPolicyOnlyFromMainDocumentDomain: |
| return WebKit::HTTPCookieAcceptPolicyOnlyFromMainDocumentDomain; |
| case NSHTTPCookieAcceptPolicyExclusivelyFromMainDocumentDomain: |
| return WebKit::HTTPCookieAcceptPolicyExclusivelyFromMainDocumentDomain; |
| } |
| |
| ASSERT_NOT_REACHED(); |
| return WebKit::HTTPCookieAcceptPolicyAlways; |
| } |
| |
| - (void)_setCookieAcceptPolicy:(NSHTTPCookieAcceptPolicy)policy |
| { |
| _processPool->supplement<WebKit::WebCookieManagerProxy>()->setHTTPCookieAcceptPolicy(toHTTPCookieAcceptPolicy(policy)); |
| } |
| |
| - (id)_objectForBundleParameter:(NSString *)parameter |
| { |
| return [_processPool->bundleParameters() objectForKey:parameter]; |
| } |
| |
| - (void)_setObject:(id <NSCopying, NSSecureCoding>)object forBundleParameter:(NSString *)parameter |
| { |
| auto copy = adoptNS([(NSObject *)object copy]); |
| |
| auto data = adoptNS([[NSMutableData alloc] init]); |
| auto keyedArchiver = adoptNS([[NSKeyedArchiver alloc] initForWritingWithMutableData:data.get()]); |
| [keyedArchiver setRequiresSecureCoding:YES]; |
| |
| @try { |
| [keyedArchiver encodeObject:copy.get() forKey:@"parameter"]; |
| [keyedArchiver finishEncoding]; |
| } @catch (NSException *exception) { |
| LOG_ERROR("Failed to encode bundle parameter: %@", exception); |
| } |
| |
| if (copy) |
| [_processPool->ensureBundleParameters() setObject:copy.get() forKey:parameter]; |
| else |
| [_processPool->ensureBundleParameters() removeObjectForKey:parameter]; |
| |
| _processPool->sendToAllProcesses(Messages::WebProcess::SetInjectedBundleParameter(parameter, IPC::DataReference(static_cast<const uint8_t*>([data bytes]), [data length]))); |
| } |
| |
| - (void)_setObjectsForBundleParametersWithDictionary:(NSDictionary *)dictionary |
| { |
| auto copy = adoptNS([[NSDictionary alloc] initWithDictionary:dictionary copyItems:YES]); |
| |
| auto data = adoptNS([[NSMutableData alloc] init]); |
| auto keyedArchiver = adoptNS([[NSKeyedArchiver alloc] initForWritingWithMutableData:data.get()]); |
| [keyedArchiver setRequiresSecureCoding:YES]; |
| |
| @try { |
| [keyedArchiver encodeObject:copy.get() forKey:@"parameters"]; |
| [keyedArchiver finishEncoding]; |
| } @catch (NSException *exception) { |
| LOG_ERROR("Failed to encode bundle parameters: %@", exception); |
| } |
| |
| [_processPool->ensureBundleParameters() setValuesForKeysWithDictionary:copy.get()]; |
| |
| _processPool->sendToAllProcesses(Messages::WebProcess::SetInjectedBundleParameters(IPC::DataReference(static_cast<const uint8_t*>([data bytes]), [data length]))); |
| } |
| |
| |
| - (id <_WKDownloadDelegate>)_downloadDelegate |
| { |
| return _downloadDelegate.getAutoreleased(); |
| } |
| |
| - (void)_setDownloadDelegate:(id <_WKDownloadDelegate>)downloadDelegate |
| { |
| _downloadDelegate = downloadDelegate; |
| _processPool->setDownloadClient(std::make_unique<WebKit::DownloadClient>(downloadDelegate)); |
| } |
| |
| - (id <_WKAutomationDelegate>)_automationDelegate |
| { |
| return _automationDelegate.getAutoreleased(); |
| } |
| |
| - (void)_setAutomationDelegate:(id <_WKAutomationDelegate>)automationDelegate |
| { |
| _automationDelegate = automationDelegate; |
| _processPool->setAutomationClient(std::make_unique<WebKit::AutomationClient>(self, automationDelegate)); |
| } |
| |
| - (void)_warmInitialProcess |
| { |
| _processPool->warmInitialProcess(); |
| } |
| |
| - (void)_automationCapabilitiesDidChange |
| { |
| _processPool->updateAutomationCapabilities(); |
| } |
| |
| - (void)_setAutomationSession:(_WKAutomationSession *)automationSession |
| { |
| _automationSession = automationSession; |
| _processPool->setAutomationSession(automationSession ? automationSession->_session.get() : nullptr); |
| } |
| |
| - (void)_terminateDatabaseProcess |
| { |
| _processPool->terminateDatabaseProcess(); |
| } |
| |
| + (void)_forceGameControllerFramework |
| { |
| #if ENABLE(GAMEPAD) |
| WebKit::UIGamepadProvider::setUsesGameControllerFramework(); |
| #endif |
| } |
| |
| - (BOOL)_isCookieStoragePartitioningEnabled |
| { |
| return _processPool->cookieStoragePartitioningEnabled(); |
| } |
| |
| - (void)_setCookieStoragePartitioningEnabled:(BOOL)enabled |
| { |
| _processPool->setCookieStoragePartitioningEnabled(enabled); |
| } |
| |
| @end |
| |
| #endif // WK_API_ENABLED |