Move NetworkCache ownership from NetworkProcess to NetworkSession
[WebKit-https.git] / Source / WebKit / UIProcess / API / Cocoa / WKWebsiteDataStore.mm
1 /*
2  * Copyright (C) 2014-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 "WKWebsiteDataStoreInternal.h"
28
29 #import "APIString.h"
30 #import "CompletionHandlerCallChecker.h"
31 #import "WKHTTPCookieStoreInternal.h"
32 #import "WKNSArray.h"
33 #import "WKWebViewInternal.h"
34 #import "WKWebsiteDataRecordInternal.h"
35 #import "WebPageProxy.h"
36 #import "WebResourceLoadStatisticsStore.h"
37 #import "WebResourceLoadStatisticsTelemetry.h"
38 #import "WebsiteDataFetchOption.h"
39 #import "_WKWebsiteDataStoreConfiguration.h"
40 #import "_WKWebsiteDataStoreDelegate.h"
41 #import <WebKit/ServiceWorkerProcessProxy.h>
42 #import <wtf/BlockPtr.h>
43 #import <wtf/URL.h>
44 #import <wtf/WeakObjCPtr.h>
45
46 class WebsiteDataStoreClient final : public WebKit::WebsiteDataStoreClient {
47 public:
48     explicit WebsiteDataStoreClient(id <_WKWebsiteDataStoreDelegate> delegate)
49         : m_delegate(delegate)
50         , m_hasRequestStorageSpaceSelector([m_delegate.get() respondsToSelector:@selector(requestStorageSpace: frameOrigin: quota: currentSize: spaceRequired: decisionHandler:)])
51     {
52     }
53
54 private:
55     void requestStorageSpace(const WebCore::SecurityOriginData& topOrigin, const WebCore::SecurityOriginData& frameOrigin, uint64_t quota, uint64_t currentSize, uint64_t spaceRequired, CompletionHandler<void(Optional<uint64_t>)>&& completionHandler) final
56     {
57         if (!m_hasRequestStorageSpaceSelector || !m_delegate) {
58             completionHandler({ });
59             return;
60         }
61
62         auto checker = WebKit::CompletionHandlerCallChecker::create(m_delegate.getAutoreleased(), @selector(requestStorageSpace: frameOrigin: quota: currentSize: spaceRequired: decisionHandler:));
63         auto decisionHandler = makeBlockPtr([completionHandler = WTFMove(completionHandler), checker = WTFMove(checker)](unsigned long long quota) mutable {
64             if (checker->completionHandlerHasBeenCalled())
65                 return;
66             checker->didCallCompletionHandler();
67             completionHandler(quota);
68         });
69
70         URL mainFrameURL { URL(), topOrigin.toString() };
71         URL frameURL { URL(), frameOrigin.toString() };
72
73         [m_delegate.getAutoreleased() requestStorageSpace:mainFrameURL frameOrigin:frameURL quota:quota currentSize:currentSize spaceRequired:spaceRequired decisionHandler:decisionHandler.get()];
74     }
75
76     WeakObjCPtr<id <_WKWebsiteDataStoreDelegate> > m_delegate;
77     bool m_hasRequestStorageSpaceSelector { false };
78 };
79
80 @implementation WKWebsiteDataStore
81
82 + (WKWebsiteDataStore *)defaultDataStore
83 {
84     return wrapper(API::WebsiteDataStore::defaultDataStore());
85 }
86
87 + (WKWebsiteDataStore *)nonPersistentDataStore
88 {
89     return wrapper(API::WebsiteDataStore::createNonPersistentDataStore());
90 }
91
92 - (void)dealloc
93 {
94     _websiteDataStore->API::WebsiteDataStore::~WebsiteDataStore();
95
96     [super dealloc];
97 }
98
99 + (BOOL)supportsSecureCoding
100 {
101     return YES;
102 }
103
104 - (instancetype)initWithCoder:(NSCoder *)coder
105 {
106     if (!(self = [super init]))
107         return nil;
108
109     RetainPtr<WKWebsiteDataStore> dataStore;
110     if ([coder decodeBoolForKey:@"isDefaultDataStore"])
111         dataStore = [WKWebsiteDataStore defaultDataStore];
112     else
113         dataStore = [WKWebsiteDataStore nonPersistentDataStore];
114
115     [self release];
116
117     return dataStore.leakRef();
118 }
119
120 - (void)encodeWithCoder:(NSCoder *)coder
121 {
122     if (self == [WKWebsiteDataStore defaultDataStore]) {
123         [coder encodeBool:YES forKey:@"isDefaultDataStore"];
124         return;
125     }
126
127     ASSERT(!self.persistent);
128 }
129
130 - (BOOL)isPersistent
131 {
132     return _websiteDataStore->isPersistent();
133 }
134
135 + (NSSet *)allWebsiteDataTypes
136 {
137     static dispatch_once_t onceToken;
138     static NSSet *allWebsiteDataTypes;
139     dispatch_once(&onceToken, ^{
140         allWebsiteDataTypes = [[NSSet alloc] initWithArray:@[ WKWebsiteDataTypeDiskCache, WKWebsiteDataTypeFetchCache, WKWebsiteDataTypeMemoryCache, WKWebsiteDataTypeOfflineWebApplicationCache, WKWebsiteDataTypeCookies, WKWebsiteDataTypeSessionStorage, WKWebsiteDataTypeLocalStorage, WKWebsiteDataTypeIndexedDBDatabases, WKWebsiteDataTypeServiceWorkerRegistrations, WKWebsiteDataTypeWebSQLDatabases ]];
141     });
142
143     return allWebsiteDataTypes;
144 }
145
146 - (WKHTTPCookieStore *)httpCookieStore
147 {
148     return wrapper(_websiteDataStore->httpCookieStore());
149 }
150
151 static WallTime toSystemClockTime(NSDate *date)
152 {
153     ASSERT(date);
154     return WallTime::fromRawSeconds(date.timeIntervalSince1970);
155 }
156
157 - (void)fetchDataRecordsOfTypes:(NSSet *)dataTypes completionHandler:(void (^)(NSArray<WKWebsiteDataRecord *> *))completionHandler
158 {
159     [self _fetchDataRecordsOfTypes:dataTypes withOptions:0 completionHandler:completionHandler];
160 }
161
162 - (void)removeDataOfTypes:(NSSet *)dataTypes modifiedSince:(NSDate *)date completionHandler:(void (^)(void))completionHandler
163 {
164     auto completionHandlerCopy = makeBlockPtr(completionHandler);
165     _websiteDataStore->websiteDataStore().removeData(WebKit::toWebsiteDataTypes(dataTypes), toSystemClockTime(date ? date : [NSDate distantPast]), [completionHandlerCopy] {
166         completionHandlerCopy();
167     });
168 }
169
170 static Vector<WebKit::WebsiteDataRecord> toWebsiteDataRecords(NSArray *dataRecords)
171 {
172     Vector<WebKit::WebsiteDataRecord> result;
173
174     for (WKWebsiteDataRecord *dataRecord in dataRecords)
175         result.append(dataRecord->_websiteDataRecord->websiteDataRecord());
176
177     return result;
178 }
179
180 - (void)removeDataOfTypes:(NSSet *)dataTypes forDataRecords:(NSArray *)dataRecords completionHandler:(void (^)(void))completionHandler
181 {
182     auto completionHandlerCopy = makeBlockPtr(completionHandler);
183
184     _websiteDataStore->websiteDataStore().removeData(WebKit::toWebsiteDataTypes(dataTypes), toWebsiteDataRecords(dataRecords), [completionHandlerCopy] {
185         completionHandlerCopy();
186     });
187 }
188
189 #pragma mark WKObject protocol implementation
190
191 - (API::Object&)_apiObject
192 {
193     return *_websiteDataStore;
194 }
195
196 @end
197
198 @implementation WKWebsiteDataStore (WKPrivate)
199
200 + (NSSet<NSString *> *)_allWebsiteDataTypesIncludingPrivate
201 {
202     static dispatch_once_t onceToken;
203     static NSSet *allWebsiteDataTypes;
204     dispatch_once(&onceToken, ^ {
205         auto *privateTypes = @[_WKWebsiteDataTypeHSTSCache, _WKWebsiteDataTypeMediaKeys, _WKWebsiteDataTypeSearchFieldRecentSearches, _WKWebsiteDataTypeResourceLoadStatistics, _WKWebsiteDataTypeCredentials, _WKWebsiteDataTypeAdClickAttributions
206 #if !TARGET_OS_IPHONE
207         , _WKWebsiteDataTypePlugInData
208 #endif
209         ];
210
211         allWebsiteDataTypes = [[[self allWebsiteDataTypes] setByAddingObjectsFromArray:privateTypes] retain];
212     });
213
214     return allWebsiteDataTypes;
215 }
216
217 + (BOOL)_defaultDataStoreExists
218 {
219     return API::WebsiteDataStore::defaultDataStoreExists();
220 }
221
222 + (void)_deleteDefaultDataStoreForTesting
223 {
224     return API::WebsiteDataStore::deleteDefaultDataStoreForTesting();
225 }
226
227 - (instancetype)_initWithConfiguration:(_WKWebsiteDataStoreConfiguration *)configuration
228 {
229     if (!(self = [super init]))
230         return nil;
231
232     auto config = configuration.isPersistent ? API::WebsiteDataStore::defaultDataStoreConfiguration() : WebKit::WebsiteDataStoreConfiguration::create();
233
234     RELEASE_ASSERT(config->isPersistent() == configuration.isPersistent);
235
236     if (configuration.isPersistent) {
237         if (configuration._webStorageDirectory)
238             config->setLocalStorageDirectory(configuration._webStorageDirectory.path);
239         if (configuration._webSQLDatabaseDirectory)
240             config->setWebSQLDatabaseDirectory(configuration._webSQLDatabaseDirectory.path);
241         if (configuration._indexedDBDatabaseDirectory)
242             config->setIndexedDBDatabaseDirectory(configuration._indexedDBDatabaseDirectory.path);
243         if (configuration._cookieStorageFile)
244             config->setCookieStorageFile(configuration._cookieStorageFile.path);
245         if (configuration._resourceLoadStatisticsDirectory)
246             config->setResourceLoadStatisticsDirectory(configuration._resourceLoadStatisticsDirectory.path);
247         if (configuration._cacheStorageDirectory)
248             config->setCacheStorageDirectory(configuration._cacheStorageDirectory.path);
249         if (configuration._serviceWorkerRegistrationDirectory)
250             config->setServiceWorkerRegistrationDirectory(configuration._serviceWorkerRegistrationDirectory.path);
251         if (configuration.networkCacheDirectory)
252             config->setNetworkCacheDirectory(configuration.networkCacheDirectory.path);
253     } else {
254         RELEASE_ASSERT(!configuration._webStorageDirectory);
255         RELEASE_ASSERT(!configuration._webSQLDatabaseDirectory);
256         RELEASE_ASSERT(!configuration._indexedDBDatabaseDirectory);
257         RELEASE_ASSERT(!configuration._cookieStorageFile);
258         RELEASE_ASSERT(!configuration._resourceLoadStatisticsDirectory);
259         RELEASE_ASSERT(!configuration._cacheStorageDirectory);
260         RELEASE_ASSERT(!configuration._serviceWorkerRegistrationDirectory);
261         RELEASE_ASSERT(!configuration.networkCacheDirectory);
262     }
263
264     if (configuration.sourceApplicationBundleIdentifier)
265         config->setSourceApplicationBundleIdentifier(configuration.sourceApplicationBundleIdentifier);
266     if (configuration.sourceApplicationSecondaryIdentifier)
267         config->setSourceApplicationSecondaryIdentifier(configuration.sourceApplicationSecondaryIdentifier);
268     if (configuration.httpProxy)
269         config->setHTTPProxy(configuration.httpProxy);
270     if (configuration.httpsProxy)
271         config->setHTTPSProxy(configuration.httpsProxy);
272     config->setDeviceManagementRestrictionsEnabled(configuration.deviceManagementRestrictionsEnabled);
273     config->setAllLoadsBlockedByDeviceManagementRestrictionsForTesting(configuration.allLoadsBlockedByDeviceManagementRestrictionsForTesting);
274
275     auto sessionID = configuration.isPersistent ? PAL::SessionID::generatePersistentSessionID() : PAL::SessionID::generateEphemeralSessionID();
276
277     API::Object::constructInWrapper<API::WebsiteDataStore>(self, WTFMove(config), sessionID);
278
279     return self;
280 }
281
282 - (void)_fetchDataRecordsOfTypes:(NSSet<NSString *> *)dataTypes withOptions:(_WKWebsiteDataStoreFetchOptions)options completionHandler:(void (^)(NSArray<WKWebsiteDataRecord *> *))completionHandler
283 {
284     auto completionHandlerCopy = makeBlockPtr(completionHandler);
285
286     OptionSet<WebKit::WebsiteDataFetchOption> fetchOptions;
287     if (options & _WKWebsiteDataStoreFetchOptionComputeSizes)
288         fetchOptions.add(WebKit::WebsiteDataFetchOption::ComputeSizes);
289
290     _websiteDataStore->websiteDataStore().fetchData(WebKit::toWebsiteDataTypes(dataTypes), fetchOptions, [completionHandlerCopy = WTFMove(completionHandlerCopy)](auto websiteDataRecords) {
291         Vector<RefPtr<API::Object>> elements;
292         elements.reserveInitialCapacity(websiteDataRecords.size());
293
294         for (auto& websiteDataRecord : websiteDataRecords)
295             elements.uncheckedAppend(API::WebsiteDataRecord::create(WTFMove(websiteDataRecord)));
296
297         completionHandlerCopy(wrapper(API::Array::create(WTFMove(elements))));
298     });
299 }
300
301 - (BOOL)_resourceLoadStatisticsEnabled
302 {
303     return _websiteDataStore->websiteDataStore().resourceLoadStatisticsEnabled();
304 }
305
306 - (void)_setResourceLoadStatisticsEnabled:(BOOL)enabled
307 {
308     _websiteDataStore->websiteDataStore().setResourceLoadStatisticsEnabled(enabled);
309 }
310
311 - (BOOL)_resourceLoadStatisticsDebugMode
312 {
313 #if ENABLE(RESOURCE_LOAD_STATISTICS)
314     return _websiteDataStore->websiteDataStore().resourceLoadStatisticsDebugMode();
315 #else
316     return NO;
317 #endif
318 }
319
320 - (void)_setResourceLoadStatisticsDebugMode:(BOOL)enabled
321 {
322 #if ENABLE(RESOURCE_LOAD_STATISTICS)
323     _websiteDataStore->websiteDataStore().setResourceLoadStatisticsDebugMode(enabled);
324 #else
325     UNUSED_PARAM(enabled);
326 #endif
327 }
328
329 - (NSUInteger)_perOriginStorageQuota
330 {
331     return _websiteDataStore->websiteDataStore().perOriginStorageQuota();
332 }
333
334 - (void)_setPerOriginStorageQuota:(NSUInteger)size
335 {
336     _websiteDataStore->websiteDataStore().setPerOriginStorageQuota(size);
337 }
338
339 - (NSString *)_cacheStorageDirectory
340 {
341     return _websiteDataStore->websiteDataStore().cacheStorageDirectory();
342 }
343
344 - (void)_setCacheStorageDirectory:(NSString *)directory
345 {
346     _websiteDataStore->websiteDataStore().setCacheStorageDirectory(directory);
347 }
348
349 - (NSString *)_serviceWorkerRegistrationDirectory
350 {
351     return _websiteDataStore->websiteDataStore().serviceWorkerRegistrationDirectory();
352 }
353
354 - (void)_setServiceWorkerRegistrationDirectory:(NSString *)directory
355 {
356     _websiteDataStore->websiteDataStore().setServiceWorkerRegistrationDirectory(directory);
357 }
358
359 - (void)_setBoundInterfaceIdentifier:(NSString *)identifier
360 {
361     _websiteDataStore->websiteDataStore().setBoundInterfaceIdentifier(identifier);
362 }
363
364 - (NSString *)_boundInterfaceIdentifier
365 {
366     return _websiteDataStore->websiteDataStore().boundInterfaceIdentifier();
367 }
368
369 - (void)_setAllowsCellularAccess:(BOOL)allows
370 {
371     _websiteDataStore->websiteDataStore().setAllowsCellularAccess(allows ? WebKit::AllowsCellularAccess::Yes : WebKit::AllowsCellularAccess::No);
372 }
373
374 - (BOOL)_allowsCellularAccess
375 {
376     return _websiteDataStore->websiteDataStore().allowsCellularAccess() == WebKit::AllowsCellularAccess::Yes;
377 }
378
379 - (void)_setProxyConfiguration:(NSDictionary *)configuration
380 {
381     _websiteDataStore->websiteDataStore().setProxyConfiguration((__bridge CFDictionaryRef)configuration);
382 }
383
384 - (NSString *)_sourceApplicationBundleIdentifier
385 {
386     return _websiteDataStore->websiteDataStore().sourceApplicationBundleIdentifier();
387 }
388
389 - (void)_setSourceApplicationBundleIdentifier:(NSString *)identifier
390 {
391     if (!_websiteDataStore->websiteDataStore().setSourceApplicationBundleIdentifier(identifier))
392         [NSException raise:NSGenericException format:@"_setSourceApplicationBundleIdentifier cannot be called after networking has begun"];
393 }
394
395 - (NSString *)_sourceApplicationSecondaryIdentifier
396 {
397     return _websiteDataStore->websiteDataStore().sourceApplicationSecondaryIdentifier();
398 }
399
400 - (void)_setSourceApplicationSecondaryIdentifier:(NSString *)identifier
401 {
402     if (!_websiteDataStore->websiteDataStore().setSourceApplicationSecondaryIdentifier(identifier))
403         [NSException raise:NSGenericException format:@"_setSourceApplicationSecondaryIdentifier cannot be called after networking has begun"];
404 }
405
406 - (void)_setAllowsTLSFallback:(BOOL)allows
407 {
408     if (!_websiteDataStore->websiteDataStore().setAllowsTLSFallback(allows))
409         [NSException raise:NSGenericException format:@"_setAllowsTLSFallback cannot be called after networking has begun"];
410 }
411
412 - (BOOL)_allowsTLSFallback
413 {
414     return _websiteDataStore->websiteDataStore().allowsTLSFallback();
415 }
416
417 - (NSDictionary *)_proxyConfiguration
418 {
419     return (__bridge NSDictionary *)_websiteDataStore->websiteDataStore().proxyConfiguration();
420 }
421
422 - (NSURL *)_indexedDBDatabaseDirectory
423 {
424     return [NSURL fileURLWithPath:_websiteDataStore->indexedDBDatabaseDirectory() isDirectory:YES];
425 }
426
427 - (void)_resourceLoadStatisticsSetShouldSubmitTelemetry:(BOOL)value
428 {
429 #if ENABLE(RESOURCE_LOAD_STATISTICS)
430     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
431     if (!store)
432         return;
433
434     store->setShouldSubmitTelemetry(value);
435 #endif
436 }
437
438 - (void)_setResourceLoadStatisticsTestingCallback:(void (^)(WKWebsiteDataStore *, NSString *))callback
439 {
440 #if ENABLE(RESOURCE_LOAD_STATISTICS)
441     if (!_websiteDataStore->isPersistent())
442         return;
443
444     if (callback) {
445         _websiteDataStore->websiteDataStore().enableResourceLoadStatisticsAndSetTestingCallback([callback = makeBlockPtr(callback), self](const String& event) {
446             callback(self, (NSString *)event);
447         });
448         return;
449     }
450
451     _websiteDataStore->websiteDataStore().setStatisticsTestingCallback(nullptr);
452 #endif
453 }
454
455 + (void)_allowWebsiteDataRecordsForAllOrigins
456 {
457     WebKit::WebsiteDataStore::allowWebsiteDataRecordsForAllOrigins();
458 }
459
460 - (void)_getAllStorageAccessEntriesFor:(WKWebView *)webView completionHandler:(void (^)(NSArray<NSString *> *domains))completionHandler
461 {
462     if (!webView) {
463         completionHandler({ });
464         return;
465     }
466
467     auto* webPageProxy = [webView _page];
468     if (!webPageProxy) {
469         completionHandler({ });
470         return;
471     }
472
473 #if ENABLE(RESOURCE_LOAD_STATISTICS)
474     _websiteDataStore->websiteDataStore().getAllStorageAccessEntries(webPageProxy->pageID(), [completionHandler = makeBlockPtr(completionHandler)](auto domains) {
475         Vector<RefPtr<API::Object>> apiDomains;
476         apiDomains.reserveInitialCapacity(domains.size());
477         for (auto& domain : domains)
478             apiDomains.uncheckedAppend(API::String::create(domain));
479         completionHandler(wrapper(API::Array::create(WTFMove(apiDomains))));
480     });
481 #else
482     completionHandler({ });
483 #endif
484 }
485
486 - (void)_scheduleCookieBlockingUpdate:(void (^)(void))completionHandler
487 {
488 #if ENABLE(RESOURCE_LOAD_STATISTICS)
489     _websiteDataStore->websiteDataStore().scheduleCookieBlockingUpdate([completionHandler = makeBlockPtr(completionHandler)]() {
490         completionHandler();
491     });
492 #else
493     completionHandler();
494 #endif
495 }
496
497 - (void)_setPrevalentDomain:(NSURL *)domain completionHandler:(void (^)(void))completionHandler
498 {
499 #if ENABLE(RESOURCE_LOAD_STATISTICS)
500     _websiteDataStore->websiteDataStore().setPrevalentResource(URL(domain), [completionHandler = makeBlockPtr(completionHandler)]() {
501         completionHandler();
502     });
503 #else
504     completionHandler();
505 #endif
506 }
507
508 - (void)_getIsPrevalentDomain:(NSURL *)domain completionHandler:(void (^)(BOOL))completionHandler
509 {
510 #if ENABLE(RESOURCE_LOAD_STATISTICS)
511     _websiteDataStore->websiteDataStore().isPrevalentResource(URL(domain), [completionHandler = makeBlockPtr(completionHandler)](bool enabled) {
512         completionHandler(enabled);
513     });
514 #else
515     completionHandler(NO);
516 #endif
517 }
518
519 - (void)_clearPrevalentDomain:(NSURL *)domain completionHandler:(void (^)(void))completionHandler
520 {
521 #if ENABLE(RESOURCE_LOAD_STATISTICS)
522     _websiteDataStore->websiteDataStore().clearPrevalentResource(URL(domain), [completionHandler = makeBlockPtr(completionHandler)]() {
523         completionHandler();
524     });
525 #else
526     completionHandler();
527 #endif
528 }
529
530 - (void)_processStatisticsAndDataRecords:(void (^)(void))completionHandler
531 {
532 #if ENABLE(RESOURCE_LOAD_STATISTICS)
533     _websiteDataStore->websiteDataStore().scheduleStatisticsAndDataRecordsProcessing([completionHandler = makeBlockPtr(completionHandler)]() {
534         completionHandler();
535     });
536 #else
537     completionHandler();
538 #endif
539 }
540
541 - (bool)_hasRegisteredServiceWorker
542 {
543     return WebKit::ServiceWorkerProcessProxy::hasRegisteredServiceWorkers(_websiteDataStore->websiteDataStore().serviceWorkerRegistrationDirectory());
544 }
545
546 - (id <_WKWebsiteDataStoreDelegate>)_delegate
547 {
548     return _delegate.get();
549 }
550
551 - (void)set_delegate:(id <_WKWebsiteDataStoreDelegate>)delegate
552 {
553     _delegate = delegate;
554     _websiteDataStore->websiteDataStore().setClient(makeUniqueRef<WebsiteDataStoreClient>(delegate));
555 }
556
557 @end