Title: [252418] trunk
Revision
252418
Author
[email protected]
Date
2019-11-13 11:15:13 -0800 (Wed, 13 Nov 2019)

Log Message

Take service worker assertions based on client processes assertion states
https://bugs.webkit.org/show_bug.cgi?id=204119

Reviewed by Chris Dumez.

Source/WebKit:

Compute in network process which processes contain clients for service workers of a given process.
WebSWServerConnection implements it and sends update to UIProcess/WebProcessProxy.
WebProcessProxy keeps for each service worker process a set of client web processes.
WebProcessProxy now computes the service worker process assertion based on this set.

Add some private APIs to set process assertions/get service worker process assertion states.
Covered by new API test.

* NetworkProcess/ServiceWorker/WebSWServerConnection.cpp:
(WebKit::WebSWServerConnection::registerServiceWorkerClient):
(WebKit::WebSWServerConnection::unregisterServiceWorkerClient):
(WebKit::WebSWServerConnection::contextConnectionCreated):
* NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
(WebKit::WebSWServerToContextConnection::webProcessIdentifier const):
* NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h:
* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _setAssertionStateForTesting:]):
(-[WKWebView _hasServiceWorkerBackgroundActivityForTesting]):
(-[WKWebView _hasServiceWorkerForegroundActivityForTesting]):
* UIProcess/API/Cocoa/WKWebViewPrivate.h:
* UIProcess/Network/NetworkProcessProxy.cpp:
(WebKit::NetworkProcessProxy::registerWebProcessToServiceWorkerProcess):
(WebKit::NetworkProcessProxy::unregisterWebProcessToServiceWorkerProcess):
* UIProcess/Network/NetworkProcessProxy.h:
* UIProcess/Network/NetworkProcessProxy.messages.in:
* UIProcess/WebProcessPool.cpp:
(WebKit::WebProcessPool::updateProcessAssertions):
(WebKit::WebProcessPool::hasServiceWorkerForegroundActivityForTesting const):
(WebKit::WebProcessPool::hasServiceWorkerBackgroundActivityForTesting const):
* UIProcess/WebProcessPool.h:
* UIProcess/WebProcessProxy.cpp:
(WebKit::WebProcessProxy::updateServiceWorkerProcessAssertion):
(WebKit::WebProcessProxy::registerWebProcessToServiceWorkerProcess):
(WebKit::WebProcessProxy::unregisterWebProcessToServiceWorkerProcess):
(WebKit::WebProcessProxy::hasServiceWorkerForegroundActivityForTesting const):
(WebKit::WebProcessProxy::hasServiceWorkerBackgroundActivityForTesting const):
* UIProcess/WebProcessProxy.h:
(WebKit::WebProcessProxy::setAssertionStateForTesting):

Tools:

* TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm:
Add tests checking service worker process assertion state.

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (252417 => 252418)


--- trunk/Source/WebKit/ChangeLog	2019-11-13 19:00:20 UTC (rev 252417)
+++ trunk/Source/WebKit/ChangeLog	2019-11-13 19:15:13 UTC (rev 252418)
@@ -1,3 +1,49 @@
+2019-11-13  Youenn Fablet  <[email protected]>
+
+        Take service worker assertions based on client processes assertion states
+        https://bugs.webkit.org/show_bug.cgi?id=204119
+
+        Reviewed by Chris Dumez.
+
+        Compute in network process which processes contain clients for service workers of a given process.
+        WebSWServerConnection implements it and sends update to UIProcess/WebProcessProxy.
+        WebProcessProxy keeps for each service worker process a set of client web processes.
+        WebProcessProxy now computes the service worker process assertion based on this set.
+
+        Add some private APIs to set process assertions/get service worker process assertion states.
+        Covered by new API test.
+
+        * NetworkProcess/ServiceWorker/WebSWServerConnection.cpp:
+        (WebKit::WebSWServerConnection::registerServiceWorkerClient):
+        (WebKit::WebSWServerConnection::unregisterServiceWorkerClient):
+        (WebKit::WebSWServerConnection::contextConnectionCreated):
+        * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
+        (WebKit::WebSWServerToContextConnection::webProcessIdentifier const):
+        * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h:
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _setAssertionStateForTesting:]):
+        (-[WKWebView _hasServiceWorkerBackgroundActivityForTesting]):
+        (-[WKWebView _hasServiceWorkerForegroundActivityForTesting]):
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+        * UIProcess/Network/NetworkProcessProxy.cpp:
+        (WebKit::NetworkProcessProxy::registerWebProcessToServiceWorkerProcess):
+        (WebKit::NetworkProcessProxy::unregisterWebProcessToServiceWorkerProcess):
+        * UIProcess/Network/NetworkProcessProxy.h:
+        * UIProcess/Network/NetworkProcessProxy.messages.in:
+        * UIProcess/WebProcessPool.cpp:
+        (WebKit::WebProcessPool::updateProcessAssertions):
+        (WebKit::WebProcessPool::hasServiceWorkerForegroundActivityForTesting const):
+        (WebKit::WebProcessPool::hasServiceWorkerBackgroundActivityForTesting const):
+        * UIProcess/WebProcessPool.h:
+        * UIProcess/WebProcessProxy.cpp:
+        (WebKit::WebProcessProxy::updateServiceWorkerProcessAssertion):
+        (WebKit::WebProcessProxy::registerWebProcessToServiceWorkerProcess):
+        (WebKit::WebProcessProxy::unregisterWebProcessToServiceWorkerProcess):
+        (WebKit::WebProcessProxy::hasServiceWorkerForegroundActivityForTesting const):
+        (WebKit::WebProcessProxy::hasServiceWorkerBackgroundActivityForTesting const):
+        * UIProcess/WebProcessProxy.h:
+        (WebKit::WebProcessProxy::setAssertionStateForTesting):
+
 2019-11-13  Andres Gonzalez  <[email protected]>
 
         AXObjectCache::rootObject should generate the isolated tree.

Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp (252417 => 252418)


--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp	2019-11-13 19:00:20 UTC (rev 252417)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp	2019-11-13 19:15:13 UTC (rev 252418)
@@ -33,6 +33,7 @@
 #include "Logging.h"
 #include "NetworkConnectionToWebProcessMessages.h"
 #include "NetworkProcess.h"
+#include "NetworkProcessProxyMessages.h"
 #include "NetworkResourceLoader.h"
 #include "WebCoreArgumentCoders.h"
 #include "WebProcess.h"
@@ -307,12 +308,24 @@
 
 void WebSWServerConnection::registerServiceWorkerClient(SecurityOriginData&& topOrigin, ServiceWorkerClientData&& data, const Optional<ServiceWorkerRegistrationIdentifier>& controllingServiceWorkerRegistrationIdentifier, String&& userAgent)
 {
-    auto clientOrigin = ClientOrigin { WTFMove(topOrigin), SecurityOriginData::fromURL(data.url) };
+    auto contextOrigin = SecurityOriginData::fromURL(data.url);
+    bool isNewOrigin = WTF::allOf(m_clientOrigins.values(), [&contextOrigin](auto& origin) {
+        return contextOrigin != origin.clientOrigin;
+    });
+
+    auto clientOrigin = ClientOrigin { WTFMove(topOrigin), WTFMove(contextOrigin) };
     m_clientOrigins.add(data.identifier, clientOrigin);
     server().registerServiceWorkerClient(WTFMove(clientOrigin), WTFMove(data), controllingServiceWorkerRegistrationIdentifier, WTFMove(userAgent));
 
     if (!m_isThrottleable)
         updateThrottleState();
+
+    if (isNewOrigin) {
+        if (auto* contextConnection = server().contextConnectionForRegistrableDomain(RegistrableDomain { contextOrigin })) {
+            auto& connection = static_cast<WebSWServerToContextConnection&>(*contextConnection);
+            m_networkProcess->parentProcessConnection()->send(Messages::NetworkProcessProxy::RegisterServiceWorkerClientProcess { identifier(), connection.webProcessIdentifier() }, 0);
+        }
+    }
 }
 
 void WebSWServerConnection::unregisterServiceWorkerClient(const ServiceWorkerClientIdentifier& clientIdentifier)
@@ -321,11 +334,24 @@
     if (iterator == m_clientOrigins.end())
         return;
 
-    server().unregisterServiceWorkerClient(iterator->value, clientIdentifier);
+    auto clientOrigin = iterator->value;
+
+    server().unregisterServiceWorkerClient(clientOrigin, clientIdentifier);
     m_clientOrigins.remove(iterator);
 
     if (!m_isThrottleable)
         updateThrottleState();
+
+    bool isDeletedOrigin = WTF::allOf(m_clientOrigins.values(), [&clientOrigin](auto& origin) {
+        return clientOrigin.clientOrigin != origin.clientOrigin;
+    });
+
+    if (isDeletedOrigin) {
+        if (auto* contextConnection = server().contextConnectionForRegistrableDomain(RegistrableDomain { clientOrigin.clientOrigin })) {
+            auto& connection = static_cast<WebSWServerToContextConnection&>(*contextConnection);
+            m_networkProcess->parentProcessConnection()->send(Messages::NetworkProcessProxy::UnregisterServiceWorkerClientProcess { identifier(), connection.webProcessIdentifier() }, 0);
+        }
+    }
 }
 
 bool WebSWServerConnection::hasMatchingClient(const RegistrableDomain& domain) const
@@ -373,6 +399,9 @@
 {
     auto& connection =  static_cast<WebSWServerToContextConnection&>(contextConnection);
     connection.setThrottleState(computeThrottleState(connection.registrableDomain()));
+
+    if (hasMatchingClient(connection.registrableDomain()))
+        m_networkProcess->parentProcessConnection()->send(Messages::NetworkProcessProxy::RegisterServiceWorkerClientProcess { identifier(), connection.webProcessIdentifier() }, 0);
 }
 
 void WebSWServerConnection::syncTerminateWorkerFromClient(WebCore::ServiceWorkerIdentifier&& identifier, CompletionHandler<void()>&& completionHandler)

Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp (252417 => 252418)


--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp	2019-11-13 19:00:20 UTC (rev 252417)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp	2019-11-13 19:15:13 UTC (rev 252418)
@@ -198,6 +198,11 @@
     }
 }
 
+WebCore::ProcessIdentifier WebSWServerToContextConnection::webProcessIdentifier() const
+{
+    return m_connection.webProcessIdentifier();
+}
+
 } // namespace WebKit
 
 #endif // ENABLE(SERVICE_WORKER)

Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h (252417 => 252418)


--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h	2019-11-13 19:00:20 UTC (rev 252417)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h	2019-11-13 19:15:13 UTC (rev 252418)
@@ -75,6 +75,8 @@
     void registerFetch(ServiceWorkerFetchTask&);
     void unregisterFetch(ServiceWorkerFetchTask&);
 
+    WebCore::ProcessIdentifier webProcessIdentifier() const;
+
 private:
     // IPC::MessageSender
     IPC::Connection* messageSenderConnection() const final;

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm (252417 => 252418)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm	2019-11-13 19:00:20 UTC (rev 252417)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm	2019-11-13 19:15:13 UTC (rev 252418)
@@ -7705,6 +7705,32 @@
         _page->process().sendProcessDidResume();
 }
 
+- (void)_setAssertionStateForTesting:(int)value
+{
+    if (!_page)
+        return;
+
+    _page->process().setAssertionStateForTesting(static_cast<WebKit::AssertionState>(value));
+}
+
+- (BOOL)_hasServiceWorkerBackgroundActivityForTesting
+{
+#if ENABLE(SERVICE_WORKER)
+    return _page ? _page->process().processPool().hasServiceWorkerBackgroundActivityForTesting() : false;
+#else
+    return false;
+#endif
+}
+
+- (BOOL)_hasServiceWorkerForegroundActivityForTesting
+{
+#if ENABLE(SERVICE_WORKER)
+    return _page ? _page->process().processPool().hasServiceWorkerForegroundActivityForTesting() : false;
+#else
+    return false;
+#endif
+}
+
 - (void)_denyNextUserMediaRequest
 {
 #if ENABLE(MEDIA_STREAM)

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h (252417 => 252418)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h	2019-11-13 19:00:20 UTC (rev 252417)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h	2019-11-13 19:15:13 UTC (rev 252418)
@@ -582,5 +582,8 @@
 
 - (void)_processWillSuspendImminentlyForTesting;
 - (void)_processDidResumeForTesting;
+@property (nonatomic, readonly) BOOL _hasServiceWorkerBackgroundActivityForTesting WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+@property (nonatomic, readonly) BOOL _hasServiceWorkerForegroundActivityForTesting WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+- (void)_setAssertionStateForTesting:(int)state WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 @end

Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp (252417 => 252418)


--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp	2019-11-13 19:00:20 UTC (rev 252417)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.cpp	2019-11-13 19:15:13 UTC (rev 252418)
@@ -1228,6 +1228,26 @@
     if (auto* process = WebProcessProxy::processForIdentifier(identifier))
         process->disableServiceWorkers();
 }
+
+void NetworkProcessProxy::registerServiceWorkerClientProcess(WebCore::ProcessIdentifier webProcessIdentifier, WebCore::ProcessIdentifier serviceWorkerProcessIdentifier)
+{
+    auto* webProcess = WebProcessProxy::processForIdentifier(webProcessIdentifier);
+    auto* serviceWorkerProcess = WebProcessProxy::processForIdentifier(serviceWorkerProcessIdentifier);
+    if (!webProcess || !serviceWorkerProcess)
+        return;
+
+    serviceWorkerProcess->registerServiceWorkerClientProcess(*webProcess);
+}
+
+void NetworkProcessProxy::unregisterServiceWorkerClientProcess(WebCore::ProcessIdentifier webProcessIdentifier, WebCore::ProcessIdentifier serviceWorkerProcessIdentifier)
+{
+    auto* webProcess = WebProcessProxy::processForIdentifier(webProcessIdentifier);
+    auto* serviceWorkerProcess = WebProcessProxy::processForIdentifier(webProcessIdentifier);
+    if (!webProcess || !serviceWorkerProcess)
+        return;
+
+    serviceWorkerProcess->unregisterServiceWorkerClientProcess(*webProcess);
+}
 #endif
 
 void NetworkProcessProxy::requestStorageSpace(PAL::SessionID sessionID, const WebCore::ClientOrigin& origin, uint64_t currentQuota, uint64_t currentSize, uint64_t spaceRequired, CompletionHandler<void(Optional<uint64_t> quota)>&& completionHandler)

Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h (252417 => 252418)


--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h	2019-11-13 19:00:20 UTC (rev 252417)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.h	2019-11-13 19:15:13 UTC (rev 252418)
@@ -246,6 +246,8 @@
 #if ENABLE(SERVICE_WORKER)
     void establishWorkerContextConnectionToNetworkProcess(WebCore::RegistrableDomain&&, PAL::SessionID);
     void workerContextConnectionNoLongerNeeded(WebCore::ProcessIdentifier);
+    void registerServiceWorkerClientProcess(WebCore::ProcessIdentifier webProcessIdentifier, WebCore::ProcessIdentifier serviceWorkerProcessIdentifier);
+    void unregisterServiceWorkerClientProcess(WebCore::ProcessIdentifier webProcessIdentifier, WebCore::ProcessIdentifier serviceWorkerProcessIdentifier);
 #endif
 
     void requestStorageSpace(PAL::SessionID, const WebCore::ClientOrigin&, uint64_t quota, uint64_t currentSize, uint64_t spaceRequired, CompletionHandler<void(Optional<uint64_t> quota)>&&);

Modified: trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in (252417 => 252418)


--- trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in	2019-11-13 19:00:20 UTC (rev 252417)
+++ trunk/Source/WebKit/UIProcess/Network/NetworkProcessProxy.messages.in	2019-11-13 19:15:13 UTC (rev 252418)
@@ -62,6 +62,8 @@
 #if ENABLE(SERVICE_WORKER)
     EstablishWorkerContextConnectionToNetworkProcess(WebCore::RegistrableDomain registrableDomain, PAL::SessionID sessionID)
     WorkerContextConnectionNoLongerNeeded(WebCore::ProcessIdentifier identifier)
+    RegisterServiceWorkerClientProcess(WebCore::ProcessIdentifier webProcessIdentifier, WebCore::ProcessIdentifier serviceWorkerProcessIdentifier)
+    UnregisterServiceWorkerClientProcess(WebCore::ProcessIdentifier webProcessIdentifier, WebCore::ProcessIdentifier serviceWorkerProcessIdentifier)
 #endif
 
     RequestStorageSpace(PAL::SessionID sessionID, struct WebCore::ClientOrigin origin, uint64_t quota, uint64_t currentSize, uint64_t spaceRequired) -> (Optional<uint64_t> newQuota) Async

Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.cpp (252417 => 252418)


--- trunk/Source/WebKit/UIProcess/WebProcessPool.cpp	2019-11-13 19:00:20 UTC (rev 252417)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.cpp	2019-11-13 19:15:13 UTC (rev 252418)
@@ -2046,11 +2046,16 @@
 
 void WebProcessPool::updateProcessAssertions()
 {
+    ensureNetworkProcess().updateProcessAssertion();
+    // Check on next run loop since the web process proxy tokens are probably being updated.
+    callOnMainRunLoop([this, weakThis = makeWeakPtr(this)] {
+        if (!weakThis)
+            return;
 #if ENABLE(SERVICE_WORKER)
-    for (auto* serviceWorkerProcess : m_serviceWorkerProcesses.values())
-        serviceWorkerProcess->updateServiceWorkerProcessAssertion();
+        for (auto* serviceWorkerProcess : m_serviceWorkerProcesses.values())
+            serviceWorkerProcess->updateServiceWorkerProcessAssertion();
 #endif
-    ensureNetworkProcess().updateProcessAssertion();
+    });
 }
 
 bool WebProcessPool::isServiceWorkerPageID(WebPageProxyIdentifier pageID) const
@@ -2397,4 +2402,20 @@
     terminateNetworkProcess();
 }
 
+#if ENABLE(SERVICE_WORKER)
+bool WebProcessPool::hasServiceWorkerForegroundActivityForTesting() const
+{
+    return WTF::anyOf(m_serviceWorkerProcesses.values(), [](auto& process) {
+        return process->hasServiceWorkerForegroundActivityForTesting();
+    });
+}
+
+bool WebProcessPool::hasServiceWorkerBackgroundActivityForTesting() const
+{
+    return WTF::anyOf(m_serviceWorkerProcesses.values(), [](auto& process) {
+        return process->hasServiceWorkerBackgroundActivityForTesting();
+    });
+}
+#endif
+
 } // namespace WebKit

Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.h (252417 => 252418)


--- trunk/Source/WebKit/UIProcess/WebProcessPool.h	2019-11-13 19:00:20 UTC (rev 252417)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.h	2019-11-13 19:15:13 UTC (rev 252418)
@@ -396,6 +396,8 @@
     bool allowsAnySSLCertificateForServiceWorker() const { return m_allowsAnySSLCertificateForServiceWorker; }
     void updateServiceWorkerUserAgent(const String& userAgent);
     const Optional<UserContentControllerIdentifier>& userContentControllerIdentifierForServiceWorkers() const { return m_userContentControllerIDForServiceWorker; }
+    bool hasServiceWorkerForegroundActivityForTesting() const;
+    bool hasServiceWorkerBackgroundActivityForTesting() const;
 #endif
 
 #if PLATFORM(COCOA)

Modified: trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp (252417 => 252418)


--- trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp	2019-11-13 19:00:20 UTC (rev 252417)
+++ trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp	2019-11-13 19:15:13 UTC (rev 252418)
@@ -1565,13 +1565,19 @@
     if (!m_serviceWorkerInformation)
         return;
 
-    // FIXME: We could do better if we knew which WebContent processes needed this service worker process.
-    if (processPool().hasForegroundWebProcesses()) {
+    bool shouldTakeForegroundActivity = WTF::anyOf(m_serviceWorkerInformation->clientProcesses, [](auto& process) {
+        return !!process.m_foregroundToken;
+    });
+    if (shouldTakeForegroundActivity) {
         if (!ProcessThrottler::isValidForegroundActivity(m_serviceWorkerInformation->activity))
             m_serviceWorkerInformation->activity = m_throttler.foregroundActivity("Service Worker for foreground view(s)"_s);
         return;
     }
-    if (processPool().hasBackgroundWebProcesses()) {
+
+    bool shouldTakeBackgroundActivity = WTF::anyOf(m_serviceWorkerInformation->clientProcesses, [](auto& process) {
+        return !!process.m_backgroundToken;
+    });
+    if (shouldTakeBackgroundActivity) {
         if (!ProcessThrottler::isValidBackgroundActivity(m_serviceWorkerInformation->activity))
             m_serviceWorkerInformation->activity = m_throttler.backgroundActivity("Service Worker for background view(s)"_s);
         return;
@@ -1578,6 +1584,34 @@
     }
     m_serviceWorkerInformation->activity = nullptr;
 }
+
+void WebProcessProxy::registerServiceWorkerClientProcess(WebProcessProxy& proxy)
+{
+    if (!m_serviceWorkerInformation)
+        return;
+
+    m_serviceWorkerInformation->clientProcesses.add(proxy);
+    updateServiceWorkerProcessAssertion();
+}
+
+void WebProcessProxy::unregisterServiceWorkerClientProcess(WebProcessProxy& proxy)
+{
+    if (!m_serviceWorkerInformation)
+        return;
+
+    m_serviceWorkerInformation->clientProcesses.remove(proxy);
+    updateServiceWorkerProcessAssertion();
+}
+
+bool WebProcessProxy::hasServiceWorkerForegroundActivityForTesting() const
+{
+    return m_serviceWorkerInformation ? ProcessThrottler::isValidForegroundActivity(m_serviceWorkerInformation->activity) : false;
+}
+
+bool WebProcessProxy::hasServiceWorkerBackgroundActivityForTesting() const
+{
+    return m_serviceWorkerInformation ? ProcessThrottler::isValidBackgroundActivity(m_serviceWorkerInformation->activity) : false;
+}
 #endif // ENABLE(SERVICE_WORKER)
 
 void WebProcessProxy::disableServiceWorkers()
@@ -1627,6 +1661,7 @@
 #endif
         },
         nullptr,
+        { }
     };
 #if ENABLE(SERVICE_WORKER)
     updateServiceWorkerProcessAssertion();

Modified: trunk/Source/WebKit/UIProcess/WebProcessProxy.h (252417 => 252418)


--- trunk/Source/WebKit/UIProcess/WebProcessProxy.h	2019-11-13 19:00:20 UTC (rev 252417)
+++ trunk/Source/WebKit/UIProcess/WebProcessProxy.h	2019-11-13 19:15:13 UTC (rev 252418)
@@ -53,6 +53,7 @@
 #include <wtf/HashSet.h>
 #include <wtf/RefCounted.h>
 #include <wtf/RefPtr.h>
+#include <wtf/WeakHashSet.h>
 
 namespace API {
 class Navigation;
@@ -339,7 +340,12 @@
     void updateServiceWorkerPreferencesStore(const WebPreferencesStore&);
     bool hasServiceWorkerPageProxy(WebPageProxyIdentifier pageProxyID) { return m_serviceWorkerInformation && m_serviceWorkerInformation->serviceWorkerPageProxyID == pageProxyID; }
     void updateServiceWorkerProcessAssertion();
+    void registerServiceWorkerClientProcess(WebProcessProxy&);
+    void unregisterServiceWorkerClientProcess(WebProcessProxy&);
+    bool hasServiceWorkerForegroundActivityForTesting() const;
+    bool hasServiceWorkerBackgroundActivityForTesting() const;
 #endif
+    void setAssertionStateForTesting(AssertionState state) { didSetAssertionState(state); }
 
 protected:
     WebProcessProxy(WebProcessPool&, WebsiteDataStore*, IsPrewarmed);
@@ -527,6 +533,7 @@
         WebCore::PageIdentifier serviceWorkerPageID;
         ServiceWorkerInitializationData initializationData;
         ProcessThrottler::ActivityVariant activity;
+        WeakHashSet<WebProcessProxy> clientProcesses;
     };
     Optional<ServiceWorkerInformation> m_serviceWorkerInformation;
 };

Modified: trunk/Tools/ChangeLog (252417 => 252418)


--- trunk/Tools/ChangeLog	2019-11-13 19:00:20 UTC (rev 252417)
+++ trunk/Tools/ChangeLog	2019-11-13 19:15:13 UTC (rev 252418)
@@ -1,3 +1,13 @@
+2019-11-13  Youenn Fablet  <[email protected]>
+
+        Take service worker assertions based on client processes assertion states
+        https://bugs.webkit.org/show_bug.cgi?id=204119
+
+        Reviewed by Chris Dumez.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm:
+        Add tests checking service worker process assertion state.
+
 2019-11-13  Aakash Jain  <[email protected]>
 
         Make webkitperl EWS robust against flakiness in webkitperl tests

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm (252417 => 252418)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm	2019-11-13 19:00:20 UTC (rev 252417)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ServiceWorkerBasic.mm	2019-11-13 19:15:13 UTC (rev 252418)
@@ -1614,6 +1614,77 @@
     EXPECT_EQ(2u, launchServiceWorkerProcess(useSeparateServiceWorkerProcess));
 }
 
+void waitUntilServiceWorkerProcessForegroundActivityState(WKWebView *page, bool shouldHaveActivity)
+{
+    do {
+        if (page._hasServiceWorkerForegroundActivityForTesting == shouldHaveActivity)
+            return;
+        TestWebKitAPI::Util::spinRunLoop(1);
+    } while (true);
+}
+
+void waitUntilServiceWorkerProcessBackgroundActivityState(WKWebView *page, bool shouldHaveActivity)
+{
+    do {
+        if (page._hasServiceWorkerBackgroundActivityForTesting == shouldHaveActivity)
+            return;
+        TestWebKitAPI::Util::spinRunLoop(1);
+    } while (true);
+}
+
+void testSuspendServiceWorkerProcessBasedOnClientProcesses(bool useSeparateServiceWorkerProcess)
+{
+    [WKWebsiteDataStore _allowWebsiteDataRecordsForAllOrigins];
+
+    // Start with a clean slate data store
+    [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:^() {
+        done = true;
+    }];
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+
+    auto messageHandler = adoptNS([[SWMessageHandler alloc] init]);
+    [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"sw"];
+
+    ServiceWorkerTCPServer server({
+        { "text/html", mainBytes },
+        { "application/_javascript_", scriptBytes },
+    });
+
+    auto *processPool = configuration.get().processPool;
+    [processPool _setUseSeparateServiceWorkerProcess: useSeparateServiceWorkerProcess];
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
+
+    [webView loadRequest:server.request()];
+
+    waitUntilServiceWorkerProcessCount(processPool, 1);
+
+    [webView _setAssertionStateForTesting: 1];
+    waitUntilServiceWorkerProcessForegroundActivityState(webView.get(), false);
+    waitUntilServiceWorkerProcessBackgroundActivityState(webView.get(), true);
+
+    [webView _setAssertionStateForTesting: 3];
+    waitUntilServiceWorkerProcessForegroundActivityState(webView.get(), true);
+    waitUntilServiceWorkerProcessBackgroundActivityState(webView.get(), false);
+
+    [webView _setAssertionStateForTesting: 0];
+    waitUntilServiceWorkerProcessBackgroundActivityState(webView.get(), false);
+    waitUntilServiceWorkerProcessForegroundActivityState(webView.get(), false);
+}
+
+TEST(ServiceWorkers, SuspendServiceWorkerProcessBasedOnClientProcesses)
+{
+    bool useSeparateServiceWorkerProcess = false;
+    testSuspendServiceWorkerProcessBasedOnClientProcesses(useSeparateServiceWorkerProcess);
+
+    useSeparateServiceWorkerProcess = true;
+    testSuspendServiceWorkerProcessBasedOnClientProcesses(useSeparateServiceWorkerProcess);
+}
+
+
 TEST(ServiceWorkers, DISABLED_ThrottleCrash)
 {
     [WKWebsiteDataStore _allowWebsiteDataRecordsForAllOrigins];
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to