Remove std::chrono completely
[WebKit-https.git] / Source / WebKit / UIProcess / API / Cocoa / WKWebsiteDataStore.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 "WKWebsiteDataStoreInternal.h"
28
29 #if WK_API_ENABLED
30
31 #import "WKHTTPCookieStoreInternal.h"
32 #import "WKNSArray.h"
33 #import "WKWebsiteDataRecordInternal.h"
34 #import "WebResourceLoadStatisticsStore.h"
35 #import "WebResourceLoadStatisticsTelemetry.h"
36 #import "WebsiteDataFetchOption.h"
37 #import "_WKWebsiteDataStoreConfiguration.h"
38 #import <WebCore/URL.h>
39 #import <wtf/BlockPtr.h>
40
41 using namespace WebCore;
42
43 @implementation WKWebsiteDataStore
44
45 + (WKWebsiteDataStore *)defaultDataStore
46 {
47     return WebKit::wrapper(API::WebsiteDataStore::defaultDataStore().get());
48 }
49
50 + (WKWebsiteDataStore *)nonPersistentDataStore
51 {
52     return [WebKit::wrapper(API::WebsiteDataStore::createNonPersistentDataStore().leakRef()) autorelease];
53 }
54
55 - (void)dealloc
56 {
57     _websiteDataStore->API::WebsiteDataStore::~WebsiteDataStore();
58
59     [super dealloc];
60 }
61
62 - (instancetype)initWithCoder:(NSCoder *)coder
63 {
64     if (!(self = [super init]))
65         return nil;
66
67     RetainPtr<WKWebsiteDataStore> dataStore;
68     if ([coder decodeBoolForKey:@"isDefaultDataStore"])
69         dataStore = [WKWebsiteDataStore defaultDataStore];
70     else
71         dataStore = [WKWebsiteDataStore nonPersistentDataStore];
72
73     [self release];
74
75     return dataStore.leakRef();
76 }
77
78 - (void)encodeWithCoder:(NSCoder *)coder
79 {
80     if (self == [WKWebsiteDataStore defaultDataStore]) {
81         [coder encodeBool:YES forKey:@"isDefaultDataStore"];
82         return;
83     }
84
85     ASSERT(!self.persistent);
86 }
87
88 - (BOOL)isPersistent
89 {
90     return _websiteDataStore->isPersistent();
91 }
92
93 + (NSSet *)allWebsiteDataTypes
94 {
95     static dispatch_once_t onceToken;
96     static NSSet *allWebsiteDataTypes;
97     dispatch_once(&onceToken, ^{
98         allWebsiteDataTypes = [[NSSet alloc] initWithArray:@[ WKWebsiteDataTypeDiskCache, WKWebsiteDataTypeFetchCache, WKWebsiteDataTypeMemoryCache, WKWebsiteDataTypeOfflineWebApplicationCache, WKWebsiteDataTypeCookies, WKWebsiteDataTypeSessionStorage, WKWebsiteDataTypeLocalStorage, WKWebsiteDataTypeIndexedDBDatabases, WKWebsiteDataTypeServiceWorkerRegistrations, WKWebsiteDataTypeWebSQLDatabases ]];
99     });
100
101     return allWebsiteDataTypes;
102 }
103
104 - (WKHTTPCookieStore *)httpCookieStore
105 {
106     return WebKit::wrapper(_websiteDataStore->httpCookieStore());
107 }
108
109 static WallTime toSystemClockTime(NSDate *date)
110 {
111     ASSERT(date);
112     return WallTime::fromRawSeconds(date.timeIntervalSince1970);
113 }
114
115 - (void)fetchDataRecordsOfTypes:(NSSet *)dataTypes completionHandler:(void (^)(NSArray<WKWebsiteDataRecord *> *))completionHandler
116 {
117     [self _fetchDataRecordsOfTypes:dataTypes withOptions:0 completionHandler:completionHandler];
118 }
119
120 - (void)removeDataOfTypes:(NSSet *)dataTypes modifiedSince:(NSDate *)date completionHandler:(void (^)(void))completionHandler
121 {
122     auto completionHandlerCopy = makeBlockPtr(completionHandler);
123     _websiteDataStore->websiteDataStore().removeData(WebKit::toWebsiteDataTypes(dataTypes), toSystemClockTime(date ? date : [NSDate distantPast]), [completionHandlerCopy] {
124         completionHandlerCopy();
125     });
126 }
127
128 static Vector<WebKit::WebsiteDataRecord> toWebsiteDataRecords(NSArray *dataRecords)
129 {
130     Vector<WebKit::WebsiteDataRecord> result;
131
132     for (WKWebsiteDataRecord *dataRecord in dataRecords)
133         result.append(dataRecord->_websiteDataRecord->websiteDataRecord());
134
135     return result;
136 }
137
138 - (void)removeDataOfTypes:(NSSet *)dataTypes forDataRecords:(NSArray *)dataRecords completionHandler:(void (^)(void))completionHandler
139 {
140     auto completionHandlerCopy = makeBlockPtr(completionHandler);
141
142     _websiteDataStore->websiteDataStore().removeData(WebKit::toWebsiteDataTypes(dataTypes), toWebsiteDataRecords(dataRecords), [completionHandlerCopy] {
143         completionHandlerCopy();
144     });
145 }
146
147 #pragma mark WKObject protocol implementation
148
149 - (API::Object&)_apiObject
150 {
151     return *_websiteDataStore;
152 }
153
154 @end
155
156 @implementation WKWebsiteDataStore (WKPrivate)
157
158 + (NSSet<NSString *> *)_allWebsiteDataTypesIncludingPrivate
159 {
160     static dispatch_once_t onceToken;
161     static NSSet *allWebsiteDataTypes;
162     dispatch_once(&onceToken, ^ {
163         auto *privateTypes = @[_WKWebsiteDataTypeHSTSCache, _WKWebsiteDataTypeMediaKeys, _WKWebsiteDataTypeSearchFieldRecentSearches, _WKWebsiteDataTypeResourceLoadStatistics, _WKWebsiteDataTypeCredentials
164 #if !TARGET_OS_IPHONE
165         , _WKWebsiteDataTypePlugInData
166 #endif
167         ];
168
169         allWebsiteDataTypes = [[[self allWebsiteDataTypes] setByAddingObjectsFromArray:privateTypes] retain];
170     });
171
172     return allWebsiteDataTypes;
173 }
174
175 + (BOOL)_defaultDataStoreExists
176 {
177     return API::WebsiteDataStore::defaultDataStoreExists();
178 }
179
180 - (instancetype)_initWithConfiguration:(_WKWebsiteDataStoreConfiguration *)configuration
181 {
182     if (!(self = [super init]))
183         return nil;
184
185     auto config = API::WebsiteDataStore::defaultDataStoreConfiguration();
186
187     if (configuration._webStorageDirectory)
188         config.localStorageDirectory = configuration._webStorageDirectory.path;
189     if (configuration._webSQLDatabaseDirectory)
190         config.webSQLDatabaseDirectory = configuration._webSQLDatabaseDirectory.path;
191     if (configuration._indexedDBDatabaseDirectory)
192         config.indexedDBDatabaseDirectory = configuration._indexedDBDatabaseDirectory.path;
193     if (configuration._cookieStorageFile)
194         config.cookieStorageFile = configuration._cookieStorageFile.path;
195     if (configuration._resourceLoadStatisticsDirectory)
196         config.resourceLoadStatisticsDirectory = configuration._resourceLoadStatisticsDirectory.path;
197
198     API::Object::constructInWrapper<API::WebsiteDataStore>(self, config, PAL::SessionID::generatePersistentSessionID());
199
200     return self;
201 }
202
203 - (void)_fetchDataRecordsOfTypes:(NSSet<NSString *> *)dataTypes withOptions:(_WKWebsiteDataStoreFetchOptions)options completionHandler:(void (^)(NSArray<WKWebsiteDataRecord *> *))completionHandler
204 {
205     auto completionHandlerCopy = makeBlockPtr(completionHandler);
206
207     OptionSet<WebKit::WebsiteDataFetchOption> fetchOptions;
208     if (options & _WKWebsiteDataStoreFetchOptionComputeSizes)
209         fetchOptions |= WebKit::WebsiteDataFetchOption::ComputeSizes;
210
211     _websiteDataStore->websiteDataStore().fetchData(WebKit::toWebsiteDataTypes(dataTypes), fetchOptions, [completionHandlerCopy = WTFMove(completionHandlerCopy)](auto websiteDataRecords) {
212         Vector<RefPtr<API::Object>> elements;
213         elements.reserveInitialCapacity(websiteDataRecords.size());
214
215         for (auto& websiteDataRecord : websiteDataRecords)
216             elements.uncheckedAppend(API::WebsiteDataRecord::create(WTFMove(websiteDataRecord)));
217
218         completionHandlerCopy(wrapper(API::Array::create(WTFMove(elements))));
219     });
220 }
221
222 - (BOOL)_resourceLoadStatisticsEnabled
223 {
224     return _websiteDataStore->websiteDataStore().resourceLoadStatisticsEnabled();
225 }
226
227 - (void)_setResourceLoadStatisticsEnabled:(BOOL)enabled
228 {
229     _websiteDataStore->websiteDataStore().setResourceLoadStatisticsEnabled(enabled);
230 }
231
232 - (NSUInteger)_cacheStoragePerOriginQuota
233 {
234     return _websiteDataStore->websiteDataStore().cacheStoragePerOriginQuota();
235 }
236
237 - (void)_setCacheStoragePerOriginQuota:(NSUInteger)size
238 {
239     _websiteDataStore->websiteDataStore().setCacheStoragePerOriginQuota(size);
240 }
241
242 - (NSString *)_cacheStorageDirectory
243 {
244     return _websiteDataStore->websiteDataStore().cacheStorageDirectory();
245 }
246
247 - (void)_setCacheStorageDirectory:(NSString *)directory
248 {
249     _websiteDataStore->websiteDataStore().setCacheStorageDirectory(directory);
250 }
251
252 - (void)_setBoundInterfaceIdentifier:(NSString *)identifier
253 {
254     _websiteDataStore->websiteDataStore().setBoundInterfaceIdentifier(identifier);
255 }
256
257 - (NSString *)_boundInterfaceIdentifier
258 {
259     return _websiteDataStore->websiteDataStore().boundInterfaceIdentifier();
260 }
261
262 - (void)_setAllowsCellularAccess:(BOOL)allows
263 {
264     _websiteDataStore->websiteDataStore().setAllowsCellularAccess(allows ? WebKit::AllowsCellularAccess::Yes : WebKit::AllowsCellularAccess::No);
265 }
266
267 - (BOOL)_allowsCellularAccess
268 {
269     return _websiteDataStore->websiteDataStore().allowsCellularAccess() == WebKit::AllowsCellularAccess::Yes;
270 }
271
272 - (void)_resourceLoadStatisticsSetLastSeen:(double)seconds forHost:(NSString *)host
273 {
274     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
275     if (!store)
276         return;
277     
278     store->setLastSeen(URL(URL(), host), Seconds { seconds });
279 }
280
281 - (void)_resourceLoadStatisticsSetIsPrevalentResource:(BOOL)value forHost:(NSString *)host
282 {
283     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
284     if (!store)
285         return;
286
287     if (value)
288         store->setPrevalentResource(URL(URL(), host));
289     else
290         store->clearPrevalentResource(URL(URL(), host));
291 }
292
293 - (void)_resourceLoadStatisticsIsPrevalentResource:(NSString *)host completionHandler:(void (^)(BOOL))completionHandler
294 {
295     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
296     if (!store) {
297         completionHandler(NO);
298         return;
299     }
300
301     auto completionHandlerCopy = makeBlockPtr(completionHandler);
302     store->isPrevalentResource(URL(URL(), host), [completionHandlerCopy](bool isPrevalentResource) {
303         completionHandlerCopy(isPrevalentResource);
304     });
305 }
306
307 - (void)_resourceLoadStatisticsIsRegisteredAsSubFrameUnder:(NSString *)subFrameHost topFrameHost:(NSString *)topFrameHost completionHandler:(void (^)(BOOL))completionHandler
308 {
309     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
310     if (!store) {
311         completionHandler(NO);
312         return;
313     }
314     
315     auto completionHandlerCopy = makeBlockPtr(completionHandler);
316     store->isRegisteredAsSubFrameUnder(URL(URL(), subFrameHost), URL(URL(), topFrameHost), [completionHandlerCopy](bool isRegisteredAsSubFrameUnder) {
317         completionHandlerCopy(isRegisteredAsSubFrameUnder);
318     });
319 }
320
321 - (void)_resourceLoadStatisticsIsRegisteredAsRedirectingTo:(NSString *)hostRedirectedFrom hostRedirectedTo:(NSString *)hostRedirectedTo completionHandler:(void (^)(BOOL))completionHandler
322 {
323     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
324     if (!store) {
325         completionHandler(NO);
326         return;
327     }
328     
329     auto completionHandlerCopy = makeBlockPtr(completionHandler);
330     store->isRegisteredAsRedirectingTo(URL(URL(), hostRedirectedFrom), URL(URL(), hostRedirectedTo), [completionHandlerCopy](bool isRegisteredAsRedirectingTo) {
331         completionHandlerCopy(isRegisteredAsRedirectingTo);
332     });
333 }
334
335 - (void)_resourceLoadStatisticsSetHadUserInteraction:(BOOL)value forHost:(NSString *)host
336 {
337     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
338     if (!store)
339         return;
340
341     if (value)
342         store->logUserInteraction(URL(URL(), host));
343     else
344         store->clearUserInteraction(URL(URL(), host));
345 }
346
347 - (void)_resourceLoadStatisticsSetHasHadNonRecentUserInteractionForHost:(NSString *)host
348 {
349     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
350     if (!store)
351         return;
352     
353     store->logNonRecentUserInteraction(URL(URL(), host));
354 }
355
356 - (void)_resourceLoadStatisticsHadUserInteraction:(NSString *)host completionHandler:(void (^)(BOOL))completionHandler
357 {
358     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
359     if (!store) {
360         completionHandler(NO);
361         return;
362     }
363
364     auto completionHandlerCopy = makeBlockPtr(completionHandler);
365     store->hasHadUserInteraction(URL(URL(), host), [completionHandlerCopy](bool hasHadUserInteraction) {
366         completionHandlerCopy(hasHadUserInteraction);
367     });
368 }
369
370 - (void)_resourceLoadStatisticsSetIsGrandfathered:(BOOL)value forHost:(NSString *)host
371 {
372     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
373     if (!store)
374         return;
375
376     store->setGrandfathered(URL(URL(), host), value);
377 }
378
379 - (void)_resourceLoadStatisticsIsGrandfathered:(NSString *)host completionHandler:(void (^)(BOOL))completionHandler
380 {
381     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
382     if (!store) {
383         completionHandler(NO);
384         return;
385     }
386
387     auto completionHandlerCopy = makeBlockPtr(completionHandler);
388     store->isGrandfathered(URL(URL(), host), [completionHandlerCopy](bool isGrandfathered) {
389         completionHandlerCopy(isGrandfathered);
390     });
391 }
392
393 - (void)_resourceLoadStatisticsSetSubframeUnderTopFrameOrigin:(NSString *)topFrameHostName forHost:(NSString *)host
394 {
395     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
396     if (!store)
397         return;
398
399     store->setSubframeUnderTopFrameOrigin(URL(URL(), host), URL(URL(), topFrameHostName));
400 }
401
402 - (void)_resourceLoadStatisticsSetSubresourceUnderTopFrameOrigin:(NSString *)topFrameHostName forHost:(NSString *)host
403 {
404     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
405     if (!store)
406         return;
407
408     store->setSubresourceUnderTopFrameOrigin(URL(URL(), host), URL(URL(), topFrameHostName));
409 }
410
411 - (void)_resourceLoadStatisticsSetSubresourceUniqueRedirectTo:(NSString *)hostNameRedirectedTo forHost:(NSString *)host
412 {
413     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
414     if (!store)
415         return;
416
417     store->setSubresourceUniqueRedirectTo(URL(URL(), host), URL(URL(), hostNameRedirectedTo));
418 }
419
420 - (void)_resourceLoadStatisticsSetTimeToLiveUserInteraction:(double)seconds
421 {
422     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
423     if (!store)
424         return;
425
426     store->setTimeToLiveUserInteraction(Seconds { seconds });
427 }
428
429 - (void)_resourceLoadStatisticsSetTimeToLiveCookiePartitionFree:(double)seconds
430 {
431     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
432     if (!store)
433         return;
434
435     store->setTimeToLiveCookiePartitionFree(Seconds { seconds });
436 }
437
438 - (void)_resourceLoadStatisticsSetMinimumTimeBetweenDataRecordsRemoval:(double)seconds
439 {
440     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
441     if (!store)
442         return;
443
444     store->setMinimumTimeBetweenDataRecordsRemoval(Seconds { seconds });
445 }
446
447 - (void)_resourceLoadStatisticsSetGrandfatheringTime:(double)seconds
448 {
449     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
450     if (!store)
451         return;
452
453     store->setGrandfatheringTime(Seconds {seconds });
454 }
455
456 - (void)_resourceLoadStatisticsSetMaxStatisticsEntries:(size_t)entries
457 {
458     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
459     if (!store)
460         return;
461
462     store->setMaxStatisticsEntries(entries);
463 }
464
465 - (void)_resourceLoadStatisticsSetPruneEntriesDownTo:(size_t)entries
466 {
467     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
468     if (!store)
469         return;
470
471     store->setPruneEntriesDownTo(entries);
472 }
473
474 - (void)_resourceLoadStatisticsProcessStatisticsAndDataRecords
475 {
476     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
477     if (!store)
478         return;
479
480     store->scheduleStatisticsAndDataRecordsProcessing();
481 }
482
483 - (void)_resourceLoadStatisticsUpdateCookiePartitioning
484 {
485     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
486     if (!store)
487         return;
488
489     store->scheduleCookiePartitioningUpdate();
490 }
491
492 - (void)_resourceLoadStatisticsSetShouldPartitionCookies:(BOOL)value forHost:(NSString *)host
493 {
494     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
495     if (!store)
496         return;
497
498     if (value)
499         store->scheduleCookiePartitioningUpdateForDomains({ host }, { }, { }, WebKit::ShouldClearFirst::No);
500     else
501         store->scheduleClearPartitioningStateForDomains({ host });
502 }
503
504 - (void)_resourceLoadStatisticsSubmitTelemetry
505 {
506     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
507     if (!store)
508         return;
509
510     store->submitTelemetry();
511 }
512
513 - (void)_resourceLoadStatisticsSetNotifyPagesWhenDataRecordsWereScanned:(BOOL)value
514 {
515     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
516     if (!store)
517         return;
518
519     store->setNotifyPagesWhenDataRecordsWereScanned(value);
520 }
521
522 - (void)_resourceLoadStatisticsSetShouldClassifyResourcesBeforeDataRecordsRemoval:(BOOL)value
523 {
524     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
525     if (!store)
526         return;
527
528     store->setShouldClassifyResourcesBeforeDataRecordsRemoval(value);
529 }
530
531 - (void)_resourceLoadStatisticsSetNotifyPagesWhenTelemetryWasCaptured:(BOOL)value
532 {
533     WebKit::WebResourceLoadStatisticsTelemetry::setNotifyPagesWhenTelemetryWasCaptured(value);
534 }
535
536 - (void)_resourceLoadStatisticsSetShouldSubmitTelemetry:(BOOL)value
537 {
538     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
539     if (!store)
540         return;
541
542     store->setShouldSubmitTelemetry(value);
543 }
544
545 - (void)_resourceLoadStatisticsClearInMemoryAndPersistentStore
546 {
547     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
548     if (!store)
549         return;
550
551     store->scheduleClearInMemoryAndPersistent(WebKit::WebResourceLoadStatisticsStore::ShouldGrandfather::Yes);
552 }
553
554 - (void)_resourceLoadStatisticsClearInMemoryAndPersistentStoreModifiedSinceHours:(unsigned)hours
555 {
556     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
557     if (!store)
558         return;
559
560     store->scheduleClearInMemoryAndPersistent(WallTime::now() - Seconds::fromHours(hours), WebKit::WebResourceLoadStatisticsStore::ShouldGrandfather::Yes);
561 }
562
563 - (void)_resourceLoadStatisticsResetToConsistentState
564 {
565     WebKit::WebResourceLoadStatisticsTelemetry::setNotifyPagesWhenTelemetryWasCaptured(false);
566
567     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
568     if (!store)
569         return;
570
571     store->resetParametersToDefaultValues();
572     store->scheduleClearInMemory();
573 }
574
575 - (void)_setResourceLoadStatisticsTestingCallback:(void (^)(WKWebsiteDataStore *, NSString *))callback
576 {
577     if (callback) {
578         _websiteDataStore->websiteDataStore().enableResourceLoadStatisticsAndSetTestingCallback([callback = makeBlockPtr(callback), self](const String& event) {
579             callback(self, (NSString *)event);
580         });
581         return;
582     }
583
584     auto* store = _websiteDataStore->websiteDataStore().resourceLoadStatistics();
585     if (!store)
586         return;
587
588     store->setStatisticsTestingCallback(nullptr);
589 }
590
591 + (void)_allowWebsiteDataRecordsForAllOrigins
592 {
593     WebKit::WebsiteDataStore::allowWebsiteDataRecordsForAllOrigins();
594 }
595
596 @end
597
598 #endif // WK_API_ENABLED