Title: [277837] trunk
Revision
277837
Author
[email protected]
Date
2021-05-20 16:39:30 -0700 (Thu, 20 May 2021)

Log Message

Mark ServiceWorkerThreadProxy with a default app-bound value
https://bugs.webkit.org/show_bug.cgi?id=223201
<rdar://problem/77664416>

Reviewed by Youenn Fablet.

Source/WebCore:

Service worker loads have their own document loader, so they don't
always get properly marked as app-bound based on the main frame
navigation. Prior fixes handled some fetch events, synthetic
responses, and soft updates. But we need to set a default value when
we install the service worker.

We had to pick a best-effort heuristic to do this. If any client for
the worker is app-bound, then all loads with that worker will be
marked app-bound.

* testing/ServiceWorkerInternals.cpp:
(WebCore::ServiceWorkerInternals::lastNavigationWasAppBound):
* testing/ServiceWorkerInternals.h:
* testing/ServiceWorkerInternals.idl:
* workers/WorkerRunLoop.h:
To test this, I added a new API to ServiceWorkerInternals to get the
worker's app bound value.

* workers/service/ServiceWorkerClientData.cpp:
(WebCore::ServiceWorkerClientData::isolatedCopy const):
(WebCore::ServiceWorkerClientData::from):
* workers/service/ServiceWorkerClientData.h:
(WebCore::ServiceWorkerClientData::encode const):
(WebCore::ServiceWorkerClientData::decode):
Store the main navigation app-bound value when we register a client.

* workers/service/ServiceWorkerContextData.cpp:
(WebCore::ServiceWorkerContextData::isolatedCopy const):
* workers/service/ServiceWorkerContextData.h:
(WebCore::ServiceWorkerContextData::encode const):
(WebCore::ServiceWorkerContextData::decode):
* workers/service/context/ServiceWorkerThreadProxy.cpp:
(WebCore::ServiceWorkerThreadProxy::ServiceWorkerThreadProxy):
(WebCore::ServiceWorkerThreadProxy::lastNavigationWasAppBound):
* workers/service/context/ServiceWorkerThreadProxy.h:
* workers/service/server/RegistrationDatabase.cpp:
(WebCore::RegistrationDatabase::importRecords):
* workers/service/server/SWServer.cpp:
(WebCore::SWServer::updateWorker):
(WebCore::SWServer::clientIsAppBoundForRegistrableDomain):
Best-effort heuristic to mark a load as app bound if any client for
that origin was registered as app-bound.

Source/WebKit:

* NetworkProcess/ServiceWorker/WebSWServerConnection.cpp:
(WebKit::WebSWServerConnection::controlClient):
* NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
(WebKit::WebSWServerToContextConnection::updateAppBoundValue):
* NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h:
* Scripts/webkit/messages.py:
(headers_for_type):
* WebProcess/Storage/WebSWContextManagerConnection.cpp:
(WebKit::WebSWContextManagerConnection::updateAppBoundValue):
* WebProcess/Storage/WebSWContextManagerConnection.h:
* WebProcess/Storage/WebSWContextManagerConnection.messages.in:

Tools:

Test coverage.

* TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm:
(-[SWAppBoundRequestMessageHandler userContentController:didReceiveScriptMessage:]):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (277836 => 277837)


--- trunk/Source/WebCore/ChangeLog	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/ChangeLog	2021-05-20 23:39:30 UTC (rev 277837)
@@ -1,3 +1,54 @@
+2021-05-20  Kate Cheney  <[email protected]>
+
+        Mark ServiceWorkerThreadProxy with a default app-bound value
+        https://bugs.webkit.org/show_bug.cgi?id=223201
+        <rdar://problem/77664416>
+
+        Reviewed by Youenn Fablet.
+
+        Service worker loads have their own document loader, so they don't
+        always get properly marked as app-bound based on the main frame
+        navigation. Prior fixes handled some fetch events, synthetic
+        responses, and soft updates. But we need to set a default value when
+        we install the service worker.
+
+        We had to pick a best-effort heuristic to do this. If any client for
+        the worker is app-bound, then all loads with that worker will be
+        marked app-bound.
+
+        * testing/ServiceWorkerInternals.cpp:
+        (WebCore::ServiceWorkerInternals::lastNavigationWasAppBound):
+        * testing/ServiceWorkerInternals.h:
+        * testing/ServiceWorkerInternals.idl:
+        * workers/WorkerRunLoop.h:
+        To test this, I added a new API to ServiceWorkerInternals to get the
+        worker's app bound value.
+
+        * workers/service/ServiceWorkerClientData.cpp:
+        (WebCore::ServiceWorkerClientData::isolatedCopy const):
+        (WebCore::ServiceWorkerClientData::from):
+        * workers/service/ServiceWorkerClientData.h:
+        (WebCore::ServiceWorkerClientData::encode const):
+        (WebCore::ServiceWorkerClientData::decode):
+        Store the main navigation app-bound value when we register a client.
+
+        * workers/service/ServiceWorkerContextData.cpp:
+        (WebCore::ServiceWorkerContextData::isolatedCopy const):
+        * workers/service/ServiceWorkerContextData.h:
+        (WebCore::ServiceWorkerContextData::encode const):
+        (WebCore::ServiceWorkerContextData::decode):
+        * workers/service/context/ServiceWorkerThreadProxy.cpp:
+        (WebCore::ServiceWorkerThreadProxy::ServiceWorkerThreadProxy):
+        (WebCore::ServiceWorkerThreadProxy::lastNavigationWasAppBound):
+        * workers/service/context/ServiceWorkerThreadProxy.h:
+        * workers/service/server/RegistrationDatabase.cpp:
+        (WebCore::RegistrationDatabase::importRecords):
+        * workers/service/server/SWServer.cpp:
+        (WebCore::SWServer::updateWorker):
+        (WebCore::SWServer::clientIsAppBoundForRegistrableDomain):
+        Best-effort heuristic to mark a load as app bound if any client for
+        that origin was registered as app-bound.
+
 2021-05-20  Sam Weinig  <[email protected]>
 
         Fix inverted ASSERT in sampleColor.

Modified: trunk/Source/WebCore/testing/ServiceWorkerInternals.cpp (277836 => 277837)


--- trunk/Source/WebCore/testing/ServiceWorkerInternals.cpp	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/testing/ServiceWorkerInternals.cpp	2021-05-20 23:39:30 UTC (rev 277837)
@@ -108,6 +108,23 @@
     return getCurrentProcessID();
 }
 
+void ServiceWorkerInternals::lastNavigationWasAppBound(Ref<DeferredPromise>&& promise)
+{
+    ASSERT(!m_lastNavigationWasAppBoundPromise);
+    m_lastNavigationWasAppBoundPromise = WTFMove(promise);
+    callOnMainThread([identifier = m_identifier, weakThis = makeWeakPtr(this)]() mutable {
+        if (auto* proxy = SWContextManager::singleton().workerByID(identifier)) {
+            proxy->thread().runLoop().postTaskForMode([weakThis = WTFMove(weakThis), appBound = proxy->lastNavigationWasAppBound()](auto&) {
+                if (!weakThis || !weakThis->m_lastNavigationWasAppBoundPromise)
+                    return;
+
+                weakThis->m_lastNavigationWasAppBoundPromise->resolve<IDLBoolean>(appBound);
+                weakThis->m_lastNavigationWasAppBoundPromise = nullptr;
+            }, WorkerRunLoop::defaultMode());
+        }
+    });
+}
+
 } // namespace WebCore
 
 #endif

Modified: trunk/Source/WebCore/testing/ServiceWorkerInternals.h (277836 => 277837)


--- trunk/Source/WebCore/testing/ServiceWorkerInternals.h	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/testing/ServiceWorkerInternals.h	2021-05-20 23:39:30 UTC (rev 277837)
@@ -28,6 +28,7 @@
 #if ENABLE(SERVICE_WORKER)
 
 #include "IDLTypes.h"
+#include "JSDOMPromiseDeferred.h"
 #include "ServiceWorkerIdentifier.h"
 #include <wtf/RefCounted.h>
 
@@ -39,7 +40,7 @@
 
 template<typename IDLType> class DOMPromiseDeferred;
 
-class WEBCORE_TESTSUPPORT_EXPORT ServiceWorkerInternals : public RefCounted<ServiceWorkerInternals> {
+class WEBCORE_TESTSUPPORT_EXPORT ServiceWorkerInternals : public RefCounted<ServiceWorkerInternals>, public CanMakeWeakPtr<ServiceWorkerInternals> {
 public:
     static Ref<ServiceWorkerInternals> create(ServiceWorkerIdentifier identifier) { return adoptRef(*new ServiceWorkerInternals { identifier }); }
     ~ServiceWorkerInternals();
@@ -57,10 +58,13 @@
 
     int processIdentifier() const;
 
+    void lastNavigationWasAppBound(Ref<DeferredPromise>&&);
+
 private:
     explicit ServiceWorkerInternals(ServiceWorkerIdentifier);
 
     ServiceWorkerIdentifier m_identifier;
+    RefPtr<DeferredPromise> m_lastNavigationWasAppBoundPromise;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/testing/ServiceWorkerInternals.idl (277836 => 277837)


--- trunk/Source/WebCore/testing/ServiceWorkerInternals.idl	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/testing/ServiceWorkerInternals.idl	2021-05-20 23:39:30 UTC (rev 277837)
@@ -40,4 +40,6 @@
     readonly attribute boolean isThrottleable;
 
     readonly attribute long processIdentifier;
+
+    Promise<boolean> lastNavigationWasAppBound();
 };

Modified: trunk/Source/WebCore/workers/WorkerRunLoop.h (277836 => 277837)


--- trunk/Source/WebCore/workers/WorkerRunLoop.h	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/workers/WorkerRunLoop.h	2021-05-20 23:39:30 UTC (rev 277837)
@@ -60,12 +60,12 @@
 
         void postTask(ScriptExecutionContext::Task&&);
         void postTaskAndTerminate(ScriptExecutionContext::Task&&);
-        void postTaskForMode(ScriptExecutionContext::Task&&, const String& mode);
+        WEBCORE_EXPORT void postTaskForMode(ScriptExecutionContext::Task&&, const String& mode);
         void postDebuggerTask(ScriptExecutionContext::Task&&);
 
         unsigned long createUniqueId() { return ++m_uniqueId; }
 
-        static String defaultMode();
+        WEBCORE_EXPORT static String defaultMode();
         class Task {
             WTF_MAKE_NONCOPYABLE(Task); WTF_MAKE_FAST_ALLOCATED;
         public:

Modified: trunk/Source/WebCore/workers/service/ServiceWorkerClientData.cpp (277836 => 277837)


--- trunk/Source/WebCore/workers/service/ServiceWorkerClientData.cpp	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerClientData.cpp	2021-05-20 23:39:30 UTC (rev 277837)
@@ -30,6 +30,7 @@
 
 #include "DOMWindow.h"
 #include "Document.h"
+#include "DocumentLoader.h"
 #include "Frame.h"
 #include "SWClientConnection.h"
 
@@ -57,7 +58,7 @@
 
 ServiceWorkerClientData ServiceWorkerClientData::isolatedCopy() const
 {
-    return { identifier, type, frameType, url.isolatedCopy() };
+    return { identifier, type, frameType, url.isolatedCopy(), lastNavigationWasAppBound };
 }
 
 ServiceWorkerClientData ServiceWorkerClientData::from(ScriptExecutionContext& context, SWClientConnection& connection)
@@ -65,11 +66,14 @@
     bool isDocument = is<Document>(context);
     RELEASE_ASSERT(isDocument); // We do not support dedicated workers as clients yet.
 
+    auto& document = downcast<Document>(context);
+    auto lastNavigationWasAppBound = document.loader() && document.loader()->lastNavigationWasAppBound() ? LastNavigationWasAppBound::Yes : LastNavigationWasAppBound::No;
+
     return {
-        { connection.serverConnectionIdentifier(), downcast<Document>(context).identifier() },
+        { connection.serverConnectionIdentifier(), document.identifier() },
         isDocument ? ServiceWorkerClientType::Window : ServiceWorkerClientType::Worker,
         toServiceWorkerClientFrameType(context),
-        context.url()
+        context.url(), lastNavigationWasAppBound
     };
 }
 

Modified: trunk/Source/WebCore/workers/service/ServiceWorkerClientData.h (277836 => 277837)


--- trunk/Source/WebCore/workers/service/ServiceWorkerClientData.h	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerClientData.h	2021-05-20 23:39:30 UTC (rev 277837)
@@ -37,11 +37,14 @@
 class SWClientConnection;
 class ScriptExecutionContext;
 
+enum class LastNavigationWasAppBound : bool { No, Yes };
+
 struct ServiceWorkerClientData {
     ServiceWorkerClientIdentifier identifier;
     ServiceWorkerClientType type;
     ServiceWorkerClientFrameType frameType;
     URL url;
+    LastNavigationWasAppBound lastNavigationWasAppBound;
 
     ServiceWorkerClientData isolatedCopy() const;
 
@@ -54,7 +57,7 @@
 template<class Encoder>
 void ServiceWorkerClientData::encode(Encoder& encoder) const
 {
-    encoder << identifier << type << frameType << url;
+    encoder << identifier << type << frameType << url << lastNavigationWasAppBound;
 }
 
 template<class Decoder>
@@ -80,7 +83,12 @@
     if (!url)
         return WTF::nullopt;
 
-    return { { WTFMove(*identifier), WTFMove(*type), WTFMove(*frameType), WTFMove(*url) } };
+    Optional<LastNavigationWasAppBound> lastNavigationWasAppBound;
+    decoder >> lastNavigationWasAppBound;
+    if (!lastNavigationWasAppBound)
+        return WTF::nullopt;
+
+    return { { WTFMove(*identifier), WTFMove(*type), WTFMove(*frameType), WTFMove(*url), WTFMove(*lastNavigationWasAppBound) } };
 }
 
 using ServiceWorkerClientsMatchAllCallback = WTF::CompletionHandler<void(Vector<ServiceWorkerClientData>&&)>;

Modified: trunk/Source/WebCore/workers/service/ServiceWorkerContextData.cpp (277836 => 277837)


--- trunk/Source/WebCore/workers/service/ServiceWorkerContextData.cpp	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerContextData.cpp	2021-05-20 23:39:30 UTC (rev 277837)
@@ -44,6 +44,7 @@
         scriptURL.isolatedCopy(),
         workerType,
         loadedFromDisk,
+        lastNavigationWasAppBound,
         crossThreadCopy(scriptResourceMap)
     };
 }

Modified: trunk/Source/WebCore/workers/service/ServiceWorkerContextData.h (277836 => 277837)


--- trunk/Source/WebCore/workers/service/ServiceWorkerContextData.h	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/workers/service/ServiceWorkerContextData.h	2021-05-20 23:39:30 UTC (rev 277837)
@@ -39,6 +39,8 @@
 
 namespace WebCore {
 
+enum class LastNavigationWasAppBound : bool;
+
 struct ServiceWorkerContextData {
     struct ImportedScript {
         ScriptBuffer script;
@@ -87,6 +89,7 @@
     URL scriptURL;
     WorkerType workerType;
     bool loadedFromDisk;
+    Optional<LastNavigationWasAppBound> lastNavigationWasAppBound;
     HashMap<URL, ImportedScript> scriptResourceMap;
 
     template<class Encoder> void encode(Encoder&) const;
@@ -99,7 +102,7 @@
 void ServiceWorkerContextData::encode(Encoder& encoder) const
 {
     encoder << jobDataIdentifier << registration << serviceWorkerIdentifier << script << contentSecurityPolicy << referrerPolicy
-        << scriptURL << workerType << loadedFromDisk << scriptResourceMap << certificateInfo;
+        << scriptURL << workerType << loadedFromDisk << lastNavigationWasAppBound << scriptResourceMap << certificateInfo;
 }
 
 template<class Decoder>
@@ -144,6 +147,10 @@
     if (!decoder.decode(loadedFromDisk))
         return WTF::nullopt;
 
+    Optional<LastNavigationWasAppBound> lastNavigationWasAppBound;
+    if (!decoder.decode(lastNavigationWasAppBound))
+        return WTF::nullopt;
+
     HashMap<URL, ImportedScript> scriptResourceMap;
     if (!decoder.decode(scriptResourceMap))
         return WTF::nullopt;
@@ -164,6 +171,7 @@
         WTFMove(scriptURL),
         workerType,
         loadedFromDisk,
+        WTFMove(lastNavigationWasAppBound),
         WTFMove(scriptResourceMap)
     }};
 }

Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp (277836 => 277837)


--- trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.cpp	2021-05-20 23:39:30 UTC (rev 277837)
@@ -116,6 +116,9 @@
     m_remoteDebuggable->setRemoteDebuggingAllowed(true);
     m_remoteDebuggable->init();
 #endif
+
+    if (data.lastNavigationWasAppBound)
+        setLastNavigationWasAppBound(data.lastNavigationWasAppBound == LastNavigationWasAppBound::Yes);
 }
 
 ServiceWorkerThreadProxy::~ServiceWorkerThreadProxy()
@@ -130,6 +133,11 @@
         m_document->loader()->setLastNavigationWasAppBound(wasAppBound);
 }
 
+bool ServiceWorkerThreadProxy::lastNavigationWasAppBound()
+{
+    return m_document->loader() ? m_document->loader()->lastNavigationWasAppBound() : false;
+}
+
 bool ServiceWorkerThreadProxy::postTaskForModeToWorkerOrWorkletGlobalScope(ScriptExecutionContext::Task&& task, const String& mode)
 {
     if (m_isTerminatingOrTerminated)

Modified: trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.h (277836 => 277837)


--- trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.h	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/workers/service/context/ServiceWorkerThreadProxy.h	2021-05-20 23:39:30 UTC (rev 277837)
@@ -82,6 +82,7 @@
     void didSaveScriptsToDisk(ScriptBuffer&&, HashMap<URL, ScriptBuffer>&& importedScripts);
 
     WEBCORE_EXPORT void setLastNavigationWasAppBound(bool);
+    WEBCORE_EXPORT bool lastNavigationWasAppBound();
 
 private:
     WEBCORE_EXPORT ServiceWorkerThreadProxy(PageConfiguration&&, ServiceWorkerContextData&&, String&& userAgent, CacheStorageProvider&, StorageBlockingPolicy);

Modified: trunk/Source/WebCore/workers/service/server/RegistrationDatabase.cpp (277836 => 277837)


--- trunk/Source/WebCore/workers/service/server/RegistrationDatabase.cpp	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/workers/service/server/RegistrationDatabase.cpp	2021-05-20 23:39:30 UTC (rev 277837)
@@ -569,7 +569,7 @@
         auto registrationIdentifier = ServiceWorkerRegistrationIdentifier::generate();
         auto serviceWorkerData = ServiceWorkerData { workerIdentifier, scriptURL, ServiceWorkerState::Activated, *workerType, registrationIdentifier };
         auto registration = ServiceWorkerRegistrationData { WTFMove(*key), registrationIdentifier, WTFMove(scopeURL), *updateViaCache, lastUpdateCheckTime, WTF::nullopt, WTF::nullopt, WTFMove(serviceWorkerData) };
-        auto contextData = ServiceWorkerContextData { WTF::nullopt, WTFMove(registration), workerIdentifier, WTFMove(script), WTFMove(*certificateInfo), WTFMove(*contentSecurityPolicy), WTFMove(referrerPolicy), WTFMove(scriptURL), *workerType, true, WTFMove(scriptResourceMap) };
+        auto contextData = ServiceWorkerContextData { WTF::nullopt, WTFMove(registration), workerIdentifier, WTFMove(script), WTFMove(*certificateInfo), WTFMove(*contentSecurityPolicy), WTFMove(referrerPolicy), WTFMove(scriptURL), *workerType, true, LastNavigationWasAppBound::No, WTFMove(scriptResourceMap) };
 
         callOnMainThread([protectedThis = makeRef(*this), contextData = contextData.isolatedCopy()]() mutable {
             protectedThis->addRegistrationToStore(WTFMove(contextData));

Modified: trunk/Source/WebCore/workers/service/server/SWServer.cpp (277836 => 277837)


--- trunk/Source/WebCore/workers/service/server/SWServer.cpp	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/workers/service/server/SWServer.cpp	2021-05-20 23:39:30 UTC (rev 277837)
@@ -648,9 +648,26 @@
 
 void SWServer::updateWorker(const ServiceWorkerJobDataIdentifier& jobDataIdentifier, SWServerRegistration& registration, const URL& url, const ScriptBuffer& script, const CertificateInfo& certificateInfo, const ContentSecurityPolicyResponseHeaders& contentSecurityPolicy, const String& referrerPolicy, WorkerType type, HashMap<URL, ServiceWorkerContextData::ImportedScript>&& scriptResourceMap)
 {
-    tryInstallContextData(ServiceWorkerContextData { jobDataIdentifier, registration.data(), ServiceWorkerIdentifier::generate(), script, certificateInfo, contentSecurityPolicy, referrerPolicy, url, type, false, WTFMove(scriptResourceMap) });
+    tryInstallContextData(ServiceWorkerContextData { jobDataIdentifier, registration.data(), ServiceWorkerIdentifier::generate(), script, certificateInfo, contentSecurityPolicy, referrerPolicy, url, type, false, clientIsAppBoundForRegistrableDomain(RegistrableDomain(url)), WTFMove(scriptResourceMap) });
 }
 
+LastNavigationWasAppBound SWServer::clientIsAppBoundForRegistrableDomain(const RegistrableDomain& domain)
+{
+    auto clientsByRegistrableDomainIterator = m_clientsByRegistrableDomain.find(domain);
+    if (clientsByRegistrableDomainIterator == m_clientsByRegistrableDomain.end())
+        return LastNavigationWasAppBound::No;
+
+    auto& clientsForRegistrableDomain = clientsByRegistrableDomainIterator->value;
+    for (auto& client : clientsForRegistrableDomain) {
+        auto data = ""
+        ASSERT(data != m_clientsById.end());
+        if (data->value.lastNavigationWasAppBound == LastNavigationWasAppBound::Yes)
+            return LastNavigationWasAppBound::Yes;
+    }
+
+    return LastNavigationWasAppBound::No;
+}
+
 void SWServer::tryInstallContextData(ServiceWorkerContextData&& data)
 {
     RegistrableDomain registrableDomain(data.scriptURL);
@@ -869,10 +886,24 @@
     return iterator->value->registration();
 }
 
+void SWServer::updateAppBoundValueForWorkers(const ClientOrigin& clientOrigin, LastNavigationWasAppBound lastNavigationWasAppBound)
+{
+    for (auto& worker : m_runningOrTerminatingWorkers.values()) {
+        if (worker->origin().clientRegistrableDomain() == clientOrigin.clientRegistrableDomain())
+            worker->updateAppBoundValue(lastNavigationWasAppBound);
+    }
+}
+
 void SWServer::registerServiceWorkerClient(ClientOrigin&& clientOrigin, ServiceWorkerClientData&& data, const Optional<ServiceWorkerRegistrationIdentifier>& controllingServiceWorkerRegistrationIdentifier, String&& userAgent)
 {
     auto clientIdentifier = data.identifier;
 
+    // Update the app-bound value if the new client is app-bound and the current clients for the origin are not marked app-bound.
+    if (data.lastNavigationWasAppBound == LastNavigationWasAppBound::Yes) {
+        if (clientIsAppBoundForRegistrableDomain(clientOrigin.clientRegistrableDomain()) == LastNavigationWasAppBound::No)
+            updateAppBoundValueForWorkers(clientOrigin, data.lastNavigationWasAppBound);
+    }
+
     ASSERT(!m_clientsById.contains(clientIdentifier));
     m_clientsById.add(clientIdentifier, WTFMove(data));
 
@@ -908,6 +939,7 @@
 void SWServer::unregisterServiceWorkerClient(const ClientOrigin& clientOrigin, ServiceWorkerClientIdentifier clientIdentifier)
 {
     auto clientRegistrableDomain = clientOrigin.clientRegistrableDomain();
+    auto appBoundValueBefore = clientIsAppBoundForRegistrableDomain(clientOrigin.clientRegistrableDomain());
 
     bool wasRemoved = m_clientsById.remove(clientIdentifier);
     ASSERT_UNUSED(wasRemoved, wasRemoved);
@@ -950,6 +982,12 @@
     if (clientsForRegistrableDomain.isEmpty())
         m_clientsByRegistrableDomain.remove(clientsByRegistrableDomainIterator);
 
+    // If the app-bound value changed after this client was removed, we know it was the only app-bound
+    // client for its origin, and we should update all workers to reflect this.
+    auto appBoundValueAfter = clientIsAppBoundForRegistrableDomain(clientOrigin.clientRegistrableDomain());
+    if (appBoundValueBefore != appBoundValueAfter)
+        updateAppBoundValueForWorkers(clientOrigin, appBoundValueAfter);
+
     auto registrationIterator = m_clientToControllingRegistration.find(clientIdentifier);
     if (registrationIterator == m_clientToControllingRegistration.end())
         return;

Modified: trunk/Source/WebCore/workers/service/server/SWServer.h (277836 => 277837)


--- trunk/Source/WebCore/workers/service/server/SWServer.h	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/workers/service/server/SWServer.h	2021-05-20 23:39:30 UTC (rev 277837)
@@ -217,6 +217,8 @@
 
     static constexpr Seconds defaultTerminationDelay = 10_s;
 
+    LastNavigationWasAppBound clientIsAppBoundForRegistrableDomain(const RegistrableDomain&);
+
 private:
     void validateRegistrationDomain(WebCore::RegistrableDomain, CompletionHandler<void(bool)>&&);
 
@@ -242,6 +244,8 @@
 
     void contextConnectionCreated(SWServerToContextConnection&);
 
+    void updateAppBoundValueForWorkers(const ClientOrigin&, LastNavigationWasAppBound);
+
     HashMap<SWServerConnectionIdentifier, std::unique_ptr<Connection>> m_connections;
     HashMap<ServiceWorkerRegistrationKey, WeakPtr<SWServerRegistration>> m_scopeToRegistrationMap;
     HashMap<ServiceWorkerRegistrationIdentifier, std::unique_ptr<SWServerRegistration>> m_registrations;

Modified: trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.h (277836 => 277837)


--- trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.h	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/workers/service/server/SWServerToContextConnection.h	2021-05-20 23:39:30 UTC (rev 277837)
@@ -52,6 +52,7 @@
 
     // Messages to the SW host process
     virtual void installServiceWorkerContext(const ServiceWorkerContextData&, const String& userAgent) = 0;
+    virtual void updateAppBoundValue(ServiceWorkerIdentifier, LastNavigationWasAppBound) = 0;
     virtual void fireInstallEvent(ServiceWorkerIdentifier) = 0;
     virtual void fireActivateEvent(ServiceWorkerIdentifier) = 0;
     virtual void terminateWorker(ServiceWorkerIdentifier) = 0;

Modified: trunk/Source/WebCore/workers/service/server/SWServerWorker.cpp (277836 => 277837)


--- trunk/Source/WebCore/workers/service/server/SWServerWorker.cpp	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/workers/service/server/SWServerWorker.cpp	2021-05-20 23:39:30 UTC (rev 277837)
@@ -62,6 +62,7 @@
     , m_registrableDomain(m_data.scriptURL)
     , m_scriptResourceMap(WTFMove(scriptResourceMap))
     , m_terminationTimer(*this, &SWServerWorker::terminationTimerFired)
+    , m_lastNavigationWasAppBound(m_server->clientIsAppBoundForRegistrableDomain(m_registrableDomain))
 {
     m_data.scriptURL.removeFragmentIdentifier();
 
@@ -86,9 +87,20 @@
 {
     ASSERT(m_registration);
 
-    return { WTF::nullopt, m_registration->data(), m_data.identifier, m_script, m_certificateInfo, m_contentSecurityPolicy, m_referrerPolicy, m_data.scriptURL, m_data.type, false, m_scriptResourceMap };
+    return { WTF::nullopt, m_registration->data(), m_data.identifier, m_script, m_certificateInfo, m_contentSecurityPolicy, m_referrerPolicy, m_data.scriptURL, m_data.type, false, m_lastNavigationWasAppBound, m_scriptResourceMap };
 }
 
+void SWServerWorker::updateAppBoundValue(LastNavigationWasAppBound lastNavigationWasAppBound)
+{
+    m_lastNavigationWasAppBound = lastNavigationWasAppBound;
+
+    if (!isRunning())
+        return;
+
+    if (auto* connection = contextConnection())
+        connection->updateAppBoundValue(identifier(), lastNavigationWasAppBound);
+}
+
 void SWServerWorker::terminate(CompletionHandler<void()>&& callback)
 {
     if (!m_server)

Modified: trunk/Source/WebCore/workers/service/server/SWServerWorker.h (277836 => 277837)


--- trunk/Source/WebCore/workers/service/server/SWServerWorker.h	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebCore/workers/service/server/SWServerWorker.h	2021-05-20 23:39:30 UTC (rev 277837)
@@ -127,6 +127,7 @@
     void setHasTimedOutAnyFetchTasks() { m_hasTimedOutAnyFetchTasks = true; }
     bool hasTimedOutAnyFetchTasks() const { return m_hasTimedOutAnyFetchTasks; }
     void didFailHeartBeatCheck();
+    void updateAppBoundValue(LastNavigationWasAppBound);
 
 private:
     SWServerWorker(SWServer&, SWServerRegistration&, const URL&, const ScriptBuffer&, const CertificateInfo&, const ContentSecurityPolicyResponseHeaders&, String&& referrerPolicy, WorkerType, ServiceWorkerIdentifier, HashMap<URL, ServiceWorkerContextData::ImportedScript>&&);
@@ -157,6 +158,7 @@
     bool m_hasTimedOutAnyFetchTasks { false };
     Vector<CompletionHandler<void()>> m_terminationCallbacks;
     Timer m_terminationTimer;
+    LastNavigationWasAppBound m_lastNavigationWasAppBound;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebKit/ChangeLog (277836 => 277837)


--- trunk/Source/WebKit/ChangeLog	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebKit/ChangeLog	2021-05-20 23:39:30 UTC (rev 277837)
@@ -1,3 +1,23 @@
+2021-05-20  Kate Cheney  <[email protected]>
+
+        Mark ServiceWorkerThreadProxy with a default app-bound value
+        https://bugs.webkit.org/show_bug.cgi?id=223201
+        <rdar://problem/77664416>
+
+        Reviewed by Youenn Fablet.
+
+        * NetworkProcess/ServiceWorker/WebSWServerConnection.cpp:
+        (WebKit::WebSWServerConnection::controlClient):
+        * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp:
+        (WebKit::WebSWServerToContextConnection::updateAppBoundValue):
+        * NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h:
+        * Scripts/webkit/messages.py:
+        (headers_for_type):
+        * WebProcess/Storage/WebSWContextManagerConnection.cpp:
+        (WebKit::WebSWContextManagerConnection::updateAppBoundValue):
+        * WebProcess/Storage/WebSWContextManagerConnection.h:
+        * WebProcess/Storage/WebSWContextManagerConnection.messages.in:
+
 2021-05-20  Eric Carlson  <[email protected]>
 
         Allow GPU process log channels to be configured

Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp (277836 => 277837)


--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerConnection.cpp	2021-05-20 23:39:30 UTC (rev 277837)
@@ -147,7 +147,7 @@
         unregisterServiceWorkerClient(clientIdentifier);
     });
 
-    ServiceWorkerClientData data { clientIdentifier, ServiceWorkerClientType::Window, ServiceWorkerClientFrameType::None, request.url() };
+    ServiceWorkerClientData data { clientIdentifier, ServiceWorkerClientType::Window, ServiceWorkerClientFrameType::None, request.url(), request.isAppBound() ? WebCore::LastNavigationWasAppBound::Yes : WebCore::LastNavigationWasAppBound::No };
     registerServiceWorkerClient(SecurityOriginData { registration.key().topOrigin() }, WTFMove(data), registration.identifier(), request.httpUserAgent());
 }
 

Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp (277836 => 277837)


--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.cpp	2021-05-20 23:39:30 UTC (rev 277837)
@@ -92,6 +92,11 @@
     send(Messages::WebSWContextManagerConnection::InstallServiceWorker { data, userAgent });
 }
 
+void WebSWServerToContextConnection::updateAppBoundValue(ServiceWorkerIdentifier serviceWorkerIdentifier, WebCore::LastNavigationWasAppBound lastNavigationWasAppBound)
+{
+    send(Messages::WebSWContextManagerConnection::UpdateAppBoundValue(serviceWorkerIdentifier, lastNavigationWasAppBound));
+}
+
 void WebSWServerToContextConnection::fireInstallEvent(ServiceWorkerIdentifier serviceWorkerIdentifier)
 {
     send(Messages::WebSWContextManagerConnection::FireInstallEvent(serviceWorkerIdentifier));

Modified: trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h (277836 => 277837)


--- trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebKit/NetworkProcess/ServiceWorker/WebSWServerToContextConnection.h	2021-05-20 23:39:30 UTC (rev 277837)
@@ -86,6 +86,7 @@
 
     // Messages to the SW host WebProcess
     void installServiceWorkerContext(const WebCore::ServiceWorkerContextData&, const String& userAgent) final;
+    void updateAppBoundValue(WebCore::ServiceWorkerIdentifier, WebCore::LastNavigationWasAppBound) final;
     void fireInstallEvent(WebCore::ServiceWorkerIdentifier) final;
     void fireActivateEvent(WebCore::ServiceWorkerIdentifier) final;
     void terminateWorker(WebCore::ServiceWorkerIdentifier) final;

Modified: trunk/Source/WebKit/Scripts/webkit/messages.py (277836 => 277837)


--- trunk/Source/WebKit/Scripts/webkit/messages.py	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebKit/Scripts/webkit/messages.py	2021-05-20 23:39:30 UTC (rev 277837)
@@ -701,6 +701,7 @@
         'WebCore::InspectorOverlay::Highlight': ['<WebCore/InspectorOverlay.h>'],
         'WebCore::KeyframeValueList': ['<WebCore/GraphicsLayer.h>'],
         'WebCore::KeypressCommand': ['<WebCore/KeyboardEvent.h>'],
+        'WebCore::LastNavigationWasAppBound': ['<WebCore/ServiceWorkerClientData.h>'],
         'WebCore::LegacyCDMSessionClient::MediaKeyErrorCode': ['<WebCore/LegacyCDMSession.h>'],
         'WebCore::LockBackForwardList': ['<WebCore/FrameLoaderTypes.h>'],
         'WebCore::MessagePortChannelProvider::HasActivity': ['<WebCore/MessagePortChannelProvider.h>'],

Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp (277836 => 277837)


--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.cpp	2021-05-20 23:39:30 UTC (rev 277837)
@@ -135,6 +135,12 @@
     setShouldUseShortTimeout(store.getBoolValueForKey(WebPreferencesKey::shouldUseServiceWorkerShortTimeoutKey()));
 }
 
+void WebSWContextManagerConnection::updateAppBoundValue(ServiceWorkerIdentifier serviceWorkerIdentifier, WebCore::LastNavigationWasAppBound lastNavigationWasAppBound)
+{
+    if (auto* serviceWorkerThreadProxy = SWContextManager::singleton().serviceWorkerThreadProxy(serviceWorkerIdentifier))
+        serviceWorkerThreadProxy->setLastNavigationWasAppBound(lastNavigationWasAppBound == WebCore::LastNavigationWasAppBound::Yes);
+}
+
 void WebSWContextManagerConnection::installServiceWorker(ServiceWorkerContextData&& data, String&& userAgent)
 {
     auto pageConfiguration = pageConfigurationWithEmptyClients(WebProcess::singleton().sessionID());

Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h (277836 => 277837)


--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.h	2021-05-20 23:39:30 UTC (rev 277837)
@@ -29,6 +29,7 @@
 
 #include "Connection.h"
 #include "MessageReceiver.h"
+#include "NavigatingToAppBoundDomain.h"
 #include "ShareableResource.h"
 #include "UserContentControllerIdentifier.h"
 #include "WebPageProxyIdentifier.h"
@@ -85,6 +86,7 @@
     void serviceWorkerStarted(Optional<WebCore::ServiceWorkerJobDataIdentifier>, WebCore::ServiceWorkerIdentifier, bool doesHandleFetch) final;
     void serviceWorkerFailedToStart(Optional<WebCore::ServiceWorkerJobDataIdentifier>, WebCore::ServiceWorkerIdentifier, const String& exceptionMessage) final;
     void installServiceWorker(WebCore::ServiceWorkerContextData&&, String&& userAgent);
+    void updateAppBoundValue(WebCore::ServiceWorkerIdentifier, WebCore::LastNavigationWasAppBound);
     void startFetch(WebCore::SWServerConnectionIdentifier, WebCore::ServiceWorkerIdentifier, WebCore::FetchIdentifier, WebCore::ResourceRequest&&, WebCore::FetchOptions&&, IPC::FormDataReference&&, String&& referrer);
     void cancelFetch(WebCore::SWServerConnectionIdentifier, WebCore::ServiceWorkerIdentifier, WebCore::FetchIdentifier);
     void continueDidReceiveFetchResponse(WebCore::SWServerConnectionIdentifier, WebCore::ServiceWorkerIdentifier, WebCore::FetchIdentifier);

Modified: trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in (277836 => 277837)


--- trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Source/WebKit/WebProcess/Storage/WebSWContextManagerConnection.messages.in	2021-05-20 23:39:30 UTC (rev 277837)
@@ -24,6 +24,7 @@
 
 messages -> WebSWContextManagerConnection NotRefCounted {
     InstallServiceWorker(struct WebCore::ServiceWorkerContextData contextData, String userAgent)
+    UpdateAppBoundValue(WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, enum:bool WebCore::LastNavigationWasAppBound lastNavigationWasAppBound)
     StartFetch(WebCore::SWServerConnectionIdentifier serverConnectionIdentifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, WebCore::FetchIdentifier fetchIdentifier, WebCore::ResourceRequest request, struct WebCore::FetchOptions options, IPC::FormDataReference requestBody, String referrer)
     CancelFetch(WebCore::SWServerConnectionIdentifier serverConnectionIdentifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, WebCore::FetchIdentifier fetchIdentifier)
     ContinueDidReceiveFetchResponse(WebCore::SWServerConnectionIdentifier serverConnectionIdentifier, WebCore::ServiceWorkerIdentifier serviceWorkerIdentifier, WebCore::FetchIdentifier fetchIdentifier)

Modified: trunk/Tools/ChangeLog (277836 => 277837)


--- trunk/Tools/ChangeLog	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Tools/ChangeLog	2021-05-20 23:39:30 UTC (rev 277837)
@@ -1,3 +1,16 @@
+2021-05-20  Kate Cheney  <[email protected]>
+
+        Mark ServiceWorkerThreadProxy with a default app-bound value
+        https://bugs.webkit.org/show_bug.cgi?id=223201
+        <rdar://problem/77664416>
+
+        Reviewed by Youenn Fablet.
+
+        Test coverage.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm:
+        (-[SWAppBoundRequestMessageHandler userContentController:didReceiveScriptMessage:]):
+
 2021-05-20  Aakash Jain  <[email protected]>
 
         Use Python 3 for running various scripts on EWS

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm (277836 => 277837)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm	2021-05-20 23:31:35 UTC (rev 277836)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/InAppBrowserPrivacy.mm	2021-05-20 23:39:30 UTC (rev 277837)
@@ -1877,4 +1877,149 @@
 {
     runWebProcessPlugInTest(IsAppBound::No);
 }
+
+#if WK_HAVE_C_SPI
+
+static const char* mainSWBytesDefaultValue = R"SWRESOURCE(
+<script>
+
+function log(msg)
+{
+    window.webkit.messageHandlers.sw.postMessage(msg);
+}
+
+navigator.serviceWorker.addEventListener("message", function(event) {
+    log(event.data);
+});
+
+try {
+    navigator.serviceWorker.register('/sw.js').then(function(reg) {
+        if (reg.active) {
+            worker = reg.active;
+            worker.postMessage("SECOND");
+            return;
+        }
+        worker = reg.installing;
+        worker.addEventListener('statechange', function() {
+            if (worker.state == 'activated')
+                worker.postMessage("FIRST");
+        });
+    }).catch(function(error) {
+        log('Registration failed with: ' + error);
+    });
+} catch(e) {
+    log('Exception: ' + e);
+}
+</script>
+)SWRESOURCE";
+
+static const char* scriptBytesDefaultValue = R"SWRESOURCE(
+self.addEventListener('message', async (event) => {
+    if (!self.internals) {
+        event.source.postMessage('No internals');
+        return;
+    }
+
+    queryAppBoundValue(event, false);
+});
+
+async function queryAppBoundValue(event, haveSentInitialMessage)
+{
+    var result = await internals.lastNavigationWasAppBound();
+    if (result) {
+        if (event.data == "FIRST") {
+            event.source.postMessage('app-bound');
+            return;
+        }
+
+        if (!haveSentInitialMessage)
+            event.source.postMessage('starts app-bound');
+
+        queryAppBoundValue(event, true);
+        return;
+    }
+
+    event.source.postMessage('non app-bound');
+}
+
+)SWRESOURCE";
+
+
+static String expectedMessage;
+static bool receivedMessage = false;
+
+@interface SWAppBoundRequestMessageHandler : NSObject <WKScriptMessageHandler>
+@end
+
+@implementation SWAppBoundRequestMessageHandler
+- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
+{
+    EXPECT_WK_STREQ(message.body, expectedMessage);
+    receivedMessage = true;
+}
+@end
+
+TEST(InAppBrowserPrivacy, RegisterServiceWorkerClientUpdatesAppBoundValue)
+{
+    static bool isDone = false;
+
+    [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:[WKWebsiteDataStore allWebsiteDataTypes] modifiedSince:[NSDate distantPast] completionHandler:^() {
+        isDone = true;
+    }];
+    TestWebKitAPI::Util::run(&isDone);
+
+    WKWebViewConfiguration *configuration = [WKWebViewConfiguration _test_configurationWithTestPlugInClassName:@"WebProcessPlugInWithInternals" configureJSCForTesting:YES];
+    WKRetainPtr<WKContextRef> context = adoptWK(TestWebKitAPI::Util::createContextForInjectedBundleTest("InternalsInjectedBundleTest"));
+    configuration.processPool = (WKProcessPool *)context.get();
+
+    RetainPtr<SWAppBoundRequestMessageHandler> messageHandler = adoptNS([[SWAppBoundRequestMessageHandler alloc] init]);
+    [[configuration userContentController] addScriptMessageHandler:messageHandler.get() name:@"sw"];
+
+    auto webView1 = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration]);
+    auto webView2 = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration]);
+
+    auto delegate = adoptNS([TestNavigationDelegate new]);
+    [delegate setDidReceiveAuthenticationChallenge:^(WKWebView *, NSURLAuthenticationChallenge *challenge, void (^callback)(NSURLSessionAuthChallengeDisposition, NSURLCredential *)) {
+        EXPECT_WK_STREQ(challenge.protectionSpace.authenticationMethod, NSURLAuthenticationMethodServerTrust);
+        callback(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
+    }];
+
+    webView1.get().navigationDelegate = delegate.get();
+    webView2.get().navigationDelegate = delegate.get();
+
+    ServiceWorkerTCPServer server({
+        { "text/html", mainSWBytesDefaultValue },
+        { "application/_javascript_", scriptBytesDefaultValue },
+    }, {
+        { "text/html", mainSWBytesDefaultValue },
+        { "application/_javascript_", scriptBytesDefaultValue },
+    });
+
+    // Load WebView with an app-bound request. We expect the ServiceWorkerThreadProxy to be app-bound.
+    expectedMessage = "app-bound";
+    [webView1 loadRequest:server.request()];
+    TestWebKitAPI::Util::run(&receivedMessage);
+
+    // Load WebView with a non app-bound request. We expect the ServiceWorkerThreadProxy to be app-bound
+    // at first, but then become non app-bound once the second webView is closed and its client is unregistered.
+    expectedMessage = "starts app-bound";
+    receivedMessage = false;
+    NSMutableURLRequest *nonAppBoundRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://127.0.0.1:%d/main.html", server.port()]]];
+    APP_BOUND_REQUEST_ADDITIONS
+
+    [webView2 loadRequest:nonAppBoundRequest];
+    TestWebKitAPI::Util::run(&receivedMessage);
+
+    // Close the app-bound view. We expect that the existing worker will become non app-bound
+    // now that all app-bound clients have been removed.
+    expectedMessage = "non app-bound";
+    receivedMessage = false;
+    [webView1 _close];
+    webView1 = nullptr;
+
+    TestWebKitAPI::Util::run(&receivedMessage);
+}
+
 #endif
+
+#endif
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to