ServiceWorkers: Enable UserTiming / ResourceTiming
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 5 Jan 2018 18:14:15 +0000 (18:14 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 5 Jan 2018 18:14:15 +0000 (18:14 +0000)
https://bugs.webkit.org/show_bug.cgi?id=181297
<rdar://problem/36307306>

Patch by Joseph Pecoraro <pecoraro@apple.com> on 2018-01-05
Reviewed by Youenn Fablet.

Source/WebCore:

Tests: http/tests/workers/service/service-worker-resource-timing.https.html
       http/tests/workers/service/service-worker-user-timing.https.html

* loader/ResourceTiming.cpp:
(WebCore::ResourceTiming::ResourceTiming):
We used to clear extra NetworkLoadMetrics data early on. However,
for Workers we want to pass the complete NetworkLoadMetrics to
the Worker so that a Worker inspector has access to it.

* page/PerformanceResourceTiming.cpp:
(WebCore::PerformanceResourceTiming::PerformanceResourceTiming):
Instead move the clearing of extra data to here, when the NetworkLoadMetrics
have finally settled into being used only for a performance entry.

Source/WebKit:

* WebProcess/Storage/WebSWContextManagerConnection.cpp:
(WebKit::WebSWContextManagerConnection::updatePreferencesStore):
Enable Resource Timing / User Timing for the ServiceWorker process.

LayoutTests:

* http/tests/workers/service/resources/data1.txt: Added.
* http/tests/workers/service/resources/data2.txt: Added.
Resources to load from a service-worker.

* http/tests/workers/service/resources/service-worker-resource-timing.js: Added.
* http/tests/workers/service/service-worker-resource-timing.https-expected.txt: Added.
* http/tests/workers/service/service-worker-resource-timing.https.html: Added.
Test that a ServiceWorker can produce resource entries for a few
different kinds of loads (CacheStorage load, and a fetch).

* http/tests/workers/service/resources/service-worker-user-timing.js: Added.
* http/tests/workers/service/service-worker-user-timing.https-expected.txt: Added.
* http/tests/workers/service/service-worker-user-timing.https.html: Added.
Test that a ServiceWorker can produce a mark/measure entries.

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

14 files changed:
LayoutTests/ChangeLog
LayoutTests/http/tests/workers/service/resources/data1.txt [new file with mode: 0644]
LayoutTests/http/tests/workers/service/resources/data2.txt [new file with mode: 0644]
LayoutTests/http/tests/workers/service/resources/service-worker-resource-timing.js [new file with mode: 0644]
LayoutTests/http/tests/workers/service/resources/service-worker-user-timing.js [new file with mode: 0644]
LayoutTests/http/tests/workers/service/service-worker-resource-timing.https-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/workers/service/service-worker-resource-timing.https.html [new file with mode: 0644]
LayoutTests/http/tests/workers/service/service-worker-user-timing.https-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/workers/service/service-worker-user-timing.https.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/loader/ResourceTiming.cpp
Source/WebCore/page/PerformanceResourceTiming.cpp
Source/WebKit/ChangeLog
Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp

index a9fe037..3a35b17 100644 (file)
@@ -1,3 +1,26 @@
+2018-01-05  Joseph Pecoraro  <pecoraro@apple.com>
+
+        ServiceWorkers: Enable UserTiming / ResourceTiming
+        https://bugs.webkit.org/show_bug.cgi?id=181297
+        <rdar://problem/36307306>
+
+        Reviewed by Youenn Fablet.
+
+        * http/tests/workers/service/resources/data1.txt: Added.
+        * http/tests/workers/service/resources/data2.txt: Added.
+        Resources to load from a service-worker.
+
+        * http/tests/workers/service/resources/service-worker-resource-timing.js: Added.
+        * http/tests/workers/service/service-worker-resource-timing.https-expected.txt: Added.
+        * http/tests/workers/service/service-worker-resource-timing.https.html: Added.
+        Test that a ServiceWorker can produce resource entries for a few
+        different kinds of loads (CacheStorage load, and a fetch).
+
+        * http/tests/workers/service/resources/service-worker-user-timing.js: Added.
+        * http/tests/workers/service/service-worker-user-timing.https-expected.txt: Added.
+        * http/tests/workers/service/service-worker-user-timing.https.html: Added.
+        Test that a ServiceWorker can produce a mark/measure entries.
+
 2018-01-05  Claudio Saavedra  <csaavedra@igalia.com>
 
         [WPE][GTK] Unreviewed gardening
diff --git a/LayoutTests/http/tests/workers/service/resources/data1.txt b/LayoutTests/http/tests/workers/service/resources/data1.txt
new file mode 100644 (file)
index 0000000..8e72b5f
--- /dev/null
@@ -0,0 +1 @@
+Text data 1.
diff --git a/LayoutTests/http/tests/workers/service/resources/data2.txt b/LayoutTests/http/tests/workers/service/resources/data2.txt
new file mode 100644 (file)
index 0000000..77e62fc
--- /dev/null
@@ -0,0 +1 @@
+Text data 2.
diff --git a/LayoutTests/http/tests/workers/service/resources/service-worker-resource-timing.js b/LayoutTests/http/tests/workers/service/resources/service-worker-resource-timing.js
new file mode 100644 (file)
index 0000000..f060ebc
--- /dev/null
@@ -0,0 +1,14 @@
+self.addEventListener("install", (event) => {
+    event.waitUntil(
+        caches.open("resource-timing-cache").then((cache) => {
+            return Promise.all([
+                cache.addAll(["/workers/service/resources/data1.txt"]),
+                fetch("/workers/service/resources/data2.txt"),
+            ]);
+        })
+    );
+});
+
+self.addEventListener("message", (event) => {
+    event.source.postMessage({entries: JSON.stringify(performance.getEntries())});
+});
diff --git a/LayoutTests/http/tests/workers/service/resources/service-worker-user-timing.js b/LayoutTests/http/tests/workers/service/resources/service-worker-user-timing.js
new file mode 100644 (file)
index 0000000..64dd47f
--- /dev/null
@@ -0,0 +1,9 @@
+self.addEventListener("message", (event) => {
+    performance.clearMarks();
+    performance.clearMeasures();
+    performance.mark("test-mark");
+    performance.measure("test-measure");
+
+    let entries = [...performance.getEntriesByType("mark"), ...performance.getEntriesByType("measure")];
+    event.source.postMessage({entries: JSON.stringify(entries)});
+});
diff --git a/LayoutTests/http/tests/workers/service/service-worker-resource-timing.https-expected.txt b/LayoutTests/http/tests/workers/service/service-worker-resource-timing.https-expected.txt
new file mode 100644 (file)
index 0000000..00f556a
--- /dev/null
@@ -0,0 +1,4 @@
+
+PASS Setup worker 
+PASS Verify service worker had 2 ResourceTiming entries 
+
diff --git a/LayoutTests/http/tests/workers/service/service-worker-resource-timing.https.html b/LayoutTests/http/tests/workers/service/service-worker-resource-timing.https.html
new file mode 100644 (file)
index 0000000..004c026
--- /dev/null
@@ -0,0 +1,44 @@
+<html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script>
+let activeWorker;
+let scope = "/workers/service/resources/";
+
+promise_test(async (test) => {
+    let registration = await navigator.serviceWorker.getRegistration(scope);
+    if (registration && registration.scope.endsWith(scope))
+        await registration.unregister();
+
+    registration = await navigator.serviceWorker.register("resources/service-worker-resource-timing.js", {scope});
+    activeWorker = registration.active;
+    if (activeWorker)
+        return;
+
+    activeWorker = registration.installing;
+    return new Promise((resolve) => {
+        activeWorker.addEventListener("statechange", () => {
+            if (activeWorker.state === "activated")
+                resolve();
+        });
+    });
+}, "Setup worker");
+
+promise_test(async (test) => {
+    activeWorker.postMessage("TEST-RESOURCE-TIMING");
+    await new Promise((resolve, reject) => {
+        navigator.serviceWorker.addEventListener("message", test.step_func((event) => {
+            let entries = JSON.parse(event.data.entries);
+            assert_equals(entries.length, 2);
+            assert_true(entries.some((entry) => entry.name.endsWith("data1.txt")));
+            assert_true(entries.some((entry) => entry.name.endsWith("data2.txt")));
+            resolve();
+        }));
+    });
+}, "Verify service worker had 2 ResourceTiming entries");
+</script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/workers/service/service-worker-user-timing.https-expected.txt b/LayoutTests/http/tests/workers/service/service-worker-user-timing.https-expected.txt
new file mode 100644 (file)
index 0000000..4bf7b7f
--- /dev/null
@@ -0,0 +1,4 @@
+
+PASS Setup worker 
+PASS Verify service worker had 2 UserTiming entries 
+
diff --git a/LayoutTests/http/tests/workers/service/service-worker-user-timing.https.html b/LayoutTests/http/tests/workers/service/service-worker-user-timing.https.html
new file mode 100644 (file)
index 0000000..35ebd7f
--- /dev/null
@@ -0,0 +1,46 @@
+<html>
+<head>
+<script src="/resources/testharness.js"></script>
+<script src="/resources/testharnessreport.js"></script>
+</head>
+<body>
+<script>
+let activeWorker;
+let scope = "/workers/service/resources/";
+
+promise_test(async (test) => {
+    let registration = await navigator.serviceWorker.getRegistration(scope);
+    if (registration && registration.scope.endsWith(scope))
+        await registration.unregister();
+
+    registration = await navigator.serviceWorker.register("resources/service-worker-user-timing.js", {scope});
+    activeWorker = registration.active;
+    if (activeWorker)
+        return;
+
+    activeWorker = registration.installing;
+    return new Promise((resolve) => {
+        activeWorker.addEventListener("statechange", () => {
+            if (activeWorker.state === "activated")
+                resolve();
+        });
+    });
+}, "Setup worker");
+
+promise_test(async (test) => {
+    activeWorker.postMessage("TEST-USER-TIMING");
+    await new Promise((resolve, reject) => {
+        navigator.serviceWorker.addEventListener("message", test.step_func((event) => {
+            let entries = JSON.parse(event.data.entries);
+            assert_equals(entries.length, 2);
+            assert_equals(entries[0].entryType, "mark");
+            assert_equals(entries[0].name, "test-mark");
+            assert_equals(entries[1].entryType, "measure");
+            assert_equals(entries[1].name, "test-measure");
+            resolve();
+        }));
+    });
+}, "Verify service worker had 2 UserTiming entries");
+</script>
+</body>
+</html>
index d7c5ac1..0e285e6 100644 (file)
@@ -1,3 +1,25 @@
+2018-01-05  Joseph Pecoraro  <pecoraro@apple.com>
+
+        ServiceWorkers: Enable UserTiming / ResourceTiming
+        https://bugs.webkit.org/show_bug.cgi?id=181297
+        <rdar://problem/36307306>
+
+        Reviewed by Youenn Fablet.
+
+        Tests: http/tests/workers/service/service-worker-resource-timing.https.html
+               http/tests/workers/service/service-worker-user-timing.https.html
+
+        * loader/ResourceTiming.cpp:
+        (WebCore::ResourceTiming::ResourceTiming):
+        We used to clear extra NetworkLoadMetrics data early on. However,
+        for Workers we want to pass the complete NetworkLoadMetrics to
+        the Worker so that a Worker inspector has access to it.
+
+        * page/PerformanceResourceTiming.cpp:
+        (WebCore::PerformanceResourceTiming::PerformanceResourceTiming):
+        Instead move the clearing of extra data to here, when the NetworkLoadMetrics
+        have finally settled into being used only for a performance entry.
+
 2018-01-04  Philippe Normand  <pnormand@igalia.com>
 
         [EME][GStreamer] Fix wrong ifdef
index 3ad940a..fbc5c70 100644 (file)
@@ -85,7 +85,6 @@ ResourceTiming::ResourceTiming(CachedResource& resource, const String& initiator
     , m_networkLoadMetrics(networkLoadMetrics)
     , m_allowTimingDetails(passesTimingAllowCheck(resource.response(), securityOrigin))
 {
-    m_networkLoadMetrics.clearNonTimingData();
 }
 
 ResourceTiming::ResourceTiming(const URL& url, const String& initiator, const LoadTiming& loadTiming, const NetworkLoadMetrics& networkLoadMetrics, const ResourceResponse& response, const SecurityOrigin& securityOrigin)
@@ -95,7 +94,6 @@ ResourceTiming::ResourceTiming(const URL& url, const String& initiator, const Lo
     , m_networkLoadMetrics(networkLoadMetrics)
     , m_allowTimingDetails(passesTimingAllowCheck(response, securityOrigin))
 {
-    m_networkLoadMetrics.clearNonTimingData();
 }
 
 ResourceTiming ResourceTiming::isolatedCopy() const
index 152a9c7..c42c6a5 100644 (file)
@@ -80,6 +80,7 @@ PerformanceResourceTiming::PerformanceResourceTiming(MonotonicTime timeOrigin, R
     , m_networkLoadMetrics(resourceTiming.networkLoadMetrics())
     , m_shouldReportDetails(resourceTiming.allowTimingDetails())
 {
+    m_networkLoadMetrics.clearNonTimingData();
 }
 
 PerformanceResourceTiming::~PerformanceResourceTiming() = default;
@@ -91,6 +92,7 @@ String PerformanceResourceTiming::nextHopProtocol() const
 
 double PerformanceResourceTiming::workerStart() const
 {
+    // FIXME: <https://webkit.org/b/179377> Implement PerformanceResourceTiming.workerStart in ServiceWorkers
     return 0.0;
 }
 
index fe3b112..cb113e6 100644 (file)
@@ -1,3 +1,15 @@
+2018-01-05  Joseph Pecoraro  <pecoraro@apple.com>
+
+        ServiceWorkers: Enable UserTiming / ResourceTiming
+        https://bugs.webkit.org/show_bug.cgi?id=181297
+        <rdar://problem/36307306>
+
+        Reviewed by Youenn Fablet.
+
+        * WebProcess/Storage/WebSWContextManagerConnection.cpp:
+        (WebKit::WebSWContextManagerConnection::updatePreferencesStore):
+        Enable Resource Timing / User Timing for the ServiceWorker process.
+
 2018-01-04  Zan Dobersek  <zdobersek@igalia.com>
 
         Unreviewed GTK+ build fix.
index 4006424..8d47942 100644 (file)
@@ -112,6 +112,8 @@ void WebSWContextManagerConnection::updatePreferencesStore(const WebPreferencesS
     RuntimeEnabledFeatures::sharedFeatures().setServiceWorkerEnabled(true);
     RuntimeEnabledFeatures::sharedFeatures().setCacheAPIEnabled(store.getBoolValueForKey(WebPreferencesKey::cacheAPIEnabledKey()));
     RuntimeEnabledFeatures::sharedFeatures().setFetchAPIEnabled(store.getBoolValueForKey(WebPreferencesKey::fetchAPIEnabledKey()));
+    RuntimeEnabledFeatures::sharedFeatures().setUserTimingEnabled(store.getBoolValueForKey(WebPreferencesKey::userTimingEnabledKey()));
+    RuntimeEnabledFeatures::sharedFeatures().setResourceTimingEnabled(store.getBoolValueForKey(WebPreferencesKey::resourceTimingEnabledKey()));
 
     m_storageBlockingPolicy = static_cast<SecurityOrigin::StorageBlockingPolicy>(store.getUInt32ValueForKey(WebPreferencesKey::storageBlockingPolicyKey()));
 }