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];