- Revision
- 246500
- Author
- [email protected]
- Date
- 2019-06-17 10:41:39 -0700 (Mon, 17 Jun 2019)
Log Message
Ensure ITP state is relayed to Network Process on restart
https://bugs.webkit.org/show_bug.cgi?id=198797
<rdar://problem/51646944>
Reviewed by Youenn Fablet.
Source/WebKit:
Now that the ITP state is maintained in the Network Process, we have to make sure that we update
that process with current ITP state if the Network Process crashes and is relaunched. This wasn't a
problem in earlier releases because we tracked all ITP state in the UIProcess.
This patch does the following:
1. Add a new method to WKWebsiteDataStore to allow us to trigger statistics processing, which has the
side effect of syncing ITP state persistently so that it will be available after bouncing the process.
2. Adds a new test that sets a tracking domain, bounces the process, and confirms the state is still
consistent.
Tested by TestWebKitAPI.
* NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp:
(WebKit::ResourceLoadStatisticsStore::processStatisticsAndDataRecords):
* UIProcess/API/Cocoa/WKWebsiteDataStore.mm:
(-[WKWebsiteDataStore _clearPrevalentDomain:completionHandler:]):
(-[WKWebsiteDataStore _processStatisticsAndDataRecords:]):
* UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h:
* UIProcess/WebProcessPool.cpp:
(WebKit::WebProcessPool::ensureNetworkProcess):
(WebKit::WebProcessPool::setResourceLoadStatisticsEnabled):
* UIProcess/WebProcessPool.h:
* UIProcess/WebsiteData/WebsiteDataStore.cpp:
(WebKit::WebsiteDataStore::setResourceLoadStatisticsEnabled):
Tools:
* TestWebKitAPI/Tests/WebKitCocoa/ResourceLoadStatistics.mm:
(cleanupITPDatabase): Added.
(TEST:EnableDisableITP): Update to use cleanup method.
(TEST:NetworkProcessRestart): Added.
Modified Paths
Diff
Modified: trunk/Source/WebKit/ChangeLog (246499 => 246500)
--- trunk/Source/WebKit/ChangeLog 2019-06-17 17:28:43 UTC (rev 246499)
+++ trunk/Source/WebKit/ChangeLog 2019-06-17 17:41:39 UTC (rev 246500)
@@ -1,3 +1,36 @@
+2019-06-17 Brent Fulgham <[email protected]>
+
+ Ensure ITP state is relayed to Network Process on restart
+ https://bugs.webkit.org/show_bug.cgi?id=198797
+ <rdar://problem/51646944>
+
+ Reviewed by Youenn Fablet.
+
+ Now that the ITP state is maintained in the Network Process, we have to make sure that we update
+ that process with current ITP state if the Network Process crashes and is relaunched. This wasn't a
+ problem in earlier releases because we tracked all ITP state in the UIProcess.
+
+ This patch does the following:
+ 1. Add a new method to WKWebsiteDataStore to allow us to trigger statistics processing, which has the
+ side effect of syncing ITP state persistently so that it will be available after bouncing the process.
+ 2. Adds a new test that sets a tracking domain, bounces the process, and confirms the state is still
+ consistent.
+
+ Tested by TestWebKitAPI.
+
+ * NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp:
+ (WebKit::ResourceLoadStatisticsStore::processStatisticsAndDataRecords):
+ * UIProcess/API/Cocoa/WKWebsiteDataStore.mm:
+ (-[WKWebsiteDataStore _clearPrevalentDomain:completionHandler:]):
+ (-[WKWebsiteDataStore _processStatisticsAndDataRecords:]):
+ * UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h:
+ * UIProcess/WebProcessPool.cpp:
+ (WebKit::WebProcessPool::ensureNetworkProcess):
+ (WebKit::WebProcessPool::setResourceLoadStatisticsEnabled):
+ * UIProcess/WebProcessPool.h:
+ * UIProcess/WebsiteData/WebsiteDataStore.cpp:
+ (WebKit::WebsiteDataStore::setResourceLoadStatisticsEnabled):
+
2019-06-17 Ludovico de Nittis <[email protected]>
[GTK] Stop accessing GdkEvent fields when possible
Modified: trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp (246499 => 246500)
--- trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp 2019-06-17 17:28:43 UTC (rev 246499)
+++ trunk/Source/WebKit/NetworkProcess/Classifier/ResourceLoadStatisticsStore.cpp 2019-06-17 17:41:39 UTC (rev 246500)
@@ -246,6 +246,8 @@
pruneStatisticsIfNeeded();
syncStorageIfNeeded();
+ logTestingEvent("Storage Synced"_s);
+
if (!m_parameters.shouldNotifyPagesWhenDataRecordsWereScanned)
return;
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm (246499 => 246500)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm 2019-06-17 17:28:43 UTC (rev 246499)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStore.mm 2019-06-17 17:41:39 UTC (rev 246500)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2014-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2014-2019 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -513,6 +513,28 @@
#endif
}
+- (void)_clearPrevalentDomain:(NSURL *)domain completionHandler:(void (^)(void))completionHandler
+{
+#if ENABLE(RESOURCE_LOAD_STATISTICS)
+ _websiteDataStore->websiteDataStore().clearPrevalentResource(URL(domain), [completionHandler = makeBlockPtr(completionHandler)]() {
+ completionHandler();
+ });
+#else
+ completionHandler();
+#endif
+}
+
+- (void)_processStatisticsAndDataRecords:(void (^)(void))completionHandler
+{
+#if ENABLE(RESOURCE_LOAD_STATISTICS)
+ _websiteDataStore->websiteDataStore().scheduleStatisticsAndDataRecordsProcessing([completionHandler = makeBlockPtr(completionHandler)]() {
+ completionHandler();
+ });
+#else
+ completionHandler();
+#endif
+}
+
- (bool)_hasRegisteredServiceWorker
{
return WebKit::ServiceWorkerProcessProxy::hasRegisteredServiceWorkers(_websiteDataStore->websiteDataStore().serviceWorkerRegistrationDirectory());
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h (246499 => 246500)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h 2019-06-17 17:28:43 UTC (rev 246499)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebsiteDataStorePrivate.h 2019-06-17 17:41:39 UTC (rev 246500)
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2016-2017 Apple Inc. All rights reserved.
+ * Copyright (C) 2016-2019 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -70,6 +70,8 @@
- (void)_scheduleCookieBlockingUpdate:(void (^)(void))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
- (void)_setPrevalentDomain:(NSURL *)domain completionHandler:(void (^)(void))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
- (void)_getIsPrevalentDomain:(NSURL *)domain completionHandler:(void (^)(BOOL))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+- (void)_clearPrevalentDomain:(NSURL *)domain completionHandler:(void (^)(void))completionHandler;
+- (void)_processStatisticsAndDataRecords:(void (^)(void))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
@property (nullable, nonatomic, weak) id <_WKWebsiteDataStoreDelegate> _delegate WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.cpp (246499 => 246500)
--- trunk/Source/WebKit/UIProcess/WebProcessPool.cpp 2019-06-17 17:28:43 UTC (rev 246499)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.cpp 2019-06-17 17:41:39 UTC (rev 246500)
@@ -582,7 +582,7 @@
SandboxExtension::createHandleForReadWriteDirectory(parameters.defaultDataStoreParameters.networkSessionParameters.resourceLoadStatisticsDirectory, parameters.defaultDataStoreParameters.networkSessionParameters.resourceLoadStatisticsDirectoryExtensionHandle);
- bool enableResourceLoadStatistics = false;
+ bool enableResourceLoadStatistics = m_shouldEnableITPForDefaultSessions;
bool shouldIncludeLocalhost = true;
bool enableResourceLoadStatisticsDebugMode = false;
WebCore::RegistrableDomain manualPrevalentResource { };
@@ -1487,6 +1487,7 @@
void WebProcessPool::setResourceLoadStatisticsEnabled(bool enabled)
{
+ m_shouldEnableITPForDefaultSessions = enabled;
sendToAllProcesses(Messages::WebProcess::SetResourceLoadStatisticsEnabled(enabled));
#if ENABLE(RESOURCE_LOAD_STATISTICS)
sendToNetworkingProcess(Messages::NetworkProcess::SetResourceLoadStatisticsEnabled(enabled));
Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.h (246499 => 246500)
--- trunk/Source/WebKit/UIProcess/WebProcessPool.h 2019-06-17 17:28:43 UTC (rev 246499)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.h 2019-06-17 17:41:39 UTC (rev 246500)
@@ -727,6 +727,7 @@
bool m_shouldTakeUIBackgroundAssertion;
bool m_shouldMakeNextWebProcessLaunchFailForTesting { false };
bool m_shouldMakeNextNetworkProcessLaunchFailForTesting { false };
+ bool m_shouldEnableITPForDefaultSessions { false };
UserObservablePageCounter m_userObservablePageCounter;
ProcessSuppressionDisabledCounter m_processSuppressionDisabledForPageCounter;
Modified: trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp (246499 => 246500)
--- trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp 2019-06-17 17:28:43 UTC (rev 246499)
+++ trunk/Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp 2019-06-17 17:41:39 UTC (rev 246500)
@@ -1875,6 +1875,8 @@
processPool->setResourceLoadStatisticsEnabled(false);
processPool->sendToNetworkingProcess(Messages::NetworkProcess::SetResourceLoadStatisticsEnabled(false));
}
+
+ m_resourceLoadStatisticsEnabled = false;
#else
UNUSED_PARAM(enabled);
#endif
Modified: trunk/Tools/ChangeLog (246499 => 246500)
--- trunk/Tools/ChangeLog 2019-06-17 17:28:43 UTC (rev 246499)
+++ trunk/Tools/ChangeLog 2019-06-17 17:41:39 UTC (rev 246500)
@@ -1,3 +1,16 @@
+2019-06-17 Brent Fulgham <[email protected]>
+
+ Ensure ITP state is relayed to Network Process on restart
+ https://bugs.webkit.org/show_bug.cgi?id=198797
+ <rdar://problem/51646944>
+
+ Reviewed by Youenn Fablet.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/ResourceLoadStatistics.mm:
+ (cleanupITPDatabase): Added.
+ (TEST:EnableDisableITP): Update to use cleanup method.
+ (TEST:NetworkProcessRestart): Added.
+
2019-06-17 Aakash Jain <[email protected]>
New EWS can't process patches larger than 640kb
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ResourceLoadStatistics.mm (246499 => 246500)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ResourceLoadStatistics.mm 2019-06-17 17:28:43 UTC (rev 246499)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ResourceLoadStatistics.mm 2019-06-17 17:41:39 UTC (rev 246500)
@@ -208,10 +208,43 @@
TestWebKitAPI::Util::run(&finishedNavigation);
}
+static void cleanupITPDatabase(WKWebsiteDataStore *dataStore)
+{
+ [dataStore _setResourceLoadStatisticsEnabled:YES];
+
+ // Make sure 'evil.com' is not in our data set.
+ static bool doneFlag;
+ [dataStore _clearPrevalentDomain:[NSURL URLWithString:@"http://evil.com"] completionHandler: ^(void) {
+ doneFlag = true;
+ }];
+
+ static bool dataSyncCompleted;
+ [dataStore _setResourceLoadStatisticsTestingCallback:^(WKWebsiteDataStore *, NSString *message) {
+ if (![message isEqualToString:@"Storage Synced"])
+ return;
+
+ dataSyncCompleted = true;
+ }];
+
+ TestWebKitAPI::Util::run(&doneFlag);
+
+ // Trigger ITP to process its data to force a sync to persistent storage.
+ [dataStore _processStatisticsAndDataRecords: ^(void) {
+ doneFlag = true;
+ }];
+
+ TestWebKitAPI::Util::run(&doneFlag);
+ TestWebKitAPI::Util::run(&dataSyncCompleted);
+
+ TestWebKitAPI::Util::spinRunLoop(1);
+
+ [dataStore _setResourceLoadStatisticsEnabled:NO];
+}
+
TEST(ResourceLoadStatistics, EnableDisableITP)
{
// Ensure the shared process pool exists so the data store operations we're about to do work with it.
- WKProcessPool *sharedProcessPool = [WKProcessPool _sharedProcessPool];
+ auto *sharedProcessPool = [WKProcessPool _sharedProcessPool];
auto *dataStore = [WKWebsiteDataStore defaultDataStore];
auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
@@ -223,6 +256,8 @@
[webView loadHTMLString:@"WebKit Test" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
[webView _test_waitForDidFinishNavigation];
+ cleanupITPDatabase(dataStore);
+
// ITP should be off, no URLs are prevalent.
static bool doneFlag;
[dataStore _getIsPrevalentDomain:[NSURL URLWithString:@"http://evil.com"] completionHandler: ^(BOOL prevalent) {
@@ -317,3 +352,124 @@
[webView2 loadHTMLString:@"WebKit Test" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
[webView2 _test_waitForDidFinishNavigation];
}
+
+TEST(ResourceLoadStatistics, NetworkProcessRestart)
+{
+ // Ensure the shared process pool exists so the data store operations we're about to do work with it.
+ auto *sharedProcessPool = [WKProcessPool _sharedProcessPool];
+ auto *dataStore = [WKWebsiteDataStore defaultDataStore];
+
+ auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ [configuration setProcessPool: sharedProcessPool];
+ configuration.get().websiteDataStore = dataStore;
+
+ auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+
+ [webView loadHTMLString:@"WebKit Test" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
+ [webView _test_waitForDidFinishNavigation];
+
+ cleanupITPDatabase(dataStore);
+
+ // Turn it on
+ [dataStore _setResourceLoadStatisticsEnabled:YES];
+
+ [webView loadHTMLString:@"WebKit Test" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
+ [webView _test_waitForDidFinishNavigation];
+
+ // ITP should be on, but nothing was registered as prevalent yet.
+ static bool doneFlag;
+ [dataStore _getIsPrevalentDomain:[NSURL URLWithString:@"http://evil.com"] completionHandler: ^(BOOL prevalent) {
+ EXPECT_FALSE(prevalent);
+ doneFlag = true;
+ }];
+
+ TestWebKitAPI::Util::run(&doneFlag);
+
+ // Teach ITP about a bad origin:
+ doneFlag = false;
+ [dataStore _setPrevalentDomain:[NSURL URLWithString:@"http://evil.com"] completionHandler: ^(void) {
+ doneFlag = true;
+ }];
+
+ TestWebKitAPI::Util::run(&doneFlag);
+
+ [webView loadHTMLString:@"WebKit Test" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
+ [webView _test_waitForDidFinishNavigation];
+
+ // ITP should be on, and know about 'evil.com'
+ doneFlag = false;
+ [dataStore _getIsPrevalentDomain:[NSURL URLWithString:@"http://evil.com"] completionHandler: ^(BOOL prevalent) {
+ EXPECT_TRUE(prevalent);
+ doneFlag = true;
+ }];
+
+ TestWebKitAPI::Util::run(&doneFlag);
+
+ static bool dataSyncCompleted;
+ [dataStore _setResourceLoadStatisticsTestingCallback:^(WKWebsiteDataStore *, NSString *message) {
+ if (![message isEqualToString:@"Storage Synced"])
+ return;
+ dataSyncCompleted = true;
+ }];
+
+ // Tell ITP to process data so it will sync the new 'bad guy' to persistent storage:
+ [dataStore _processStatisticsAndDataRecords: ^(void) {
+ doneFlag = true;
+ }];
+
+ TestWebKitAPI::Util::run(&doneFlag);
+ TestWebKitAPI::Util::run(&dataSyncCompleted);
+
+ TestWebKitAPI::Util::spinRunLoop(1);
+
+ [configuration.get().processPool _terminateNetworkProcess];
+
+ auto webView2 = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+
+ [webView2 loadHTMLString:@"WebKit Test 2" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
+ [webView2 _test_waitForDidFinishNavigation];
+
+ // ITP should be on, and know about 'evil.com'
+ doneFlag = false;
+ [dataStore _getIsPrevalentDomain:[NSURL URLWithString:@"http://evil.com"] completionHandler: ^(BOOL prevalent) {
+ EXPECT_TRUE(prevalent);
+ doneFlag = true;
+ }];
+
+ TestWebKitAPI::Util::run(&doneFlag);
+
+ // Turn it off
+ [dataStore _setResourceLoadStatisticsEnabled:NO];
+
+ [webView loadHTMLString:@"WebKit Test" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
+ [webView _test_waitForDidFinishNavigation];
+
+ // ITP should be off, no URLs are prevalent.
+ doneFlag = false;
+ [dataStore _getIsPrevalentDomain:[NSURL URLWithString:@"http://evil.com"] completionHandler: ^(BOOL prevalent) {
+ EXPECT_FALSE(prevalent);
+ doneFlag = true;
+ }];
+
+ TestWebKitAPI::Util::run(&doneFlag);
+
+ TestWebKitAPI::Util::spinRunLoop(1);
+
+ [configuration.get().processPool _terminateNetworkProcess];
+
+ auto webView3 = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+
+ [webView3 loadHTMLString:@"WebKit Test 3" baseURL:[NSURL URLWithString:@"http://webkit.org"]];
+ [webView3 _test_waitForDidFinishNavigation];
+
+ TestWebKitAPI::Util::run(&doneFlag);
+
+ // ITP should still be off, and should not know about 'evil.com'
+ doneFlag = false;
+ [dataStore _getIsPrevalentDomain:[NSURL URLWithString:@"http://evil.com"] completionHandler: ^(BOOL prevalent) {
+ EXPECT_FALSE(prevalent);
+ doneFlag = true;
+ }];
+
+ TestWebKitAPI::Util::run(&doneFlag);
+}