Add a second tier of prevalence to facilitate telemetry on very prevalent domains
authorwilander@apple.com <wilander@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 28 Feb 2018 22:25:27 +0000 (22:25 +0000)
committerwilander@apple.com <wilander@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 28 Feb 2018 22:25:27 +0000 (22:25 +0000)
https://bugs.webkit.org/show_bug.cgi?id=183218
<rdar://problem/37992388>

Reviewed by Brent Fulgham.

Source/WebCore:

Test: http/tests/resourceLoadStatistics/classify-as-very-prevalent-based-on-mixed-statistics.html

* loader/ResourceLoadStatistics.cpp:
(WebCore::ResourceLoadStatistics::encode const):
(WebCore::ResourceLoadStatistics::decode):
(WebCore::ResourceLoadStatistics::toString const):
(WebCore::ResourceLoadStatistics::merge):
    Handling of the new boolean field isVeryPrevalentResource.
* loader/ResourceLoadStatistics.h:
    Added the new boolean field isVeryPrevalentResource.

Source/WebKit:

* Platform/classifier/ResourceLoadStatisticsClassifier.cpp:
(WebKit::vectorLength):
    New convenience function.
(WebKit::ResourceLoadStatisticsClassifier::calculateResourcePrevalence):
    Renamed from ResourceLoadStatisticsClassifier::hasPrevalentResourceCharacteristics().
    Now returns a value from the enum ResourceLoadPrevalence.
(WebKit::ResourceLoadStatisticsClassifier::classifyWithVectorThreshold):
    Now uses the new vectorLength() convenience function.
(WebKit::ResourceLoadStatisticsClassifier::hasPrevalentResourceCharacteristics): Deleted.
    Renamed to ResourceLoadStatisticsClassifier::calculateResourcePrevalence().
* Platform/classifier/ResourceLoadStatisticsClassifier.h:
    Added enum ResourceLoadPrevalence.
* Shared/WebCoreArgumentCoders.cpp:
(IPC::ArgumentCoder<ResourceLoadStatistics>::encode):
(IPC::ArgumentCoder<ResourceLoadStatistics>::decode):
    Handling of the new boolean field isVeryPrevalentResource.
* UIProcess/API/C/WKWebsiteDataStoreRef.cpp:
(WKWebsiteDataStoreSetStatisticsVeryPrevalentResource):
(WKWebsiteDataStoreIsStatisticsVeryPrevalentResource):
    Test infrastructure.
* UIProcess/API/C/WKWebsiteDataStoreRef.h:
* UIProcess/WebResourceLoadStatisticsStore.cpp:
(WebKit::WebResourceLoadStatisticsStore::processStatisticsAndDataRecords):
(WebKit::WebResourceLoadStatisticsStore::setPrevalentResource):
(WebKit::WebResourceLoadStatisticsStore::setVeryPrevalentResource):
(WebKit::WebResourceLoadStatisticsStore::isVeryPrevalentResource):
(WebKit::WebResourceLoadStatisticsStore::clearPrevalentResource):
    All of these are for handling of the two-tier classification.
    Also bumped the statisticsModelVersion to 12.
* UIProcess/WebResourceLoadStatisticsStore.h:

Tools:

* WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
    Added two new testRunner functions:
    - setStatisticsVeryPrevalentResource()
    - isStatisticsVeryPrevalentResource()
* WebKitTestRunner/InjectedBundle/TestRunner.cpp:
(WTR::TestRunner::setStatisticsVeryPrevalentResource):
(WTR::TestRunner::isStatisticsVeryPrevalentResource):
* WebKitTestRunner/InjectedBundle/TestRunner.h:
* WebKitTestRunner/TestController.cpp:
(WTR::TestController::setStatisticsVeryPrevalentResource):
(WTR::TestController::isStatisticsVeryPrevalentResource):
* WebKitTestRunner/TestController.h:
* WebKitTestRunner/TestInvocation.cpp:
(WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):

LayoutTests:

* http/tests/resourceLoadStatistics/classify-as-prevalent-based-on-mixed-statistics.html:
* http/tests/resourceLoadStatistics/classify-as-prevalent-based-on-sub-frame-under-top-frame-origins.html:
* http/tests/resourceLoadStatistics/classify-as-prevalent-based-on-subresource-redirect-collusion.html:
* http/tests/resourceLoadStatistics/classify-as-prevalent-based-on-subresource-under-top-frame-origins.html:
* http/tests/resourceLoadStatistics/classify-as-prevalent-based-on-subresource-unique-redirects-to.html:
* http/tests/resourceLoadStatistics/classify-as-prevalent-based-on-top-frame-redirect-collusion.html:
* http/tests/resourceLoadStatistics/classify-as-prevalent-based-on-top-frame-unique-redirects-to.html:
* http/tests/resourceLoadStatistics/classify-as-very-prevalent-based-on-mixed-statistics-expected.txt: Added.
* http/tests/resourceLoadStatistics/classify-as-very-prevalent-based-on-mixed-statistics.html: Added.
* platform/wk2/TestExpectations:
    New test marked as [ Pass ].

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@229106 268f45cc-cd09-0410-ab3c-d52691b4dbfc

29 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/resourceLoadStatistics/classify-as-prevalent-based-on-mixed-statistics.html
LayoutTests/http/tests/resourceLoadStatistics/classify-as-prevalent-based-on-sub-frame-under-top-frame-origins.html
LayoutTests/http/tests/resourceLoadStatistics/classify-as-prevalent-based-on-subresource-redirect-collusion.html
LayoutTests/http/tests/resourceLoadStatistics/classify-as-prevalent-based-on-subresource-under-top-frame-origins.html
LayoutTests/http/tests/resourceLoadStatistics/classify-as-prevalent-based-on-subresource-unique-redirects-to.html
LayoutTests/http/tests/resourceLoadStatistics/classify-as-prevalent-based-on-top-frame-redirect-collusion.html
LayoutTests/http/tests/resourceLoadStatistics/classify-as-prevalent-based-on-top-frame-unique-redirects-to.html
LayoutTests/http/tests/resourceLoadStatistics/classify-as-very-prevalent-based-on-mixed-statistics-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/resourceLoadStatistics/classify-as-very-prevalent-based-on-mixed-statistics.html [new file with mode: 0644]
LayoutTests/platform/wk2/TestExpectations
Source/WebCore/ChangeLog
Source/WebCore/loader/ResourceLoadStatistics.cpp
Source/WebCore/loader/ResourceLoadStatistics.h
Source/WebKit/ChangeLog
Source/WebKit/Platform/classifier/ResourceLoadStatisticsClassifier.cpp
Source/WebKit/Platform/classifier/ResourceLoadStatisticsClassifier.h
Source/WebKit/Shared/WebCoreArgumentCoders.cpp
Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.cpp
Source/WebKit/UIProcess/API/C/WKWebsiteDataStoreRef.h
Source/WebKit/UIProcess/WebResourceLoadStatisticsStore.cpp
Source/WebKit/UIProcess/WebResourceLoadStatisticsStore.h
Tools/ChangeLog
Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl
Tools/WebKitTestRunner/InjectedBundle/TestRunner.cpp
Tools/WebKitTestRunner/InjectedBundle/TestRunner.h
Tools/WebKitTestRunner/TestController.cpp
Tools/WebKitTestRunner/TestController.h
Tools/WebKitTestRunner/TestInvocation.cpp

index d895c3d..f67a7b8 100644 (file)
@@ -1,3 +1,23 @@
+2018-02-28  John Wilander  <wilander@apple.com>
+
+        Add a second tier of prevalence to facilitate telemetry on very prevalent domains
+        https://bugs.webkit.org/show_bug.cgi?id=183218
+        <rdar://problem/37992388>
+
+        Reviewed by Brent Fulgham.
+
+        * http/tests/resourceLoadStatistics/classify-as-prevalent-based-on-mixed-statistics.html:
+        * http/tests/resourceLoadStatistics/classify-as-prevalent-based-on-sub-frame-under-top-frame-origins.html:
+        * http/tests/resourceLoadStatistics/classify-as-prevalent-based-on-subresource-redirect-collusion.html:
+        * http/tests/resourceLoadStatistics/classify-as-prevalent-based-on-subresource-under-top-frame-origins.html:
+        * http/tests/resourceLoadStatistics/classify-as-prevalent-based-on-subresource-unique-redirects-to.html:
+        * http/tests/resourceLoadStatistics/classify-as-prevalent-based-on-top-frame-redirect-collusion.html:
+        * http/tests/resourceLoadStatistics/classify-as-prevalent-based-on-top-frame-unique-redirects-to.html:
+        * http/tests/resourceLoadStatistics/classify-as-very-prevalent-based-on-mixed-statistics-expected.txt: Added.
+        * http/tests/resourceLoadStatistics/classify-as-very-prevalent-based-on-mixed-statistics.html: Added.
+        * platform/wk2/TestExpectations:
+            New test marked as [ Pass ].
+
 2018-02-28  Ryan Haddad  <ryanhaddad@apple.com>
 
         Disable three resourceLoadStatistics tests on iOS Simulator Debug because they frequently time out.
index 128d3f2..6ef2ad1 100644 (file)
@@ -17,6 +17,8 @@
     function completeTest() {
         if (!testRunner.isStatisticsPrevalentResource(statisticsUrl))
             testFailed("Host did not get classified as prevalent resource.");
+        if (testRunner.isStatisticsVeryPrevalentResource(statisticsUrl))
+            testFailed("Host got classified as very prevalent resource.");
         else
             testPassed("Host classified as prevalent resource.");
 
index 2a45d29..85a6c7f 100644 (file)
@@ -17,6 +17,8 @@
     function completeTest() {
         if (!testRunner.isStatisticsPrevalentResource(statisticsUrl))
             testFailed("Host did not get classified as prevalent resource.");
+        if (testRunner.isStatisticsVeryPrevalentResource(statisticsUrl))
+            testFailed("Host got classified as very prevalent resource.");
         else
             testPassed("Host classified as prevalent resource.");
 
index a6a8d1b..fcc68f9 100644 (file)
             testFailed("Host explicity set did not get set as prevalent resource.");
         if (testRunner.isStatisticsPrevalentResource(subresourceOrigin1))
             testPassed("Colluding host 1 got set as prevalent resource.");
+        if (testRunner.isStatisticsVeryPrevalentResource(subresourceOrigin1))
+            testFailed("Colluding host 1 got classified as very prevalent resource.");
         if (testRunner.isStatisticsPrevalentResource(subresourceOrigin2))
             testPassed("Colluding host 2 got set as prevalent resource.");
+        if (testRunner.isStatisticsVeryPrevalentResource(subresourceOrigin2))
+            testFailed("Colluding host 2 got classified as very prevalent resource.");
         if (testRunner.isStatisticsPrevalentResource(subresourceOrigin3))
             testPassed("Colluding host 3 got set as prevalent resource.");
+        if (testRunner.isStatisticsVeryPrevalentResource(subresourceOrigin3))
+            testFailed("Colluding host 3 got classified as very prevalent resource.");
         if (testRunner.isStatisticsPrevalentResource(subresourceOrigin4))
             testPassed("Colluding host 4 got set as prevalent resource.");
+        if (testRunner.isStatisticsVeryPrevalentResource(subresourceOrigin4))
+            testFailed("Colluding host 4 got classified as very prevalent resource.");
         if (testRunner.isStatisticsPrevalentResource("http://localhost:8000"))
             testPassed("Colluding localhost got set as prevalent resource after actual sub frame redirect.");
+        if (testRunner.isStatisticsVeryPrevalentResource("http://localhost:8000"))
+            testFailed("Colluding localhost got classified as very prevalent resource.");
 
         setEnableFeature(false);
         finishJSTest();
index 1f687ab..6941e57 100644 (file)
@@ -17,6 +17,8 @@
     function completeTest() {
         if (!testRunner.isStatisticsPrevalentResource(statisticsUrl))
             testFailed("Host did not get classified as prevalent resource.");
+        if (testRunner.isStatisticsVeryPrevalentResource(statisticsUrl))
+            testFailed("Host got classified as very prevalent resource.");
         else
             testPassed("Host classified as prevalent resource.");
 
index 1306769..f0a9354 100644 (file)
@@ -17,6 +17,8 @@
     function completeTest() {
         if (!testRunner.isStatisticsPrevalentResource(statisticsUrl))
             testFailed("Host did not get classified as prevalent resource.");
+        if (testRunner.isStatisticsVeryPrevalentResource(statisticsUrl))
+            testFailed("Host got classified as very prevalent resource.");
         else
             testPassed("Host classified as prevalent resource.");
 
index ec3ed66..3e5de35 100644 (file)
             testFailed("Host explicity set did not get set as prevalent resource.");
         if (testRunner.isStatisticsPrevalentResource(topFrameOrigin1))
             testPassed("Colluding host 1 got set as prevalent resource.");
+        if (testRunner.isStatisticsVeryPrevalentResource(topFrameOrigin1))
+            testFailed("Colluding host 1 got classified as very prevalent resource.");
         if (testRunner.isStatisticsPrevalentResource(topFrameOrigin2))
             testPassed("Colluding host 2 got set as prevalent resource.");
+        if (testRunner.isStatisticsVeryPrevalentResource(topFrameOrigin2))
+            testFailed("Colluding host 2 got classified as very prevalent resource.");
         if (testRunner.isStatisticsPrevalentResource(topFrameOrigin3))
             testPassed("Colluding host 3 got set as prevalent resource.");
+        if (testRunner.isStatisticsVeryPrevalentResource(topFrameOrigin3))
+            testFailed("Colluding host 3 got classified as very prevalent resource.");
         if (testRunner.isStatisticsPrevalentResource(topFrameOrigin4))
             testPassed("Colluding host 4 got set as prevalent resource.");
+        if (testRunner.isStatisticsVeryPrevalentResource(topFrameOrigin4))
+            testFailed("Colluding host 4 got classified as very prevalent resource.");
         if (testRunner.isStatisticsPrevalentResource(topFrameOrigin5))
             testPassed("Colluding localhost got set as prevalent resource after actual navigational redirect.");
+        if (testRunner.isStatisticsVeryPrevalentResource(topFrameOrigin5))
+            testFailed("Colluding localhost got classified as very prevalent resource.");
 
         setEnableFeature(false);
         finishJSTest();
index 77a74c3..5918692 100644 (file)
@@ -26,6 +26,8 @@
     function completeTest() {
         if (!testRunner.isStatisticsPrevalentResource(statisticsUrl))
             testFailed("Host did not get classified as prevalent resource.");
+        if (testRunner.isStatisticsVeryPrevalentResource(statisticsUrl))
+            testFailed("Host got classified as very prevalent resource.");
         else
             testPassed("Host classified as prevalent resource.");
 
diff --git a/LayoutTests/http/tests/resourceLoadStatistics/classify-as-very-prevalent-based-on-mixed-statistics-expected.txt b/LayoutTests/http/tests/resourceLoadStatistics/classify-as-very-prevalent-based-on-mixed-statistics-expected.txt
new file mode 100644 (file)
index 0000000..b0f031d
--- /dev/null
@@ -0,0 +1,10 @@
+Test for classification as very prevalent based on mixed statistics.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS Host classified as very prevalent resource.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/resourceLoadStatistics/classify-as-very-prevalent-based-on-mixed-statistics.html b/LayoutTests/http/tests/resourceLoadStatistics/classify-as-very-prevalent-based-on-mixed-statistics.html
new file mode 100644 (file)
index 0000000..d55fa77
--- /dev/null
@@ -0,0 +1,73 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <script src="../../resources/js-test-pre.js"></script>
+</head>
+<body>
+<script>
+    description("Test for classification as very prevalent based on mixed statistics.");
+    jsTestIsAsync = true;
+
+    const hostUnderTest = "127.0.0.1:8000";
+    const statisticsUrl = "http://" + hostUnderTest + "/temp";
+    var topFrameOrigins = [];
+    const startNum = 2;
+    const numberOfSubresourceDomains = 30;
+    for (var i = startNum; i < numberOfSubresourceDomains + startNum; ++i)
+        topFrameOrigins.push("http://127.0.0." + i + ":8000/temp")
+
+    function setEnableFeature(enable) {
+        if (!enable)
+            testRunner.statisticsResetToConsistentState();
+        internals.setResourceLoadStatisticsEnabled(enable);
+        testRunner.setCookieStoragePartitioningEnabled(enable);
+    }
+
+    function completeTest() {
+        if (!testRunner.isStatisticsPrevalentResource(statisticsUrl))
+            testFailed("Host did not get classified as prevalent resource.");
+        if (!testRunner.isStatisticsVeryPrevalentResource(statisticsUrl))
+            testFailed("Host did not get classified as very prevalent resource.");
+        else
+            testPassed("Host classified as very prevalent resource.");
+
+        setEnableFeature(false);
+        finishJSTest();
+    }
+
+    function runTestRunnerTest() {
+        testRunner.setStatisticsNotifyPagesWhenDataRecordsWereScanned(true);
+        testRunner.setStatisticsPrevalentResource(statisticsUrl, false);
+        if (testRunner.isStatisticsPrevalentResource(statisticsUrl))
+            testFailed("Host started out as prevalent resource.");
+
+        var i = 0;
+        while (i < numberOfSubresourceDomains) {
+            testRunner.setStatisticsSubframeUnderTopFrameOrigin(statisticsUrl, topFrameOrigins[i]);
+            testRunner.setStatisticsSubresourceUnderTopFrameOrigin(statisticsUrl, topFrameOrigins[i]);
+            testRunner.setStatisticsSubresourceUniqueRedirectTo(statisticsUrl, topFrameOrigins[i]);
+
+            testRunner.setStatisticsSubframeUnderTopFrameOrigin(statisticsUrl, topFrameOrigins[i+1]);
+            testRunner.setStatisticsSubresourceUnderTopFrameOrigin(statisticsUrl, topFrameOrigins[i+1]);
+            testRunner.setStatisticsSubresourceUniqueRedirectTo(statisticsUrl, topFrameOrigins[i+1]);
+
+            testRunner.setStatisticsSubframeUnderTopFrameOrigin(statisticsUrl, topFrameOrigins[i+2]);
+            testRunner.setStatisticsSubresourceUnderTopFrameOrigin(statisticsUrl, topFrameOrigins[i+2]);
+            testRunner.setStatisticsSubresourceUniqueRedirectTo(statisticsUrl, topFrameOrigins[i+2]);
+            i += 3;
+        }
+
+        testRunner.installStatisticsDidScanDataRecordsCallback(completeTest);
+        testRunner.statisticsProcessStatisticsAndDataRecords();
+    }
+
+    if (document.location.host === hostUnderTest && window.testRunner && window.internals) {
+        setEnableFeature(true);
+        runTestRunnerTest();
+    }
+</script>
+<script src="../../resources/js-test-post.js"></script>
+</body>
+</html>
index 620eb47..0659889 100644 (file)
@@ -676,6 +676,7 @@ http/tests/resourceLoadStatistics/classify-as-non-prevalent-based-on-sub-frame-u
 http/tests/resourceLoadStatistics/classify-as-non-prevalent-based-on-subresource-under-top-frame-origins.html [ Pass ]
 http/tests/resourceLoadStatistics/classify-as-non-prevalent-based-on-subresource-unique-redirects-to.html [ Pass ]
 http/tests/resourceLoadStatistics/classify-as-prevalent-based-on-mixed-statistics.html [ Pass ]
+http/tests/resourceLoadStatistics/classify-as-very-prevalent-based-on-mixed-statistics.html [ Pass ]
 http/tests/resourceLoadStatistics/classify-as-prevalent-based-on-sub-frame-under-top-frame-origins.html [ Pass ]
 http/tests/resourceLoadStatistics/classify-as-prevalent-based-on-subresource-under-top-frame-origins.html [ Pass ]
 http/tests/resourceLoadStatistics/classify-as-prevalent-based-on-subresource-unique-redirects-to.html [ Pass ]
index cd72992..9b7158c 100644 (file)
@@ -1,3 +1,22 @@
+2018-02-28  John Wilander  <wilander@apple.com>
+
+        Add a second tier of prevalence to facilitate telemetry on very prevalent domains
+        https://bugs.webkit.org/show_bug.cgi?id=183218
+        <rdar://problem/37992388>
+
+        Reviewed by Brent Fulgham.
+
+        Test: http/tests/resourceLoadStatistics/classify-as-very-prevalent-based-on-mixed-statistics.html
+
+        * loader/ResourceLoadStatistics.cpp:
+        (WebCore::ResourceLoadStatistics::encode const):
+        (WebCore::ResourceLoadStatistics::decode):
+        (WebCore::ResourceLoadStatistics::toString const):
+        (WebCore::ResourceLoadStatistics::merge):
+            Handling of the new boolean field isVeryPrevalentResource.
+        * loader/ResourceLoadStatistics.h:
+            Added the new boolean field isVeryPrevalentResource.
+
 2018-02-28  Alex Christensen  <achristensen@webkit.org>
 
         Reduce use of NetworkingContext in WebKit
index f5ad6b8..2fdee44 100644 (file)
@@ -84,6 +84,7 @@ void ResourceLoadStatistics::encode(KeyedEncoder& encoder) const
 
     // Prevalent Resource
     encoder.encodeBool("isPrevalentResource", isPrevalentResource);
+    encoder.encodeBool("isVeryPrevalentResource", isVeryPrevalentResource);
     encoder.encodeUInt32("dataRecordsRemoved", dataRecordsRemoved);
 
     encoder.encodeUInt32("timesAccessedAsFirstPartyDueToUserInteraction", timesAccessedAsFirstPartyDueToUserInteraction);
@@ -149,6 +150,11 @@ bool ResourceLoadStatistics::decode(KeyedDecoder& decoder, unsigned modelVersion
     if (!decoder.decodeBool("isPrevalentResource", isPrevalentResource))
         return false;
 
+    if (modelVersion >= 12) {
+        if (!decoder.decodeBool("isVeryPrevalentResource", isPrevalentResource))
+            return false;
+    }
+
     if (!decoder.decodeUInt32("dataRecordsRemoved", dataRecordsRemoved))
         return false;
 
@@ -250,6 +256,7 @@ String ResourceLoadStatistics::toString() const
 
     // Prevalent Resource
     appendBoolean(builder, "isPrevalentResource", isPrevalentResource);
+    appendBoolean(builder, "    isVeryPrevalentResource", isVeryPrevalentResource);
     builder.appendLiteral("    dataRecordsRemoved: ");
     builder.appendNumber(dataRecordsRemoved);
     builder.append('\n');
@@ -316,6 +323,7 @@ void ResourceLoadStatistics::merge(const ResourceLoadStatistics& other)
 
     // Prevalent resource stats
     isPrevalentResource |= other.isPrevalentResource;
+    isVeryPrevalentResource |= other.isVeryPrevalentResource;
     dataRecordsRemoved = std::max(dataRecordsRemoved, other.dataRecordsRemoved);
     
     // In-memory only
index 3d93f47..034ed3d 100644 (file)
@@ -87,6 +87,7 @@ struct ResourceLoadStatistics {
 
     // Prevalent resource stats
     bool isPrevalentResource { false };
+    bool isVeryPrevalentResource { false };
     unsigned dataRecordsRemoved { 0 };
     unsigned timesAccessedAsFirstPartyDueToUserInteraction { 0 };
     unsigned timesAccessedAsFirstPartyDueToStorageAccessAPI { 0 };
index 9de1f69..92f3413 100644 (file)
@@ -1,3 +1,42 @@
+2018-02-28  John Wilander  <wilander@apple.com>
+
+        Add a second tier of prevalence to facilitate telemetry on very prevalent domains
+        https://bugs.webkit.org/show_bug.cgi?id=183218
+        <rdar://problem/37992388>
+
+        Reviewed by Brent Fulgham.
+
+        * Platform/classifier/ResourceLoadStatisticsClassifier.cpp:
+        (WebKit::vectorLength):
+            New convenience function.
+        (WebKit::ResourceLoadStatisticsClassifier::calculateResourcePrevalence):
+            Renamed from ResourceLoadStatisticsClassifier::hasPrevalentResourceCharacteristics().
+            Now returns a value from the enum ResourceLoadPrevalence.
+        (WebKit::ResourceLoadStatisticsClassifier::classifyWithVectorThreshold):
+            Now uses the new vectorLength() convenience function.
+        (WebKit::ResourceLoadStatisticsClassifier::hasPrevalentResourceCharacteristics): Deleted.
+            Renamed to ResourceLoadStatisticsClassifier::calculateResourcePrevalence().
+        * Platform/classifier/ResourceLoadStatisticsClassifier.h:
+            Added enum ResourceLoadPrevalence.
+        * Shared/WebCoreArgumentCoders.cpp:
+        (IPC::ArgumentCoder<ResourceLoadStatistics>::encode):
+        (IPC::ArgumentCoder<ResourceLoadStatistics>::decode):
+            Handling of the new boolean field isVeryPrevalentResource.
+        * UIProcess/API/C/WKWebsiteDataStoreRef.cpp:
+        (WKWebsiteDataStoreSetStatisticsVeryPrevalentResource):
+        (WKWebsiteDataStoreIsStatisticsVeryPrevalentResource):
+            Test infrastructure.
+        * UIProcess/API/C/WKWebsiteDataStoreRef.h:
+        * UIProcess/WebResourceLoadStatisticsStore.cpp:
+        (WebKit::WebResourceLoadStatisticsStore::processStatisticsAndDataRecords):
+        (WebKit::WebResourceLoadStatisticsStore::setPrevalentResource):
+        (WebKit::WebResourceLoadStatisticsStore::setVeryPrevalentResource):
+        (WebKit::WebResourceLoadStatisticsStore::isVeryPrevalentResource):
+        (WebKit::WebResourceLoadStatisticsStore::clearPrevalentResource):
+            All of these are for handling of the two-tier classification.
+            Also bumped the statisticsModelVersion to 12.
+        * UIProcess/WebResourceLoadStatisticsStore.h:
+
 2018-02-28  Alex Christensen  <achristensen@webkit.org>
 
         Reduce use of NetworkingContext in WebKit
index 83c8ab3..affa733 100644 (file)
 namespace WebKit {
 using namespace WebCore;
 
-static const auto featureVectorLengthThreshold = 3;
-bool ResourceLoadStatisticsClassifier::hasPrevalentResourceCharacteristics(const ResourceLoadStatistics& resourceStatistic)
+static double vectorLength(unsigned a, unsigned b, unsigned c)
 {
+    return sqrt(a * a + b * b + c * c);
+}
+
+static const auto featureVectorLengthThresholdHigh = 3;
+static const auto featureVectorLengthThresholdVeryHigh = 30;
+ResourceLoadPrevalence ResourceLoadStatisticsClassifier::calculateResourcePrevalence(const ResourceLoadStatistics& resourceStatistic, ResourceLoadPrevalence currentPrevalence)
+{
+    ASSERT(currentPrevalence != VeryHigh);
+
     auto subresourceUnderTopFrameOriginsCount = resourceStatistic.subresourceUnderTopFrameOrigins.size();
     auto subresourceUniqueRedirectsToCount = resourceStatistic.subresourceUniqueRedirectsTo.size();
     auto subframeUnderTopFrameOriginsCount = resourceStatistic.subframeUnderTopFrameOrigins.size();
@@ -43,22 +51,29 @@ bool ResourceLoadStatisticsClassifier::hasPrevalentResourceCharacteristics(const
     if (!subresourceUnderTopFrameOriginsCount
         && !subresourceUniqueRedirectsToCount
         && !subframeUnderTopFrameOriginsCount
-        && !topFrameUniqueRedirectsToCount)
-        return false;
-    
-    if (subresourceUnderTopFrameOriginsCount > featureVectorLengthThreshold
-        || subresourceUniqueRedirectsToCount > featureVectorLengthThreshold
-        || subframeUnderTopFrameOriginsCount > featureVectorLengthThreshold
-        || topFrameUniqueRedirectsToCount > featureVectorLengthThreshold)
-        return true;
+        && !topFrameUniqueRedirectsToCount) {
+        ASSERT(currentPrevalence == Low);
+        return Low;
+    }
+
+    if (vectorLength(subresourceUnderTopFrameOriginsCount, subresourceUniqueRedirectsToCount, subframeUnderTopFrameOriginsCount) > featureVectorLengthThresholdVeryHigh)
+        return VeryHigh;
+
+    if (currentPrevalence == High
+        || subresourceUnderTopFrameOriginsCount > featureVectorLengthThresholdHigh
+        || subresourceUniqueRedirectsToCount > featureVectorLengthThresholdHigh
+        || subframeUnderTopFrameOriginsCount > featureVectorLengthThresholdHigh
+        || topFrameUniqueRedirectsToCount > featureVectorLengthThresholdHigh
+        || classify(subresourceUnderTopFrameOriginsCount, subresourceUniqueRedirectsToCount, subframeUnderTopFrameOriginsCount))
+        return High;
 
-    return classify(subresourceUnderTopFrameOriginsCount, subresourceUniqueRedirectsToCount, subframeUnderTopFrameOriginsCount);
+    return Low;
 }
 
 bool ResourceLoadStatisticsClassifier::classifyWithVectorThreshold(unsigned a, unsigned b, unsigned c)
 {
     LOG(ResourceLoadStatistics, "ResourceLoadStatisticsClassifier::classifyWithVectorThreshold(): Classified with threshold.");
-    return sqrt(a * a + b * b + c * c) > featureVectorLengthThreshold;
+    return vectorLength(a, b, c) > featureVectorLengthThresholdHigh;
 }
     
 }
index 9b42d21..acf1f38 100644 (file)
@@ -31,11 +31,17 @@ struct ResourceLoadStatistics;
 
 namespace WebKit {
 
+enum ResourceLoadPrevalence {
+    Low = 1 << 0,
+    High = 1 << 1,
+    VeryHigh = 1 << 2,
+};
+
 class ResourceLoadStatisticsClassifier {
 public:
     ResourceLoadStatisticsClassifier() = default;
     virtual ~ResourceLoadStatisticsClassifier() = default;
-    bool hasPrevalentResourceCharacteristics(const WebCore::ResourceLoadStatistics& resourceStatistic);
+    ResourceLoadPrevalence calculateResourcePrevalence(const WebCore::ResourceLoadStatistics& resourceStatistic, ResourceLoadPrevalence currentPrevalence);
 protected:
     virtual bool classify(unsigned subresourceUnderTopFrameOriginsCount, unsigned subresourceUniqueRedirectsToCount, unsigned subframeUnderTopFrameOriginsCount)
     {
index 7b3b194..08282a8 100644 (file)
@@ -2552,6 +2552,7 @@ void ArgumentCoder<ResourceLoadStatistics>::encode(Encoder& encoder, const WebCo
 
     // Prevalent Resource
     encoder << statistics.isPrevalentResource;
+    encoder << statistics.isVeryPrevalentResource;
     encoder << statistics.dataRecordsRemoved;
 }
 
@@ -2607,6 +2608,9 @@ std::optional<ResourceLoadStatistics> ArgumentCoder<ResourceLoadStatistics>::dec
     if (!decoder.decode(statistics.isPrevalentResource))
         return std::nullopt;
 
+    if (!decoder.decode(statistics.isVeryPrevalentResource))
+        return std::nullopt;
+    
     if (!decoder.decode(statistics.dataRecordsRemoved))
         return std::nullopt;
 
index 981e1ee..6650b58 100644 (file)
@@ -89,6 +89,18 @@ void WKWebsiteDataStoreSetStatisticsPrevalentResource(WKWebsiteDataStoreRef data
         store->clearPrevalentResource(WebCore::URL(WebCore::URL(), WebKit::toImpl(host)->string()));
 }
 
+void WKWebsiteDataStoreSetStatisticsVeryPrevalentResource(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, bool value)
+{
+    auto* store = WebKit::toImpl(dataStoreRef)->websiteDataStore().resourceLoadStatistics();
+    if (!store)
+        return;
+    
+    if (value)
+        store->setVeryPrevalentResource(WebCore::URL(WebCore::URL(), WebKit::toImpl(host)->string()));
+    else
+        store->clearPrevalentResource(WebCore::URL(WebCore::URL(), WebKit::toImpl(host)->string()));
+}
+
 void WKWebsiteDataStoreIsStatisticsPrevalentResource(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, void* context, WKWebsiteDataStoreIsStatisticsPrevalentResourceFunction callback)
 {
     auto* store = WebKit::toImpl(dataStoreRef)->websiteDataStore().resourceLoadStatistics();
@@ -102,6 +114,19 @@ void WKWebsiteDataStoreIsStatisticsPrevalentResource(WKWebsiteDataStoreRef dataS
     });
 }
 
+void WKWebsiteDataStoreIsStatisticsVeryPrevalentResource(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, void* context, WKWebsiteDataStoreIsStatisticsPrevalentResourceFunction callback)
+{
+    auto* store = WebKit::toImpl(dataStoreRef)->websiteDataStore().resourceLoadStatistics();
+    if (!store) {
+        callback(false, context);
+        return;
+    }
+    
+    store->isVeryPrevalentResource(WebCore::URL(WebCore::URL(), WebKit::toImpl(host)->string()), [context, callback](bool isVeryPrevalentResource) {
+        callback(isVeryPrevalentResource, context);
+    });
+}
+
 void WKWebsiteDataStoreIsStatisticsRegisteredAsSubFrameUnder(WKWebsiteDataStoreRef dataStoreRef, WKStringRef subFrameHost, WKStringRef topFrameHost, void* context, WKWebsiteDataStoreIsStatisticsRegisteredAsSubFrameUnderFunction callback)
 {
     auto* store = WebKit::toImpl(dataStoreRef)->websiteDataStore().resourceLoadStatistics();
index 3564e0a..452b2fe 100644 (file)
@@ -42,8 +42,10 @@ WK_EXPORT void WKWebsiteDataStoreSetResourceLoadStatisticsEnabled(WKWebsiteDataS
 WK_EXPORT void WKWebsiteDataStoreSetResourceLoadStatisticsDebugMode(WKWebsiteDataStoreRef dataStoreRef, bool enable);
 WK_EXPORT void WKWebsiteDataStoreSetStatisticsLastSeen(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, double seconds);
 WK_EXPORT void WKWebsiteDataStoreSetStatisticsPrevalentResource(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, bool value);
+WK_EXPORT void WKWebsiteDataStoreSetStatisticsVeryPrevalentResource(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, bool value);
 typedef void (*WKWebsiteDataStoreIsStatisticsPrevalentResourceFunction)(bool isPrevalentResource, void* functionContext);
 WK_EXPORT void WKWebsiteDataStoreIsStatisticsPrevalentResource(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, void* context, WKWebsiteDataStoreIsStatisticsPrevalentResourceFunction callback);
+WK_EXPORT void WKWebsiteDataStoreIsStatisticsVeryPrevalentResource(WKWebsiteDataStoreRef dataStoreRef, WKStringRef host, void* context, WKWebsiteDataStoreIsStatisticsPrevalentResourceFunction callback);
 typedef void (*WKWebsiteDataStoreIsStatisticsRegisteredAsSubFrameUnderFunction)(bool isRegisteredAsSubFrameUnder, void* functionContext);
 WK_EXPORT void WKWebsiteDataStoreIsStatisticsRegisteredAsSubFrameUnder(WKWebsiteDataStoreRef dataStoreRef, WKStringRef subFrameHost, WKStringRef topFrameHost, void* context, WKWebsiteDataStoreIsStatisticsRegisteredAsSubFrameUnderFunction callback);
 typedef void (*WKWebsiteDataStoreIsStatisticsRegisteredAsRedirectingToFunction)(bool isRegisteredAsRedirectingTo, void* functionContext);
index e86eb0a..dcbd781 100644 (file)
@@ -49,7 +49,7 @@ namespace WebKit {
 using namespace WebCore;
 
 constexpr unsigned operatingDatesWindow { 30 };
-constexpr unsigned statisticsModelVersion { 11 };
+constexpr unsigned statisticsModelVersion { 12 };
 constexpr unsigned maxImportance { 3 };
 constexpr unsigned maxNumberOfRecursiveCallsInRedirectTraceBack { 50 };
 
@@ -292,8 +292,12 @@ void WebResourceLoadStatisticsStore::processStatisticsAndDataRecords()
 
     if (m_parameters.shouldClassifyResourcesBeforeDataRecordsRemoval) {
         for (auto& resourceStatistic : m_resourceStatisticsMap.values()) {
-            if (!resourceStatistic.isPrevalentResource && m_resourceLoadStatisticsClassifier.hasPrevalentResourceCharacteristics(resourceStatistic))
-                setPrevalentResource(resourceStatistic);
+            if (!resourceStatistic.isVeryPrevalentResource) {
+                auto currentPrevalence = resourceStatistic.isPrevalentResource ? ResourceLoadPrevalence::High : ResourceLoadPrevalence::Low;
+                auto newPrevalence = m_resourceLoadStatisticsClassifier.calculateResourcePrevalence(resourceStatistic, currentPrevalence);
+                if (newPrevalence != currentPrevalence)
+                    setPrevalentResource(resourceStatistic, newPrevalence);
+            }
         }
     }
     
@@ -520,14 +524,28 @@ void WebResourceLoadStatisticsStore::setPrevalentResource(const URL& url)
 
     m_statisticsQueue->dispatch([this, protectedThis = makeRef(*this), primaryDomain = isolatedPrimaryDomain(url)] {
         auto& resourceStatistic = ensureResourceStatisticsForPrimaryDomain(primaryDomain);
-        setPrevalentResource(resourceStatistic);
+        setPrevalentResource(resourceStatistic, ResourceLoadPrevalence::High);
+    });
+}
+
+void WebResourceLoadStatisticsStore::setVeryPrevalentResource(const URL& url)
+{
+    ASSERT(isMainThread());
+
+    if (url.isBlankURL() || url.isEmpty())
+        return;
+    
+    m_statisticsQueue->dispatch([this, protectedThis = makeRef(*this), primaryDomain = isolatedPrimaryDomain(url)] {
+        auto& resourceStatistic = ensureResourceStatisticsForPrimaryDomain(primaryDomain);
+        setPrevalentResource(resourceStatistic, ResourceLoadPrevalence::VeryHigh);
     });
 }
 
-void WebResourceLoadStatisticsStore::setPrevalentResource(WebCore::ResourceLoadStatistics& resourceStatistic)
+void WebResourceLoadStatisticsStore::setPrevalentResource(WebCore::ResourceLoadStatistics& resourceStatistic, ResourceLoadPrevalence newPrevalence)
 {
     ASSERT(!RunLoop::isMain());
     resourceStatistic.isPrevalentResource = true;
+    resourceStatistic.isVeryPrevalentResource = newPrevalence == ResourceLoadPrevalence::VeryHigh;
     HashSet<String> domainsThatHaveRedirectedTo;
     recursivelyGetAllDomainsThatHaveRedirectedToThisDomain(resourceStatistic, domainsThatHaveRedirectedTo, 0);
     for (auto& domain : domainsThatHaveRedirectedTo) {
@@ -555,6 +573,24 @@ void WebResourceLoadStatisticsStore::isPrevalentResource(const URL& url, WTF::Fu
     });
 }
 
+void WebResourceLoadStatisticsStore::isVeryPrevalentResource(const URL& url, WTF::Function<void(bool)>&& completionHandler)
+{
+    ASSERT(isMainThread());
+
+    if (url.isBlankURL() || url.isEmpty()) {
+        completionHandler(false);
+        return;
+    }
+    
+    m_statisticsQueue->dispatch([this, protectedThis = makeRef(*this), primaryDomain = isolatedPrimaryDomain(url), completionHandler = WTFMove(completionHandler)] () mutable {
+        auto mapEntry = m_resourceStatisticsMap.find(primaryDomain);
+        bool isVeryPrevalentResource = mapEntry == m_resourceStatisticsMap.end() ? false : mapEntry->value.isPrevalentResource && mapEntry->value.isVeryPrevalentResource;
+        RunLoop::main().dispatch([isVeryPrevalentResource, completionHandler = WTFMove(completionHandler)] {
+            completionHandler(isVeryPrevalentResource);
+        });
+    });
+}
+
 void WebResourceLoadStatisticsStore::isRegisteredAsSubFrameUnder(const URL& subFrame, const URL& topFrame, WTF::Function<void (bool)>&& completionHandler)
 {
     m_statisticsQueue->dispatch([this, protectedThis = makeRef(*this), subFramePrimaryDomain = isolatedPrimaryDomain(subFrame), topFramePrimaryDomain = isolatedPrimaryDomain(topFrame), completionHandler = WTFMove(completionHandler)] () mutable {
@@ -585,6 +621,7 @@ void WebResourceLoadStatisticsStore::clearPrevalentResource(const URL& url)
     m_statisticsQueue->dispatch([this, protectedThis = makeRef(*this), primaryDomain = isolatedPrimaryDomain(url)] {
         auto& statistics = ensureResourceStatisticsForPrimaryDomain(primaryDomain);
         statistics.isPrevalentResource = false;
+        statistics.isVeryPrevalentResource = false;
     });
 }
 
index 030758f..f0ae29b 100644 (file)
@@ -97,7 +97,9 @@ public:
     void hasHadUserInteraction(const WebCore::URL&, WTF::Function<void (bool)>&&);
     void setLastSeen(const WebCore::URL&, Seconds);
     void setPrevalentResource(const WebCore::URL&);
+    void setVeryPrevalentResource(const WebCore::URL&);
     void isPrevalentResource(const WebCore::URL&, WTF::Function<void (bool)>&&);
+    void isVeryPrevalentResource(const WebCore::URL&, WTF::Function<void(bool)>&&);
     void isRegisteredAsSubFrameUnder(const WebCore::URL& subFrame, const WebCore::URL& topFrame, WTF::Function<void (bool)>&&);
     void isRegisteredAsRedirectingTo(const WebCore::URL& hostRedirectedFrom, const WebCore::URL& hostRedirectedTo, WTF::Function<void (bool)>&&);
     void clearPrevalentResource(const WebCore::URL&);
@@ -171,7 +173,7 @@ private:
     void mergeStatistics(Vector<WebCore::ResourceLoadStatistics>&&);
     WebCore::ResourceLoadStatistics& ensureResourceStatisticsForPrimaryDomain(const String&);
     unsigned recursivelyGetAllDomainsThatHaveRedirectedToThisDomain(const WebCore::ResourceLoadStatistics&, HashSet<String>& domainsThatHaveRedirectedTo, unsigned numberOfRecursiveCalls);
-    void setPrevalentResource(WebCore::ResourceLoadStatistics&);
+    void setPrevalentResource(WebCore::ResourceLoadStatistics&, ResourceLoadPrevalence);
     void processStatisticsAndDataRecords();
 
     void resetCookiePartitioningState();
index 690d588..0ece790 100644 (file)
@@ -1,3 +1,26 @@
+2018-02-28  John Wilander  <wilander@apple.com>
+
+        Add a second tier of prevalence to facilitate telemetry on very prevalent domains
+        https://bugs.webkit.org/show_bug.cgi?id=183218
+        <rdar://problem/37992388>
+
+        Reviewed by Brent Fulgham.
+
+        * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+            Added two new testRunner functions:
+            - setStatisticsVeryPrevalentResource()
+            - isStatisticsVeryPrevalentResource()
+        * WebKitTestRunner/InjectedBundle/TestRunner.cpp:
+        (WTR::TestRunner::setStatisticsVeryPrevalentResource):
+        (WTR::TestRunner::isStatisticsVeryPrevalentResource):
+        * WebKitTestRunner/InjectedBundle/TestRunner.h:
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::TestController::setStatisticsVeryPrevalentResource):
+        (WTR::TestController::isStatisticsVeryPrevalentResource):
+        * WebKitTestRunner/TestController.h:
+        * WebKitTestRunner/TestInvocation.cpp:
+        (WTR::TestInvocation::didReceiveSynchronousMessageFromInjectedBundle):
+
 2018-02-28  Jonathan Bedard  <jbedard@apple.com>
 
         [webkitpy] Remove concept of 'future' versions (Follow-up fix)
index 8b25dea..b694aca 100644 (file)
@@ -268,7 +268,9 @@ interface TestRunner {
     void installStatisticsDidRunTelemetryCallback(object callback);
     void setStatisticsLastSeen(DOMString hostName, double seconds);
     void setStatisticsPrevalentResource(DOMString hostName, boolean value);
+    void setStatisticsVeryPrevalentResource(DOMString hostName, boolean value);
     boolean isStatisticsPrevalentResource(DOMString hostName);
+    boolean isStatisticsVeryPrevalentResource(DOMString hostName);
     boolean isStatisticsRegisteredAsSubFrameUnder(DOMString subFrameHost, DOMString topFrameHost);
     boolean isStatisticsRegisteredAsRedirectingTo(DOMString hostRedirectedFrom, DOMString hostRedirectedTo);
     void setStatisticsHasHadUserInteraction(DOMString hostName, boolean value);
index 470dda7..5edb655 100644 (file)
@@ -1272,6 +1272,33 @@ void TestRunner::setStatisticsPrevalentResource(JSStringRef hostName, bool value
     WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
 }
 
+void TestRunner::setStatisticsVeryPrevalentResource(JSStringRef hostName, bool value)
+{
+    Vector<WKRetainPtr<WKStringRef>> keys;
+    Vector<WKRetainPtr<WKTypeRef>> values;
+    
+    keys.append({ AdoptWK, WKStringCreateWithUTF8CString("HostName") });
+    values.append({ AdoptWK, WKStringCreateWithJSString(hostName) });
+    
+    keys.append({ AdoptWK, WKStringCreateWithUTF8CString("Value") });
+    values.append({ AdoptWK, WKBooleanCreate(value) });
+    
+    Vector<WKStringRef> rawKeys;
+    Vector<WKTypeRef> rawValues;
+    rawKeys.resize(keys.size());
+    rawValues.resize(values.size());
+    
+    for (size_t i = 0; i < keys.size(); ++i) {
+        rawKeys[i] = keys[i].get();
+        rawValues[i] = values[i].get();
+    }
+    
+    WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("SetStatisticsVeryPrevalentResource"));
+    WKRetainPtr<WKDictionaryRef> messageBody(AdoptWK, WKDictionaryCreate(rawKeys.data(), rawValues.data(), rawKeys.size()));
+    
+    WKBundlePostSynchronousMessage(InjectedBundle::singleton().bundle(), messageName.get(), messageBody.get(), nullptr);
+}
+
 bool TestRunner::isStatisticsPrevalentResource(JSStringRef hostName)
 {
     WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("IsStatisticsPrevalentResource"));
@@ -1281,6 +1308,15 @@ bool TestRunner::isStatisticsPrevalentResource(JSStringRef hostName)
     return WKBooleanGetValue(static_cast<WKBooleanRef>(returnData));
 }
 
+bool TestRunner::isStatisticsVeryPrevalentResource(JSStringRef hostName)
+{
+    WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("IsStatisticsVeryPrevalentResource"));
+    WKRetainPtr<WKStringRef> messageBody(AdoptWK, WKStringCreateWithJSString(hostName));
+    WKTypeRef returnData = 0;
+    WKBundlePagePostSynchronousMessageForTesting(InjectedBundle::singleton().page()->page(), messageName.get(), messageBody.get(), &returnData);
+    return WKBooleanGetValue(static_cast<WKBooleanRef>(returnData));
+}
+
 bool TestRunner::isStatisticsRegisteredAsSubFrameUnder(JSStringRef subFrameHost, JSStringRef topFrameHost)
 {
     Vector<WKRetainPtr<WKStringRef>> keys;
index 3effac8..9e4405f 100644 (file)
@@ -373,7 +373,9 @@ public:
     void statisticsSubmitTelemetry();
     void setStatisticsLastSeen(JSStringRef hostName, double seconds);
     void setStatisticsPrevalentResource(JSStringRef hostName, bool value);
+    void setStatisticsVeryPrevalentResource(JSStringRef hostName, bool value);
     bool isStatisticsPrevalentResource(JSStringRef hostName);
+    bool isStatisticsVeryPrevalentResource(JSStringRef hostName);
     bool isStatisticsRegisteredAsSubFrameUnder(JSStringRef subFrameHost, JSStringRef topFrameHost);
     bool isStatisticsRegisteredAsRedirectingTo(JSStringRef hostRedirectedFrom, JSStringRef hostRedirectedTo);
     void setStatisticsHasHadUserInteraction(JSStringRef hostName, bool value);
index 3400d45..e708e10 100644 (file)
@@ -2530,6 +2530,12 @@ void TestController::setStatisticsPrevalentResource(WKStringRef host, bool value
     WKWebsiteDataStoreSetStatisticsPrevalentResource(dataStore, host, value);
 }
 
+void TestController::setStatisticsVeryPrevalentResource(WKStringRef host, bool value)
+{
+    auto* dataStore = WKContextGetWebsiteDataStore(platformContext());
+    WKWebsiteDataStoreSetStatisticsVeryPrevalentResource(dataStore, host, value);
+}
+
 struct ResourceStatisticsCallbackContext {
     explicit ResourceStatisticsCallbackContext(TestController& controller)
         : testController(controller)
@@ -2565,6 +2571,15 @@ bool TestController::isStatisticsPrevalentResource(WKStringRef host)
     return context.result;
 }
 
+bool TestController::isStatisticsVeryPrevalentResource(WKStringRef host)
+{
+    auto* dataStore = WKContextGetWebsiteDataStore(platformContext());
+    ResourceStatisticsCallbackContext context(*this);
+    WKWebsiteDataStoreIsStatisticsVeryPrevalentResource(dataStore, host, &context, resourceStatisticsBooleanResultCallback);
+    runUntil(context.done, noTimeout);
+    return context.result;
+}
+
 bool TestController::isStatisticsRegisteredAsSubFrameUnder(WKStringRef subFrameHost, WKStringRef topFrameHost)
 {
     auto* dataStore = WKContextGetWebsiteDataStore(platformContext());
index 01c17e0..c8d4734 100644 (file)
@@ -156,7 +156,9 @@ public:
 
     void setStatisticsLastSeen(WKStringRef hostName, double seconds);
     void setStatisticsPrevalentResource(WKStringRef hostName, bool value);
+    void setStatisticsVeryPrevalentResource(WKStringRef hostName, bool value);
     bool isStatisticsPrevalentResource(WKStringRef hostName);
+    bool isStatisticsVeryPrevalentResource(WKStringRef hostName);
     bool isStatisticsRegisteredAsSubFrameUnder(WKStringRef subFrameHost, WKStringRef topFrameHost);
     bool isStatisticsRegisteredAsRedirectingTo(WKStringRef hostRedirectedFrom, WKStringRef hostRedirectedTo);
     void setStatisticsHasHadUserInteraction(WKStringRef hostName, bool value);
index 064a014..6347d0b 100644 (file)
@@ -961,6 +961,20 @@ WKRetainPtr<WKTypeRef> TestInvocation::didReceiveSynchronousMessageFromInjectedB
         return nullptr;
     }
 
+    if (WKStringIsEqualToUTF8CString(messageName, "SetStatisticsVeryPrevalentResource")) {
+        ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());
+        
+        WKDictionaryRef messageBodyDictionary = static_cast<WKDictionaryRef>(messageBody);
+        WKRetainPtr<WKStringRef> hostNameKey(AdoptWK, WKStringCreateWithUTF8CString("HostName"));
+        WKRetainPtr<WKStringRef> valueKey(AdoptWK, WKStringCreateWithUTF8CString("Value"));
+        
+        WKStringRef hostName = static_cast<WKStringRef>(WKDictionaryGetItemForKey(messageBodyDictionary, hostNameKey.get()));
+        WKBooleanRef value = static_cast<WKBooleanRef>(WKDictionaryGetItemForKey(messageBodyDictionary, valueKey.get()));
+        
+        TestController::singleton().setStatisticsVeryPrevalentResource(hostName, WKBooleanGetValue(value));
+        return nullptr;
+    }
+    
     if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsPrevalentResource")) {
         ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
 
@@ -970,6 +984,15 @@ WKRetainPtr<WKTypeRef> TestInvocation::didReceiveSynchronousMessageFromInjectedB
         return result;
     }
 
+    if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsVeryPrevalentResource")) {
+        ASSERT(WKGetTypeID(messageBody) == WKStringGetTypeID());
+        
+        WKStringRef hostName = static_cast<WKStringRef>(messageBody);
+        bool isPrevalent = TestController::singleton().isStatisticsVeryPrevalentResource(hostName);
+        WKRetainPtr<WKTypeRef> result(AdoptWK, WKBooleanCreate(isPrevalent));
+        return result;
+    }
+    
     if (WKStringIsEqualToUTF8CString(messageName, "IsStatisticsRegisteredAsSubFrameUnder")) {
         ASSERT(WKGetTypeID(messageBody) == WKDictionaryGetTypeID());