Title: [286661] trunk
Revision
286661
Author
[email protected]
Date
2021-12-08 10:04:41 -0800 (Wed, 08 Dec 2021)

Log Message

Make KVO work for WKWebpagePreferences._captivePortalModeEnabled
https://bugs.webkit.org/show_bug.cgi?id=233954

Reviewed by Alex Christensen.

Source/WebKit:

Make KVO work for WKWebpagePreferences._captivePortalModeEnabled so that the client can observe
when the system setting changes. Also add SPI to simulate a change of the system setting so that
I can write API tests.

* UIProcess/API/Cocoa/WKProcessPool.mm:
(+[WKProcessPool _setCaptivePortalModeEnabledGloballyForTesting:]):
(+[WKProcessPool _clearCaptivePortalModeEnabledGloballyForTesting]):
* UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
* UIProcess/API/Cocoa/WKWebpagePreferences.mm:
(-[WKWebpagePreferences init]):
(-[WKWebpagePreferences _setCaptivePortalModeEnabled:]):
* UIProcess/API/Cocoa/WKWebpagePreferencesInternal.h:
* UIProcess/CaptivePortalModeObserver.h: Copied from Source/WebKit/UIProcess/API/Cocoa/WKWebpagePreferencesInternal.h.
(WebKit::CaptivePortalModeObserver::~CaptivePortalModeObserver):
* UIProcess/Cocoa/WebProcessPoolCocoa.mm:
(WebKit::captivePortalModeObservers):
(WebKit::isCaptivePortalModeEnabledGloballyForTesting):
(WebKit::isCaptivePortalModeEnabledBySystemIgnoringCaching):
(WebKit::WebProcessPool::captivePortalModeStateChanged):
(WebKit::addCaptivePortalModeObserver):
(WebKit::removeCaptivePortalModeObserver):
(WebKit::captivePortalModeEnabledBySystem):
(WebKit::setCaptivePortalModeEnabledGloballyForTesting):
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::receivedNavigationPolicyDecision):
* UIProcess/WebProcessPool.cpp:
(WebKit::addCaptivePortalModeObserver):
(WebKit::removeCaptivePortalModeObserver):
(WebKit::setCaptivePortalModeEnabledGloballyForTesting):
* UIProcess/WebProcessPool.h:
* WebKit.xcodeproj/project.pbxproj:

Tools:

Add API test coverage.

* TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
(-[CaptivePortalModeKVO observeValueForKeyPath:ofObject:change:context:]):

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (286660 => 286661)


--- trunk/Source/WebKit/ChangeLog	2021-12-08 17:50:40 UTC (rev 286660)
+++ trunk/Source/WebKit/ChangeLog	2021-12-08 18:04:41 UTC (rev 286661)
@@ -1,3 +1,42 @@
+2021-12-08  Chris Dumez  <[email protected]>
+
+        Make KVO work for WKWebpagePreferences._captivePortalModeEnabled
+        https://bugs.webkit.org/show_bug.cgi?id=233954
+
+        Reviewed by Alex Christensen.
+
+        Make KVO work for WKWebpagePreferences._captivePortalModeEnabled so that the client can observe
+        when the system setting changes. Also add SPI to simulate a change of the system setting so that
+        I can write API tests.
+
+        * UIProcess/API/Cocoa/WKProcessPool.mm:
+        (+[WKProcessPool _setCaptivePortalModeEnabledGloballyForTesting:]):
+        (+[WKProcessPool _clearCaptivePortalModeEnabledGloballyForTesting]):
+        * UIProcess/API/Cocoa/WKProcessPoolPrivate.h:
+        * UIProcess/API/Cocoa/WKWebpagePreferences.mm:
+        (-[WKWebpagePreferences init]):
+        (-[WKWebpagePreferences _setCaptivePortalModeEnabled:]):
+        * UIProcess/API/Cocoa/WKWebpagePreferencesInternal.h:
+        * UIProcess/CaptivePortalModeObserver.h: Copied from Source/WebKit/UIProcess/API/Cocoa/WKWebpagePreferencesInternal.h.
+        (WebKit::CaptivePortalModeObserver::~CaptivePortalModeObserver):
+        * UIProcess/Cocoa/WebProcessPoolCocoa.mm:
+        (WebKit::captivePortalModeObservers):
+        (WebKit::isCaptivePortalModeEnabledGloballyForTesting):
+        (WebKit::isCaptivePortalModeEnabledBySystemIgnoringCaching):
+        (WebKit::WebProcessPool::captivePortalModeStateChanged):
+        (WebKit::addCaptivePortalModeObserver):
+        (WebKit::removeCaptivePortalModeObserver):
+        (WebKit::captivePortalModeEnabledBySystem):
+        (WebKit::setCaptivePortalModeEnabledGloballyForTesting):
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::receivedNavigationPolicyDecision):
+        * UIProcess/WebProcessPool.cpp:
+        (WebKit::addCaptivePortalModeObserver):
+        (WebKit::removeCaptivePortalModeObserver):
+        (WebKit::setCaptivePortalModeEnabledGloballyForTesting):
+        * UIProcess/WebProcessPool.h:
+        * WebKit.xcodeproj/project.pbxproj:
+
 2021-12-08  Aditya Keerthi  <[email protected]>
 
         [iOS] Add support for _UITextSearchOptions when finding a string

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm (286660 => 286661)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm	2021-12-08 17:50:40 UTC (rev 286660)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPool.mm	2021-12-08 18:04:41 UTC (rev 286661)
@@ -499,6 +499,16 @@
     setApplicationSDKVersion(std::numeric_limits<uint32_t>::max());
 }
 
++ (void)_setCaptivePortalModeEnabledGloballyForTesting:(BOOL)isEnabled
+{
+    WebKit::setCaptivePortalModeEnabledGloballyForTesting(!!isEnabled);
+}
+
++ (void)_clearCaptivePortalModeEnabledGloballyForTesting
+{
+    WebKit::setCaptivePortalModeEnabledGloballyForTesting(std::nullopt);
+}
+
 - (BOOL)_isCookieStoragePartitioningEnabled
 {
     return _processPool->cookieStoragePartitioningEnabled();

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h (286660 => 286661)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h	2021-12-08 17:50:40 UTC (rev 286660)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKProcessPoolPrivate.h	2021-12-08 18:04:41 UTC (rev 286661)
@@ -124,6 +124,8 @@
 + (void)_forceGameControllerFramework WK_API_AVAILABLE(macos(10.13), ios(11.0));
 + (void)_setLinkedOnOrAfterEverythingForTesting WK_API_AVAILABLE(macos(12.0), ios(15.0));
 + (void)_setLinkedOnOrBeforeEverythingForTesting WK_API_AVAILABLE(macos(12.0), ios(15.0));
++ (void)_setCaptivePortalModeEnabledGloballyForTesting:(BOOL)isEnabled WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
++ (void)_clearCaptivePortalModeEnabledGloballyForTesting WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
 
 - (void)_preconnectToServer:(NSURL *)serverURL WK_API_DEPRECATED_WITH_REPLACEMENT("WKWebView._preconnectToServer", macos(10.13.4, 10.15.4), ios(11.3, 13.4));
 

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebpagePreferences.mm (286660 => 286661)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebpagePreferences.mm	2021-12-08 17:50:40 UTC (rev 286660)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebpagePreferences.mm	2021-12-08 18:04:41 UTC (rev 286661)
@@ -27,10 +27,12 @@
 #import <WebKit/WKWebpagePreferences.h>
 
 #import "APICustomHeaderFields.h"
+#import "CaptivePortalModeObserver.h"
 #import "WKUserContentControllerInternal.h"
 #import "WKWebpagePreferencesInternal.h"
 #import "WKWebsiteDataStoreInternal.h"
 #import "WebContentMode.h"
+#import "WebProcessPool.h"
 #import "_WKCustomHeaderFieldsInternal.h"
 #import <WebCore/DocumentLoader.h>
 #import <WebCore/WebCoreObjCExtras.h>
@@ -102,6 +104,40 @@
     return WebCore::MouseEventPolicy::Default;
 }
 
+class WebPagePreferencesCaptivePortalModeObserver final : public CaptivePortalModeObserver {
+    WTF_MAKE_FAST_ALLOCATED;
+public:
+    WebPagePreferencesCaptivePortalModeObserver(id object)
+        : m_object(object)
+    {
+        addCaptivePortalModeObserver(*this);
+    }
+
+    ~WebPagePreferencesCaptivePortalModeObserver()
+    {
+        removeCaptivePortalModeObserver(*this);
+    }
+
+private:
+    void willChangeCaptivePortalMode() final
+    {
+        if (auto object = m_object.get()) {
+            [object willChangeValueForKey:@"_captivePortalModeEnabled"];
+            [object _willChangeCaptivePortalMode];
+        }
+    }
+
+    void didChangeCaptivePortalMode() final
+    {
+        if (auto object = m_object.get()) {
+            [object didChangeValueForKey:@"_captivePortalModeEnabled"];
+            [object _didChangeCaptivePortalMode];
+        }
+    }
+
+    WeakObjCPtr<id> m_object;
+};
+
 } // namespace WebKit
 
 @implementation WKWebpagePreferences
@@ -127,6 +163,7 @@
         return nil;
 
     API::Object::constructInWrapper<API::WebsitePolicies>(self);
+    _captivePortalModeObserver = makeUnique<WebKit::WebPagePreferencesCaptivePortalModeObserver>(self);
 
     return self;
 }
@@ -418,9 +455,6 @@
 
 - (void)_setCaptivePortalModeEnabled:(BOOL)captivePortalModeEnabled
 {
-    if (_websitePolicies->captivePortalModeEnabled() == captivePortalModeEnabled)
-        return;
-
 #if PLATFORM(IOS_FAMILY)
     // On iOS, the web browser entitlement is required to disable captive portal mode.
     if (!captivePortalModeEnabled && !WTF::processHasEntitlement("com.apple.developer.web-browser"))
@@ -461,6 +495,13 @@
 
 #if USE(APPLE_INTERNAL_SDK)
 #import <WebKitAdditions/WKWebpagePreferencesAdditions.mm>
+#else
+- (void)_willChangeCaptivePortalMode
+{
+}
+- (void)_didChangeCaptivePortalMode
+{
+}
 #endif
 
 @end

Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebpagePreferencesInternal.h (286660 => 286661)


--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebpagePreferencesInternal.h	2021-12-08 17:50:40 UTC (rev 286660)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebpagePreferencesInternal.h	2021-12-08 18:04:41 UTC (rev 286661)
@@ -38,12 +38,19 @@
 WebContentMode webContentMode(WKContentMode);
 #endif
 
+class WebPagePreferencesCaptivePortalModeObserver;
+
 }
 
 @interface WKWebpagePreferences () <WKObject> {
 @package
     API::ObjectStorage<API::WebsitePolicies> _websitePolicies;
+    std::unique_ptr<WebKit::WebPagePreferencesCaptivePortalModeObserver> _captivePortalModeObserver;
 }
 
 @property (class, nonatomic, readonly) WKWebpagePreferences *defaultPreferences;
+
+- (void)_willChangeCaptivePortalMode;
+- (void)_didChangeCaptivePortalMode;
+
 @end

Copied: trunk/Source/WebKit/UIProcess/CaptivePortalModeObserver.h (from rev 286660, trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebpagePreferencesInternal.h) (0 => 286661)


--- trunk/Source/WebKit/UIProcess/CaptivePortalModeObserver.h	                        (rev 0)
+++ trunk/Source/WebKit/UIProcess/CaptivePortalModeObserver.h	2021-12-08 18:04:41 UTC (rev 286661)
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2021 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <wtf/WeakPtr.h>
+
+namespace WebKit {
+
+class CaptivePortalModeObserver : public CanMakeWeakPtr<CaptivePortalModeObserver> {
+public:
+    virtual ~CaptivePortalModeObserver() { }
+
+    virtual void willChangeCaptivePortalMode() = 0;
+    virtual void didChangeCaptivePortalMode() = 0;
+};
+
+} // namespace WebKit

Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm (286660 => 286661)


--- trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm	2021-12-08 17:50:40 UTC (rev 286660)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm	2021-12-08 18:04:41 UTC (rev 286661)
@@ -29,6 +29,7 @@
 #import "APINavigation.h"
 #import "AccessibilityPreferences.h"
 #import "AccessibilitySupportSPI.h"
+#import "CaptivePortalModeObserver.h"
 #import "CookieStorageUtilsCF.h"
 #import "DefaultWebBrowserChecks.h"
 #import "LegacyCustomProtocolManagerClient.h"
@@ -945,10 +946,35 @@
     return qos;
 }
 
+static WeakHashSet<CaptivePortalModeObserver>& captivePortalModeObservers()
+{
+    RELEASE_ASSERT(isMainRunLoop());
+    static NeverDestroyed<WeakHashSet<CaptivePortalModeObserver>> observers;
+    return observers;
+}
+
+static std::optional<bool>& isCaptivePortalModeEnabledGloballyForTesting()
+{
+    static NeverDestroyed<std::optional<bool>> enabledForTesting;
+    return enabledForTesting;
+}
+
+static bool isCaptivePortalModeEnabledBySystemIgnoringCaching()
+{
+    if (auto& enabledForTesting = isCaptivePortalModeEnabledGloballyForTesting())
+        return *enabledForTesting;
+
+    return [[NSUserDefaults standardUserDefaults] boolForKey:[NSString stringWithUTF8String:WebKitCaptivePortalModeChangedNotification]];
+}
+
 void WebProcessPool::captivePortalModeStateChanged()
 {
-    cachedCaptivePortalModeEnabledGlobally() = std::nullopt;
-    auto isNowEnabled = captivePortalModeEnabledBySystem();
+    auto isNowEnabled = isCaptivePortalModeEnabledBySystemIgnoringCaching();
+    if (cachedCaptivePortalModeEnabledGlobally() != isNowEnabled) {
+        captivePortalModeObservers().forEach([](auto& observer) { observer.willChangeCaptivePortalMode(); });
+        cachedCaptivePortalModeEnabledGlobally() = isNowEnabled;
+        captivePortalModeObservers().forEach([](auto& observer) { observer.didChangeCaptivePortalMode(); });
+    }
 
     WEBPROCESSPOOL_RELEASE_LOG(Loading, "WebProcessPool::captivePortalModeStateChanged() isNowEnabled=%d", isNowEnabled);
 
@@ -969,16 +995,40 @@
     }
 }
 
+void addCaptivePortalModeObserver(CaptivePortalModeObserver& observer)
+{
+    // Make sure cachedCaptivePortalModeEnabledGlobally() gets initialized so captivePortalModeStateChanged() can track changes.
+    auto& cachedState = cachedCaptivePortalModeEnabledGlobally();
+    if (!cachedState)
+        cachedState = isCaptivePortalModeEnabledBySystemIgnoringCaching();
+
+    captivePortalModeObservers().add(observer);
+}
+
+void removeCaptivePortalModeObserver(CaptivePortalModeObserver& observer)
+{
+    captivePortalModeObservers().remove(observer);
+}
+
 bool captivePortalModeEnabledBySystem()
 {
     auto& cachedState = cachedCaptivePortalModeEnabledGlobally();
-    if (!cachedState) {
-        // FIXME: Using NSUserDefaults is a temporary workaround. This setting should be stored elsewhere (TCC?).
-        cachedState = [[NSUserDefaults standardUserDefaults] boolForKey:[NSString stringWithUTF8String:WebKitCaptivePortalModeChangedNotification]];
-    }
+    if (!cachedState)
+        cachedState = isCaptivePortalModeEnabledBySystemIgnoringCaching();
     return *cachedState;
 }
 
+void setCaptivePortalModeEnabledGloballyForTesting(std::optional<bool> enabledForTesting)
+{
+    if (isCaptivePortalModeEnabledGloballyForTesting() == enabledForTesting)
+        return;
+
+    isCaptivePortalModeEnabledGloballyForTesting() = enabledForTesting;
+
+    for (auto& processPool : WebProcessPool::allProcessPools())
+        processPool->captivePortalModeStateChanged();
+}
+
 #if PLATFORM(IOS_FAMILY)
 
 void WebProcessPool::applicationIsAboutToSuspend()

Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (286660 => 286661)


--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2021-12-08 17:50:40 UTC (rev 286660)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp	2021-12-08 18:04:41 UTC (rev 286661)
@@ -3457,7 +3457,7 @@
         }
     }
 
-    m_isCaptivePortalModeExplicitlySet = policies ? policies->isCaptivePortalModeExplicitlySet() : m_configuration->isCaptivePortalModeExplicitlySet();
+    m_isCaptivePortalModeExplicitlySet = (policies && policies->isCaptivePortalModeExplicitlySet()) || m_configuration->isCaptivePortalModeExplicitlySet();
     auto captivePortalMode = (policies ? policies->captivePortalModeEnabled() : shouldEnableCaptivePortalMode()) ? WebProcessProxy::CaptivePortalMode::Enabled : WebProcessProxy::CaptivePortalMode::Disabled;
     process().processPool().processForNavigation(*this, *navigation, sourceProcess.copyRef(), sourceURL, processSwapRequestedByClient, captivePortalMode, frameInfo, WTFMove(websiteDataStore), [this, protectedThis = Ref { *this }, policyAction, navigation = Ref { *navigation }, navigationAction = WTFMove(navigationAction), sourceProcess = sourceProcess.copyRef(),
         policies = WTFMove(policies), sender = WTFMove(sender), processSwapRequestedByClient] (Ref<WebProcessProxy>&& processForNavigation, SuspendedPageProxy* destinationSuspendedPage, const String& reason) mutable {

Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.cpp (286660 => 286661)


--- trunk/Source/WebKit/UIProcess/WebProcessPool.cpp	2021-12-08 17:50:40 UTC (rev 286660)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.cpp	2021-12-08 18:04:41 UTC (rev 286661)
@@ -2124,10 +2124,19 @@
 #endif
 
 #if !PLATFORM(COCOA)
+void addCaptivePortalModeObserver(CaptivePortalModeObserver&)
+{
+}
+void removeCaptivePortalModeObserver(CaptivePortalModeObserver&)
+{
+}
 bool captivePortalModeEnabledBySystem()
 {
     return false;
 }
+void setCaptivePortalModeEnabledGloballyForTesting(std::optional<bool>)
+{
+}
 #endif
 
 } // namespace WebKit

Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.h (286660 => 286661)


--- trunk/Source/WebKit/UIProcess/WebProcessPool.h	2021-12-08 17:50:40 UTC (rev 286660)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.h	2021-12-08 18:04:41 UTC (rev 286661)
@@ -97,12 +97,13 @@
 
 namespace WebKit {
 
-class WebBackForwardCache;
+class CaptivePortalModeObserver;
 class HighPerformanceGraphicsUsageSampler;
 class UIGamepad;
 class PerActivityStateCPUUsageSampler;
 class SuspendedPageProxy;
 class WebAutomationSession;
+class WebBackForwardCache;
 class WebContextSupplement;
 class WebPageGroup;
 class WebPageProxy;
@@ -119,7 +120,10 @@
 int webProcessLatencyQOS();
 int webProcessThroughputQOS();
 #endif
+void addCaptivePortalModeObserver(CaptivePortalModeObserver&);
+void removeCaptivePortalModeObserver(CaptivePortalModeObserver&);
 bool captivePortalModeEnabledBySystem();
+void setCaptivePortalModeEnabledGloballyForTesting(std::optional<bool>);
 
 enum class CallDownloadDidStart : bool;
 enum class ProcessSwapRequestedByClient : bool;
@@ -432,6 +436,8 @@
     void setCookieStoragePartitioningEnabled(bool);
 
     void clearPermanentCredentialsForProtectionSpace(WebCore::ProtectionSpace&&);
+
+    void captivePortalModeStateChanged();
 #endif
 
     ForegroundWebProcessToken foregroundWebProcessToken() const { return ForegroundWebProcessToken(m_foregroundWebProcessCounter.count()); }
@@ -548,8 +554,6 @@
 
     void registerNotificationObservers();
     void unregisterNotificationObservers();
-
-    void captivePortalModeStateChanged();
 #endif
 
     void setApplicationIsActive(bool);

Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (286660 => 286661)


--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2021-12-08 17:50:40 UTC (rev 286660)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj	2021-12-08 18:04:41 UTC (rev 286661)
@@ -908,6 +908,7 @@
 		461CCCA6231485AA00B659B9 /* WebRemoteObjectRegistry.h in Headers */ = {isa = PBXBuildFile; fileRef = 46323683231481EF00A48FA7 /* WebRemoteObjectRegistry.h */; };
 		463FD4801EB9459600A2982C /* WKProcessTerminationReason.h in Headers */ = {isa = PBXBuildFile; fileRef = 463FD47F1EB9458400A2982C /* WKProcessTerminationReason.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		463FD4821EB94EC000A2982C /* ProcessTerminationReason.h in Headers */ = {isa = PBXBuildFile; fileRef = 463FD4811EB94EAD00A2982C /* ProcessTerminationReason.h */; };
+		4659F25F275FF6B200BBB369 /* CaptivePortalModeObserver.h in Headers */ = {isa = PBXBuildFile; fileRef = 4659F25E275FF6B200BBB369 /* CaptivePortalModeObserver.h */; };
 		465F4E06230B2E95003CEDB7 /* StorageNamespaceIdentifier.h in Headers */ = {isa = PBXBuildFile; fileRef = 465F4E05230B2E7C003CEDB7 /* StorageNamespaceIdentifier.h */; };
 		465FA7262757D93D0072362B /* WebLockRegistryProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = 465FA7232757D9180072362B /* WebLockRegistryProxy.h */; };
 		466BC03C1FA266DA002FA9C1 /* WebSWContextManagerConnection.h in Headers */ = {isa = PBXBuildFile; fileRef = 466BC0391FA266C9002FA9C1 /* WebSWContextManagerConnection.h */; };
@@ -4190,6 +4191,7 @@
 		463FD4811EB94EAD00A2982C /* ProcessTerminationReason.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ProcessTerminationReason.h; sourceTree = "<group>"; };
 		4651ECE622178A850067EB95 /* WebProcessCacheCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebProcessCacheCocoa.mm; sourceTree = "<group>"; };
 		465250E51ECF52CD002025CB /* WebKit2InitializeCocoa.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WebKit2InitializeCocoa.mm; sourceTree = "<group>"; };
+		4659F25E275FF6B200BBB369 /* CaptivePortalModeObserver.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CaptivePortalModeObserver.h; sourceTree = "<group>"; };
 		465F4E02230759D5003CEDB7 /* StorageAreaIdentifier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StorageAreaIdentifier.h; sourceTree = "<group>"; };
 		465F4E032307604E003CEDB7 /* StorageAreaImplIdentifier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StorageAreaImplIdentifier.h; sourceTree = "<group>"; };
 		465F4E05230B2E7C003CEDB7 /* StorageNamespaceIdentifier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StorageNamespaceIdentifier.h; sourceTree = "<group>"; };
@@ -5023,7 +5025,6 @@
 		7B483F1C25CDDA9B00120486 /* MessageReceiveQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageReceiveQueue.h; sourceTree = "<group>"; };
 		7B483F1D25CDDA9B00120486 /* MessageReceiveQueueMap.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MessageReceiveQueueMap.cpp; sourceTree = "<group>"; };
 		7B483F1E25CDDA9B00120486 /* MessageReceiveQueues.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MessageReceiveQueues.h; sourceTree = "<group>"; };
-		7B5300E72718217A00082086 /* RemoteGraphicsContextGLProxyCocoa.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = RemoteGraphicsContextGLProxyCocoa.mm; sourceTree = "<group>"; };
 		7B64C0B6254C5C250006B4AF /* GraphicsContextGLIdentifier.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GraphicsContextGLIdentifier.h; sourceTree = "<group>"; };
 		7B73123125CC8523003B2796 /* StreamConnectionBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = StreamConnectionBuffer.h; sourceTree = "<group>"; };
 		7B73123225CC8523003B2796 /* StreamConnectionWorkQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = StreamConnectionWorkQueue.cpp; sourceTree = "<group>"; };
@@ -9949,7 +9950,6 @@
 		5C157A0A2717C9F100ED5280 /* webpushd */ = {
 			isa = PBXGroup;
 			children = (
-				517B5F77275E9795002DC22D /* webpushd.cpp */,
 				517B5F63275A8D5C002DC22D /* webpushtool */,
 				5160E954274B887100567388 /* AppBundleRequest.h */,
 				5160E953274B887100567388 /* AppBundleRequest.mm */,
@@ -9963,10 +9963,11 @@
 				5160E958274C0D8800567388 /* PushAppBundle.mm */,
 				51F7BB792744C50700C45A72 /* PushClientConnection.h */,
 				51F7BB7A2744C50700C45A72 /* PushClientConnection.mm */,
+				517B5F77275E9795002DC22D /* webpushd.cpp */,
 				512CD69D2723393A00F7F8EC /* WebPushDaemon.h */,
 				512CD69E2723393A00F7F8EC /* WebPushDaemon.mm */,
+				517B5F72275E9609002DC22D /* WebPushDaemonMain.h */,
 				5C157A0B2717CA1C00ED5280 /* WebPushDaemonMain.mm */,
-				517B5F72275E9609002DC22D /* WebPushDaemonMain.h */,
 			);
 			path = webpushd;
 			sourceTree = "<group>";
@@ -10771,6 +10772,7 @@
 				E1513C65166EABB200149FCB /* AuxiliaryProcessProxy.h */,
 				46A2B6061E5675A200C3DEDA /* BackgroundProcessResponsivenessTimer.cpp */,
 				46A2B6071E5675A200C3DEDA /* BackgroundProcessResponsivenessTimer.h */,
+				4659F25E275FF6B200BBB369 /* CaptivePortalModeObserver.h */,
 				07297F9C1C1711EA003F0735 /* DeviceIdHashSaltStorage.cpp */,
 				07297F9D1C17BBEA223F0735 /* DeviceIdHashSaltStorage.h */,
 				BC2652121182608100243E12 /* DrawingAreaProxy.cpp */,
@@ -12595,7 +12597,6 @@
 				5CAFDE452130846300B1F7E1 /* _WKInspector.h in Headers */,
 				994C6042253CA54400BDF060 /* _WKInspectorConfiguration.h in Headers */,
 				994C6045253CABA200BDF060 /* _WKInspectorConfigurationInternal.h in Headers */,
-				517B5F7F275E97B6002DC22D /* WebPushDaemon.h in Headers */,
 				991F492F23A812C60054642B /* _WKInspectorDebuggableInfo.h in Headers */,
 				99036AE223A949CF0000B06A /* _WKInspectorDebuggableInfoInternal.h in Headers */,
 				9197940C23DBC50300257892 /* _WKInspectorDelegate.h in Headers */,
@@ -12759,6 +12760,7 @@
 				1A6563E51B7A8C50009CF787 /* APIWindowFeatures.h in Headers */,
 				572EBBDB2538F6B6000552B3 /* AppAttestInternalSoftLink.h in Headers */,
 				572EBBDD25392181000552B3 /* AppAttestSPI.h in Headers */,
+				517B5F85275E97B6002DC22D /* AppBundleRequest.h in Headers */,
 				074879B92373A90900F5678E /* AppKitSoftLink.h in Headers */,
 				F48D2A8521583A7E00C6752B /* AppKitSPI.h in Headers */,
 				9565083926D87A2B00E15CB7 /* AppleMediaServicesSPI.h in Headers */,
@@ -12804,6 +12806,7 @@
 				41897ED81F415D8A0016FA42 /* CacheStorageEngine.h in Headers */,
 				41FABD2A1F4DE001006A6C97 /* CacheStorageEngineCache.h in Headers */,
 				41897EDA1F415D8A0016FA42 /* CacheStorageEngineConnection.h in Headers */,
+				4659F25F275FF6B200BBB369 /* CaptivePortalModeObserver.h in Headers */,
 				BCE579A62634836700F5C5E9 /* CGDisplayListImageBufferBackend.h in Headers */,
 				57B4B46020B504AC00D4AD79 /* ClientCertificateAuthenticationXPCConstants.h in Headers */,
 				F4FE0A3B24632B60002631E1 /* CocoaColor.h in Headers */,
@@ -12972,6 +12975,8 @@
 				1A3EED0F161A535400AEB4F5 /* MessageReceiverMap.h in Headers */,
 				1AAB037A185A7C6A00EDF501 /* MessageSender.h in Headers */,
 				A13B3DA2207F39DE0090C58D /* MobileWiFiSPI.h in Headers */,
+				517B5F7C275E97B6002DC22D /* MockAppBundleForTesting.h in Headers */,
+				517B5F80275E97B6002DC22D /* MockAppBundleRegistry.h in Headers */,
 				57DCEDCB214F4E420016B847 /* MockAuthenticatorManager.h in Headers */,
 				57DCEDC7214F18300016B847 /* MockLocalConnection.h in Headers */,
 				57DCEDC3214F114C0016B847 /* MockLocalService.h in Headers */,
@@ -12999,7 +13004,6 @@
 				831EEBBD1BD85C4300BB64C3 /* NetworkCacheSpeculativeLoad.h in Headers */,
 				832AE2521BE2E8CD00FAAE10 /* NetworkCacheSpeculativeLoadManager.h in Headers */,
 				E4436ECF1A0D040B00EAD204 /* NetworkCacheStorage.h in Headers */,
-				517B5F7C275E97B6002DC22D /* MockAppBundleForTesting.h in Headers */,
 				8310428B1BD6B66F00A715E4 /* NetworkCacheSubresourcesEntry.h in Headers */,
 				513A164D1630A9BF005D7D22 /* NetworkConnectionToWebProcess.h in Headers */,
 				51DD9F2916367DA2001578E9 /* NetworkConnectionToWebProcessMessages.h in Headers */,
@@ -13094,6 +13098,8 @@
 				86E67A251910B9D100004AB7 /* ProcessThrottler.h in Headers */,
 				83048AE61ACA45DC0082C832 /* ProcessThrottlerClient.h in Headers */,
 				2D279E1926955768004B3EEB /* PrototypeToolsSPI.h in Headers */,
+				517B5F81275E97B6002DC22D /* PushAppBundle.h in Headers */,
+				517B5F7D275E97B6002DC22D /* PushClientConnection.h in Headers */,
 				A1E688701F6E2BAB007006A6 /* QuarantineSPI.h in Headers */,
 				1A0C227E2451130A00ED614D /* QuickLookThumbnailingSoftLink.h in Headers */,
 				1AEE57252409F142002005D6 /* QuickLookThumbnailLoader.h in Headers */,
@@ -13134,7 +13140,6 @@
 				071BC59123CE1EAA00680D7C /* RemoteMediaPlayerProxyMessagesReplies.h in Headers */,
 				1D4D737123A9E56200717A25 /* RemoteMediaResourceManagerMessages.h in Headers */,
 				1D4D737623A9ED1800717A25 /* RemoteMediaResourceManagerMessagesReplies.h in Headers */,
-				517B5F85275E97B6002DC22D /* AppBundleRequest.h in Headers */,
 				1DD2A68525633C6700FF7B6F /* RemoteMediaSourceProxyMessages.h in Headers */,
 				1DD2A68825633C9500FF7B6F /* RemoteMediaSourceProxyMessagesReplies.h in Headers */,
 				E1B78471163F24690007B692 /* RemoteNetworkingContext.h in Headers */,
@@ -13227,7 +13232,6 @@
 				57FD318622B3516C008D0E8B /* SubFrameSOAuthorizationSession.h in Headers */,
 				448AC24E267135A700B28921 /* SynapseSPI.h in Headers */,
 				4459984222833E8700E61373 /* SyntheticEditingCommandType.h in Headers */,
-				517B5F7D275E97B6002DC22D /* PushClientConnection.h in Headers */,
 				3157135F2040A9B20084F9CF /* SystemPreviewController.h in Headers */,
 				079D1D9A26960CD300883577 /* SystemStatusSPI.h in Headers */,
 				F4D985CB2691096600BBCCBE /* TapHandlingResult.h in Headers */,
@@ -13252,7 +13256,6 @@
 				1A64245E12DE29A100CAAE2C /* UpdateInfo.h in Headers */,
 				5C19A5201FD0B29500EEA323 /* URLSchemeTaskParameters.h in Headers */,
 				1AC1336818565B5700F3EC05 /* UserData.h in Headers */,
-				517B5F80275E97B6002DC22D /* MockAppBundleRegistry.h in Headers */,
 				CD491B081E70D05F00009066 /* UserMediaCaptureManager.h in Headers */,
 				CD491B0E1E732E4D00009066 /* UserMediaCaptureManagerMessages.h in Headers */,
 				CD491B131E73482100009066 /* UserMediaCaptureManagerProxy.h in Headers */,
@@ -13478,9 +13481,11 @@
 				BCE0E425168B7A280057E66A /* WebProcessSupplement.h in Headers */,
 				1A1E093418861D3800D2DC49 /* WebProgressTrackerClient.h in Headers */,
 				512F589D12A8838800629530 /* WebProtectionSpace.h in Headers */,
+				517B5F7F275E97B6002DC22D /* WebPushDaemon.h in Headers */,
 				512CD6982721EFC800F7F8EC /* WebPushDaemonConnection.h in Headers */,
 				517B5F2E2757382A002DC22D /* WebPushDaemonConnectionConfiguration.h in Headers */,
 				512CD69A2721F0A900F7F8EC /* WebPushDaemonConstants.h in Headers */,
+				517B5F73275E9609002DC22D /* WebPushDaemonMain.h in Headers */,
 				461CCCA6231485AA00B659B9 /* WebRemoteObjectRegistry.h in Headers */,
 				A5860E71230F67FC00461AAE /* WebResourceInterceptController.h in Headers */,
 				510AFFBA16542048001BA05E /* WebResourceLoader.h in Headers */,
@@ -13730,7 +13735,6 @@
 				A1579B28258490E500528236 /* WKMediaFormatReader.h in Headers */,
 				9ACC07B925C8218400DC6386 /* WKMediaKeySystemPermissionCallback.h in Headers */,
 				1AB40EE61BF677E300BA81BE /* WKMenuItemIdentifiersPrivate.h in Headers */,
-				517B5F81275E97B6002DC22D /* PushAppBundle.h in Headers */,
 				5CABDC8622C40FDE001EDE8E /* WKMessageListener.h in Headers */,
 				C11E1694212B87C500985FF6 /* WKMockDisplay.h in Headers */,
 				411A8DDB20DDD1AC0060D34F /* WKMockMediaDevice.h in Headers */,
@@ -13796,7 +13800,6 @@
 				BC2D021912AC426C00E732A3 /* WKPageLoadTypes.h in Headers */,
 				93BDEB01171DD7AF00BFEE1B /* WKPageLoadTypesPrivate.h in Headers */,
 				2D7303791A7C2B7500F8F487 /* WKPageNavigationClient.h in Headers */,
-				517B5F73275E9609002DC22D /* WebPushDaemonMain.h in Headers */,
 				1AB8A1EE18400ACB00E9AE69 /* WKPagePolicyClient.h in Headers */,
 				373CEAD81859553F008C363D /* WKPagePolicyClientInternal.h in Headers */,
 				BC177465118B9FF4007D9E9A /* WKPagePrivate.h in Headers */,
@@ -15104,8 +15107,8 @@
 				51F7BB7D2745640400C45A72 /* CodeSigning.mm in Sources */,
 				5C1579FF2717B6D200ED5280 /* DaemonDecoder.cpp in Sources */,
 				5C1579FE2717B6C100ED5280 /* DaemonEncoder.cpp in Sources */,
+				5C1579FB2717AF5000ED5280 /* DaemonUtilities.mm in Sources */,
 				517B5F78275E9795002DC22D /* webpushd.cpp in Sources */,
-				5C1579FB2717AF5000ED5280 /* DaemonUtilities.mm in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -15149,6 +15152,7 @@
 				99E7189A21F79D9E0055E975 /* _WKTouchEventGenerator.mm in Sources */,
 				2D92A784212B6AB100F493FD /* ActivityAssertion.cpp in Sources */,
 				572EBBDA2538F6B4000552B3 /* AppAttestInternalSoftLink.mm in Sources */,
+				517B5F7E275E97B6002DC22D /* AppBundleRequest.mm in Sources */,
 				2D92A77B212B6A7100F493FD /* ArgumentCoders.cpp in Sources */,
 				2DEB1D2E2127473600933906 /* ArgumentCodersCF.cpp in Sources */,
 				2D92A77C212B6A7100F493FD /* Attachment.cpp in Sources */,
@@ -15156,7 +15160,6 @@
 				CD4570D3244113B500A3DCEB /* AudioSessionRoutingArbitratorProxyMessageReceiver.cpp in Sources */,
 				512F58A212A883AD00629530 /* AuthenticationManagerMessageReceiver.cpp in Sources */,
 				57FABB132581827C0059DC95 /* AuthenticationServicesCoreSoftLink.mm in Sources */,
-				517B5F7E275E97B6002DC22D /* AppBundleRequest.mm in Sources */,
 				9955A6F41C7986DC00EB6A93 /* AutomationBackendDispatchers.cpp in Sources */,
 				99249AD51F1F1E5600B62FBB /* AutomationFrontendDispatchers.cpp in Sources */,
 				9955A6F61C7986E300EB6A93 /* AutomationProtocolObjects.cpp in Sources */,
@@ -15195,6 +15198,8 @@
 				7B483F2125CDDA9C00120486 /* MessageReceiveQueueMap.cpp in Sources */,
 				2D92A781212B6A7100F493FD /* MessageReceiverMap.cpp in Sources */,
 				2D92A782212B6A7100F493FD /* MessageSender.cpp in Sources */,
+				517B5F84275E97B6002DC22D /* MockAppBundleForTesting.mm in Sources */,
+				517B5F86275E97B6002DC22D /* MockAppBundleRegistry.mm in Sources */,
 				2D92A77A212B6A6100F493FD /* Module.cpp in Sources */,
 				57B826452304F14000B72EB0 /* NearFieldSoftLink.mm in Sources */,
 				C1C1B30F2540F50D00D9100B /* NetworkConnectionToWebProcessMac.mm in Sources */,
@@ -15219,6 +15224,8 @@
 				2D91344D212CF9F000128AFD /* PluginView.cpp in Sources */,
 				C15CBB3723F37ECB00300CC7 /* PreferenceObserver.mm in Sources */,
 				2D54C31B212F4DA60049C174 /* ProcessLauncher.cpp in Sources */,
+				517B5F82275E97B6002DC22D /* PushAppBundle.mm in Sources */,
+				517B5F7B275E97A9002DC22D /* PushClientConnection.mm in Sources */,
 				1A0C227F2451130A00ED614D /* QuickLookThumbnailingSoftLink.mm in Sources */,
 				1A0C225E243575CD00ED614D /* QuickLookThumbnailLoader.mm in Sources */,
 				9B1229CE23FF25F2008CA751 /* RemoteAudioDestinationManager.cpp in Sources */,
@@ -15238,7 +15245,6 @@
 				CDE555352406EB8C008A3DDB /* RemoteLegacyCDMSessionProxyMessageReceiver.cpp in Sources */,
 				CD3EEF462579C261006563BB /* RemoteMediaEngineConfigurationFactoryProxyMessageReceiver.cpp in Sources */,
 				0792314B239CBCB8009598E2 /* RemoteMediaPlayerManagerProxyMessageReceiver.cpp in Sources */,
-				517B5F7A275E97A4002DC22D /* WebPushDaemon.mm in Sources */,
 				0701789E23BE9CFC005F0FAA /* RemoteMediaPlayerMIMETypeCache.cpp in Sources */,
 				071BC58F23CE1EAA00680D7C /* RemoteMediaPlayerProxyMessageReceiver.cpp in Sources */,
 				1D4D737023A9E54700717A25 /* RemoteMediaResourceManagerMessageReceiver.cpp in Sources */,
@@ -15279,8 +15285,6 @@
 				2D11B7552126A282006F8878 /* UnifiedSource3-mm.mm in Sources */,
 				2D11B7562126A282006F8878 /* UnifiedSource3.cpp in Sources */,
 				2D11B7572126A282006F8878 /* UnifiedSource4-mm.mm in Sources */,
-				517B5F84275E97B6002DC22D /* MockAppBundleForTesting.mm in Sources */,
-				517B5F86275E97B6002DC22D /* MockAppBundleRegistry.mm in Sources */,
 				2D11B7582126A282006F8878 /* UnifiedSource4.cpp in Sources */,
 				2D11B7592126A282006F8878 /* UnifiedSource5-mm.mm in Sources */,
 				2D11B75A2126A282006F8878 /* UnifiedSource5.cpp in Sources */,
@@ -15363,7 +15367,6 @@
 				2D11B7A72126A283006F8878 /* UnifiedSource44-mm.mm in Sources */,
 				2D11B7A82126A283006F8878 /* UnifiedSource44.cpp in Sources */,
 				2D11B7A92126A283006F8878 /* UnifiedSource45-mm.mm in Sources */,
-				517B5F82275E97B6002DC22D /* PushAppBundle.mm in Sources */,
 				2D11B7AA2126A283006F8878 /* UnifiedSource45.cpp in Sources */,
 				2D11B7AB2126A283006F8878 /* UnifiedSource46-mm.mm in Sources */,
 				2D11B7AC2126A283006F8878 /* UnifiedSource46.cpp in Sources */,
@@ -15394,7 +15397,6 @@
 				2D11B7C52126A283006F8878 /* UnifiedSource59-mm.mm in Sources */,
 				2D11B7C62126A283006F8878 /* UnifiedSource59.cpp in Sources */,
 				2D11B7C72126A283006F8878 /* UnifiedSource60-mm.mm in Sources */,
-				517B5F79275E97A1002DC22D /* WebPushDaemonMain.mm in Sources */,
 				2D11B7C82126A283006F8878 /* UnifiedSource60.cpp in Sources */,
 				2D54C31A212F3B330049C174 /* UnifiedSource61-mm.mm in Sources */,
 				2D11B7CA2126A283006F8878 /* UnifiedSource61.cpp in Sources */,
@@ -15402,7 +15404,6 @@
 				2D11B7CB2126A283006F8878 /* UnifiedSource62.cpp in Sources */,
 				2D54C308212F3B330049C174 /* UnifiedSource63-mm.mm in Sources */,
 				2D11B7CC2126A283006F8878 /* UnifiedSource63.cpp in Sources */,
-				517B5F7B275E97A9002DC22D /* PushClientConnection.mm in Sources */,
 				2D54C30C212F3B330049C174 /* UnifiedSource64-mm.mm in Sources */,
 				2D11B7CD2126A283006F8878 /* UnifiedSource64.cpp in Sources */,
 				2D54C307212F3B330049C174 /* UnifiedSource65-mm.mm in Sources */,
@@ -15537,6 +15538,8 @@
 				BC3066BE125A442100E71278 /* WebProcessMessageReceiver.cpp in Sources */,
 				7CE4D2271A4916C200C7F152 /* WebProcessPoolMessageReceiver.cpp in Sources */,
 				BCEE7AD012817988009827DA /* WebProcessProxyMessageReceiver.cpp in Sources */,
+				517B5F7A275E97A4002DC22D /* WebPushDaemon.mm in Sources */,
+				517B5F79275E97A1002DC22D /* WebPushDaemonMain.mm in Sources */,
 				51F060E11654318500F3281B /* WebResourceLoaderMessageReceiver.cpp in Sources */,
 				51F060E11654318500F3281F /* WebRTCMonitorMessageReceiver.cpp in Sources */,
 				51F060E11654318500F3282C /* WebRTCResolverMessageReceiver.cpp in Sources */,

Modified: trunk/Tools/ChangeLog (286660 => 286661)


--- trunk/Tools/ChangeLog	2021-12-08 17:50:40 UTC (rev 286660)
+++ trunk/Tools/ChangeLog	2021-12-08 18:04:41 UTC (rev 286661)
@@ -1,3 +1,15 @@
+2021-12-08  Chris Dumez  <[email protected]>
+
+        Make KVO work for WKWebpagePreferences._captivePortalModeEnabled
+        https://bugs.webkit.org/show_bug.cgi?id=233954
+
+        Reviewed by Alex Christensen.
+
+        Add API test coverage.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
+        (-[CaptivePortalModeKVO observeValueForKeyPath:ofObject:change:context:]):
+
 2021-12-08  Aditya Keerthi  <[email protected]>
 
         [iOS] Add support for _UITextSearchOptions when finding a string

Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm (286660 => 286661)


--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm	2021-12-08 17:50:40 UTC (rev 286660)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm	2021-12-08 18:04:41 UTC (rev 286661)
@@ -89,6 +89,29 @@
 static RetainPtr<NSURL> clientRedirectSourceURL;
 static RetainPtr<NSURL> clientRedirectDestinationURL;
 
+static bool didChangeCaptivePortalMode;
+static bool captivePortalModeBeforeChange;
+static bool captivePortalModeAfterChange;
+
+@interface CaptivePortalModeKVO : NSObject {
+@public
+}
+@end
+
+@implementation CaptivePortalModeKVO
+
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *, id> *)change context:(void *)context
+{
+    ASSERT([keyPath isEqualToString:@"_captivePortalModeEnabled"]);
+    ASSERT([[object class] isEqual:[WKWebpagePreferences class]]);
+
+    captivePortalModeBeforeChange = [[change objectForKey:NSKeyValueChangeOldKey] boolValue];
+    captivePortalModeAfterChange = [[change objectForKey:NSKeyValueChangeNewKey] boolValue];
+    didChangeCaptivePortalMode = true;
+}
+
+@end
+
 @interface PSONMessageHandler : NSObject <WKScriptMessageHandler>
 @end
 
@@ -7819,6 +7842,70 @@
     checkSettingsControlledByCaptivePortalMode(webView.get(), ShouldBeEnabled::No);
 }
 
+TEST(ProcessSwap, CaptivePortalModeSystemSettingChange)
+{
+    auto kvo = adoptNS([CaptivePortalModeKVO new]);
+
+    auto webViewConfiguration = adoptNS([WKWebViewConfiguration new]);
+    EXPECT_FALSE(webViewConfiguration.get().defaultWebpagePreferences._captivePortalModeEnabled);
+    [webViewConfiguration.get().defaultWebpagePreferences addObserver:kvo.get() forKeyPath:@"_captivePortalModeEnabled" options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:nil];
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+    auto delegate = adoptNS([TestNavigationDelegate new]);
+    [webView setNavigationDelegate:delegate.get()];
+
+    EXPECT_TRUE(isJITEnabled(webView.get()));
+
+    __block bool finishedNavigation = false;
+    delegate.get().didFinishNavigation = ^(WKWebView *, WKNavigation *) {
+        finishedNavigation = true;
+    };
+
+    NSURL *url = "" mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
+    [webView loadRequest:[NSURLRequest requestWithURL:url]];
+    TestWebKitAPI::Util::run(&finishedNavigation);
+
+    pid_t pid1 = [webView _webProcessIdentifier];
+    EXPECT_NE(pid1, 0);
+
+    EXPECT_TRUE(isJITEnabled(webView.get()));
+
+    EXPECT_FALSE(didChangeCaptivePortalMode);
+
+    finishedNavigation = false;
+    // Now change the global setting.
+    [WKProcessPool _setCaptivePortalModeEnabledGloballyForTesting:YES];
+
+    TestWebKitAPI::Util::run(&didChangeCaptivePortalMode);
+    EXPECT_FALSE(captivePortalModeBeforeChange);
+    EXPECT_TRUE(captivePortalModeAfterChange);
+    EXPECT_TRUE(webViewConfiguration.get().defaultWebpagePreferences._captivePortalModeEnabled);
+
+    // This should cause the WebView to reload with a WebProcess in captive portal mode.
+    TestWebKitAPI::Util::run(&finishedNavigation);
+
+    EXPECT_FALSE(isJITEnabled(webView.get()));
+
+    pid_t pid2 = [webView _webProcessIdentifier];
+    EXPECT_NE(pid1, pid2);
+
+    didChangeCaptivePortalMode = false;
+    finishedNavigation = false;
+    [WKProcessPool _clearCaptivePortalModeEnabledGloballyForTesting];
+
+    TestWebKitAPI::Util::run(&didChangeCaptivePortalMode);
+    EXPECT_TRUE(captivePortalModeBeforeChange);
+    EXPECT_FALSE(captivePortalModeAfterChange);
+    EXPECT_FALSE(webViewConfiguration.get().defaultWebpagePreferences._captivePortalModeEnabled);
+
+    TestWebKitAPI::Util::run(&finishedNavigation);
+
+    EXPECT_TRUE(isJITEnabled(webView.get()));
+
+    pid_t pid3 = [webView _webProcessIdentifier];
+    EXPECT_NE(pid2, pid3);
+}
+
 #if PLATFORM(IOS)
 
 TEST(ProcessSwap, CannotDisableCaptivePortalModeWithoutBrowserEntitlement)
@@ -7946,4 +8033,189 @@
     EXPECT_EQ(pid2, [webView2 _webProcessIdentifier]);
 }
 
+TEST(ProcessSwap, CaptivePortalModeSystemSettingChangeDoesNotReloadViewsWhenModeIsSetExplicitly1)
+{
+    // Captive portal mode is disabled globally and explicitly opted out via defaultWebpagePreferences.
+
+    auto webViewConfiguration = adoptNS([WKWebViewConfiguration new]);
+    EXPECT_FALSE(webViewConfiguration.get().defaultWebpagePreferences._captivePortalModeEnabled);
+    [webViewConfiguration.get().defaultWebpagePreferences _setCaptivePortalModeEnabled:NO]; // Explicitly opt out via default WKWebpagePreferences.
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+    auto delegate = adoptNS([TestNavigationDelegate new]);
+    [webView setNavigationDelegate:delegate.get()];
+
+    EXPECT_TRUE(isJITEnabled(webView.get()));
+
+    __block bool finishedNavigation = false;
+    delegate.get().didFinishNavigation = ^(WKWebView *, WKNavigation *) {
+        finishedNavigation = true;
+    };
+
+    NSURL *url = "" mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
+    [webView loadRequest:[NSURLRequest requestWithURL:url]];
+    TestWebKitAPI::Util::run(&finishedNavigation);
+
+    pid_t pid1 = [webView _webProcessIdentifier];
+    EXPECT_NE(pid1, 0);
+
+    EXPECT_TRUE(isJITEnabled(webView.get()));
+
+    finishedNavigation = false;
+    // Now change the global setting.
+    [WKProcessPool _setCaptivePortalModeEnabledGloballyForTesting:YES];
+
+    // This should not reload the web view since the view has explicitly opted out of captive portal mode.
+    TestWebKitAPI::Util::sleep(0.5);
+    EXPECT_FALSE(finishedNavigation);
+
+    pid_t pid2 = [webView _webProcessIdentifier];
+    EXPECT_EQ(pid1, pid2);
+
+    EXPECT_TRUE(isJITEnabled(webView.get()));
+
+    [WKProcessPool _clearCaptivePortalModeEnabledGloballyForTesting];
+}
+
+TEST(ProcessSwap, CaptivePortalModeSystemSettingChangeDoesNotReloadViewsWhenModeIsSetExplicitly2)
+{
+    // Captive portal mode is enabled globally but explicitly opted out via defaultWebpagePreferences.
+    [WKProcessPool _setCaptivePortalModeEnabledGloballyForTesting:YES];
+
+    auto webViewConfiguration = adoptNS([WKWebViewConfiguration new]);
+    EXPECT_TRUE(webViewConfiguration.get().defaultWebpagePreferences._captivePortalModeEnabled);
+    [webViewConfiguration.get().defaultWebpagePreferences _setCaptivePortalModeEnabled:NO]; // Explicitly opt out via default WKWebpagePreferences.
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+    auto delegate = adoptNS([TestNavigationDelegate new]);
+    [webView setNavigationDelegate:delegate.get()];
+
+    EXPECT_TRUE(isJITEnabled(webView.get()));
+
+    __block bool finishedNavigation = false;
+    delegate.get().didFinishNavigation = ^(WKWebView *, WKNavigation *) {
+        finishedNavigation = true;
+    };
+
+    NSURL *url = "" mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
+    [webView loadRequest:[NSURLRequest requestWithURL:url]];
+    TestWebKitAPI::Util::run(&finishedNavigation);
+
+    pid_t pid1 = [webView _webProcessIdentifier];
+    EXPECT_NE(pid1, 0);
+
+    EXPECT_TRUE(isJITEnabled(webView.get()));
+
+    finishedNavigation = false;
+    // Now change the global setting.
+    [WKProcessPool _clearCaptivePortalModeEnabledGloballyForTesting];
+
+    // This should not reload the web view since the view has explicitly opted out of captive portal mode.
+    TestWebKitAPI::Util::sleep(0.5);
+    EXPECT_FALSE(finishedNavigation);
+
+    pid_t pid2 = [webView _webProcessIdentifier];
+    EXPECT_EQ(pid1, pid2);
+
+    EXPECT_TRUE(isJITEnabled(webView.get()));
+}
+
+TEST(ProcessSwap, CaptivePortalModeSystemSettingChangeDoesNotReloadViewsWhenModeIsSetExplicitly3)
+{
+    // Captive portal mode is disabled globally and explicitly opted out for the load.
+
+    auto webViewConfiguration = adoptNS([WKWebViewConfiguration new]);
+    EXPECT_FALSE(webViewConfiguration.get().defaultWebpagePreferences._captivePortalModeEnabled);
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+    auto delegate = adoptNS([TestNavigationDelegate new]);
+    [webView setNavigationDelegate:delegate.get()];
+
+    EXPECT_TRUE(isJITEnabled(webView.get()));
+
+    __block bool finishedNavigation = false;
+    delegate.get().didFinishNavigation = ^(WKWebView *, WKNavigation *) {
+        finishedNavigation = true;
+    };
+
+    delegate.get().decidePolicyForNavigationActionWithPreferences = ^(WKNavigationAction *action, WKWebpagePreferences *preferences, void (^completionHandler)(WKNavigationActionPolicy, WKWebpagePreferences *)) {
+        EXPECT_FALSE(preferences._captivePortalModeEnabled);
+        [preferences _setCaptivePortalModeEnabled:NO]; // Explicitly Opt out of captive portal mode for this load.
+        completionHandler(WKNavigationActionPolicyAllow, preferences);
+    };
+
+    NSURL *url = "" mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
+    [webView loadRequest:[NSURLRequest requestWithURL:url]];
+    TestWebKitAPI::Util::run(&finishedNavigation);
+
+    pid_t pid1 = [webView _webProcessIdentifier];
+    EXPECT_NE(pid1, 0);
+
+    EXPECT_TRUE(isJITEnabled(webView.get()));
+
+    finishedNavigation = false;
+    // Now change the global setting.
+    [WKProcessPool _setCaptivePortalModeEnabledGloballyForTesting:YES];
+
+    // This should not reload the web view since the view has explicitly opted out of captive portal mode.
+    TestWebKitAPI::Util::sleep(0.5);
+    EXPECT_FALSE(finishedNavigation);
+
+    pid_t pid2 = [webView _webProcessIdentifier];
+    EXPECT_EQ(pid1, pid2);
+
+    EXPECT_TRUE(isJITEnabled(webView.get()));
+
+    [WKProcessPool _clearCaptivePortalModeEnabledGloballyForTesting];
+}
+
+TEST(ProcessSwap, CaptivePortalModeSystemSettingChangeDoesNotReloadViewsWhenModeIsSetExplicitly4)
+{
+    // Captive portal mode is enabled globally but explicitly opted out for the load.
+    [WKProcessPool _setCaptivePortalModeEnabledGloballyForTesting:YES];
+
+    auto webViewConfiguration = adoptNS([WKWebViewConfiguration new]);
+    EXPECT_TRUE(webViewConfiguration.get().defaultWebpagePreferences._captivePortalModeEnabled);
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+    auto delegate = adoptNS([TestNavigationDelegate new]);
+    [webView setNavigationDelegate:delegate.get()];
+
+    EXPECT_FALSE(isJITEnabled(webView.get()));
+
+    __block bool finishedNavigation = false;
+    delegate.get().didFinishNavigation = ^(WKWebView *, WKNavigation *) {
+        finishedNavigation = true;
+    };
+
+    delegate.get().decidePolicyForNavigationActionWithPreferences = ^(WKNavigationAction *action, WKWebpagePreferences *preferences, void (^completionHandler)(WKNavigationActionPolicy, WKWebpagePreferences *)) {
+        EXPECT_TRUE(preferences._captivePortalModeEnabled);
+        [preferences _setCaptivePortalModeEnabled:NO]; // Explicitly Opt out of captive portal mode for this load.
+        completionHandler(WKNavigationActionPolicyAllow, preferences);
+    };
+
+    NSURL *url = "" mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
+    [webView loadRequest:[NSURLRequest requestWithURL:url]];
+    TestWebKitAPI::Util::run(&finishedNavigation);
+
+    pid_t pid1 = [webView _webProcessIdentifier];
+    EXPECT_NE(pid1, 0);
+
+    EXPECT_TRUE(isJITEnabled(webView.get()));
+
+    finishedNavigation = false;
+    // Now change the global setting.
+    [WKProcessPool _clearCaptivePortalModeEnabledGloballyForTesting];
+
+    // This should not reload the web view since the view has explicitly opted out of captive portal mode.
+    TestWebKitAPI::Util::sleep(0.5);
+    EXPECT_FALSE(finishedNavigation);
+
+    pid_t pid2 = [webView _webProcessIdentifier];
+    EXPECT_EQ(pid1, pid2);
+
+    EXPECT_TRUE(isJITEnabled(webView.get()));
+
+}
+
 #endif
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to