Diff
Modified: trunk/Source/WebKit/ChangeLog (285593 => 285594)
--- trunk/Source/WebKit/ChangeLog 2021-11-10 19:04:38 UTC (rev 285593)
+++ trunk/Source/WebKit/ChangeLog 2021-11-10 19:14:25 UTC (rev 285594)
@@ -1,3 +1,77 @@
+2021-11-10 Chris Dumez <[email protected]>
+
+ Add basic support for launching CaptivePortalMode WebProcesses
+ https://bugs.webkit.org/show_bug.cgi?id=232737
+ <rdar://84473037>
+
+ Reviewed by Brent Fulgham.
+
+ Add new `WKWebpagePreferences.captivePortalModeEnabled` API to allow clients apps to opt in or
+ out of captive portal mode for each navigation (WKWebpagePreferences is passed with the navigation
+ policy decision). For setting the default state of this setting, the client can set
+ `WebWebViewConfiguration.defaultWebpagePreferences.captivePortalModeEnabled` (will impact all views
+ using this configuration).
+
+ Note that both this property can only be set by apps with the browser entitlement on iOS (no
+ restriction on macOS). On iOS, the default value of WKWebpagePreferences.captivePortalModeEnabled
+ depends on the corresponding system setting. For now, this is simulated by a NSUserDefault but it
+ will eventually come from somewhere else (TCC?).
+
+ Whenever transitioning in or out of captive portal mode, we process-swap on navigation policy
+ decision. Whenever captive portal mode is enabled, we turn off JIT, generational and concurrent GC
+ in the WebProcess, as soon as it launches.
+
+ Covered by new API tests.
+
+ * Shared/EntryPointUtilities/Cocoa/XPCService/XPCServiceEntryPoint.h:
+ (WebKit::XPCServiceInitializer):
+ * UIProcess/API/APIPageConfiguration.cpp:
+ (API::PageConfiguration::captivePortalModeEnabled const):
+ * UIProcess/API/APIPageConfiguration.h:
+ * UIProcess/API/APIWebsitePolicies.cpp:
+ (API::WebsitePolicies::copy const):
+ (API::WebsitePolicies::captivePortalModeEnabled const):
+ * UIProcess/API/APIWebsitePolicies.h:
+ * UIProcess/API/Cocoa/WKWebpagePreferences.h:
+ * UIProcess/API/Cocoa/WKWebpagePreferences.mm:
+ (-[WKWebpagePreferences setCaptivePortalModeEnabled:]):
+ (-[WKWebpagePreferences captivePortalModeEnabled]):
+ * UIProcess/Cocoa/WebProcessPoolCocoa.mm:
+ (WebKit::captivePortalModeEnabledBySystem):
+ * UIProcess/Launcher/ProcessLauncher.h:
+ (WebKit::ProcessLauncher::Client::shouldEnableCaptivePortalMode const):
+ * UIProcess/Launcher/mac/ProcessLauncherMac.mm:
+ (WebKit::ProcessLauncher::launchProcess):
+ * UIProcess/SuspendedPageProxy.cpp:
+ (WebKit::SuspendedPageProxy::findReusableSuspendedPageProcess):
+ * UIProcess/SuspendedPageProxy.h:
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::launchProcess):
+ (WebKit::WebPageProxy::receivedNavigationPolicyDecision):
+ (WebKit::WebPageProxy::triggerBrowsingContextGroupSwitchForNavigation):
+ (WebKit::WebPageProxy::isJITEnabled):
+ (WebKit::WebPageProxy::shouldEnableCaptivePortalMode const):
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/WebProcessCache.cpp:
+ (WebKit::WebProcessCache::takeProcess):
+ * UIProcess/WebProcessCache.h:
+ * UIProcess/WebProcessPool.cpp:
+ (WebKit::WebProcessPool::createNewWebProcess):
+ (WebKit::WebProcessPool::tryTakePrewarmedProcess):
+ (WebKit::WebProcessPool::prewarmProcess):
+ (WebKit::WebProcessPool::processForRegistrableDomain):
+ (WebKit::WebProcessPool::createWebPage):
+ (WebKit::WebProcessPool::processForNavigation):
+ (WebKit::WebProcessPool::processForNavigationInternal):
+ (WebKit::captivePortalModeEnabledBySystem):
+ * UIProcess/WebProcessPool.h:
+ * UIProcess/WebProcessProxy.cpp:
+ (WebKit::WebProcessProxy::create):
+ (WebKit::WebProcessProxy::createForServiceWorkers):
+ (WebKit::WebProcessProxy::WebProcessProxy):
+ * UIProcess/WebProcessProxy.h:
+ (WebKit::WebProcessProxy::captivePortalMode const):
+
2021-11-10 Per Arne Vollan <[email protected]>
[iOS][GPUP] Remove sandbox read access to files
Modified: trunk/Source/WebKit/Shared/EntryPointUtilities/Cocoa/XPCService/XPCServiceEntryPoint.h (285593 => 285594)
--- trunk/Source/WebKit/Shared/EntryPointUtilities/Cocoa/XPCService/XPCServiceEntryPoint.h 2021-11-10 19:04:38 UTC (rev 285593)
+++ trunk/Source/WebKit/Shared/EntryPointUtilities/Cocoa/XPCService/XPCServiceEntryPoint.h 2021-11-10 19:14:25 UTC (rev 285594)
@@ -89,6 +89,13 @@
if (initializerMessage) {
if (xpc_dictionary_get_bool(initializerMessage, "configure-jsc-for-testing"))
JSC::Config::configureForTesting();
+ if (xpc_dictionary_get_bool(initializerMessage, "enable-captive-portal-mode")) {
+ JSC::ExecutableAllocator::setJITEnabled(false);
+ JSC::Options::initialize();
+ JSC::Options::AllowUnfinalizedAccessScope scope;
+ JSC::Options::useGenerationalGC() = false;
+ JSC::Options::useConcurrentGC() = false;
+ }
if (xpc_dictionary_get_bool(initializerMessage, "disable-jit"))
JSC::ExecutableAllocator::setJITEnabled(false);
if (xpc_dictionary_get_bool(initializerMessage, "enable-shared-array-buffer")) {
Modified: trunk/Source/WebKit/UIProcess/API/APIPageConfiguration.cpp (285593 => 285594)
--- trunk/Source/WebKit/UIProcess/API/APIPageConfiguration.cpp 2021-11-10 19:04:38 UTC (rev 285593)
+++ trunk/Source/WebKit/UIProcess/API/APIPageConfiguration.cpp 2021-11-10 19:14:25 UTC (rev 285594)
@@ -197,6 +197,13 @@
m_urlSchemeHandlers.set(scheme, WTFMove(handler));
}
+bool PageConfiguration::captivePortalModeEnabled() const
+{
+ if (m_defaultWebsitePolicies)
+ return m_defaultWebsitePolicies->captivePortalModeEnabled();
+ return captivePortalModeEnabledBySystem();
+}
+
#if ENABLE(APPLICATION_MANIFEST)
ApplicationManifest* PageConfiguration::applicationManifest() const
{
Modified: trunk/Source/WebKit/UIProcess/API/APIPageConfiguration.h (285593 => 285594)
--- trunk/Source/WebKit/UIProcess/API/APIPageConfiguration.h 2021-11-10 19:04:38 UTC (rev 285593)
+++ trunk/Source/WebKit/UIProcess/API/APIPageConfiguration.h 2021-11-10 19:14:25 UTC (rev 285594)
@@ -189,6 +189,8 @@
void setRequiresUserActionForEditingControlsManager(bool value) { m_requiresUserActionForEditingControlsManager = value; }
#endif
+ bool captivePortalModeEnabled() const;
+
private:
RefPtr<WebKit::WebProcessPool> m_processPool;
Modified: trunk/Source/WebKit/UIProcess/API/APIWebsitePolicies.cpp (285593 => 285594)
--- trunk/Source/WebKit/UIProcess/API/APIWebsitePolicies.cpp 2021-11-10 19:04:38 UTC (rev 285593)
+++ trunk/Source/WebKit/UIProcess/API/APIWebsitePolicies.cpp 2021-11-10 19:14:25 UTC (rev 285594)
@@ -26,6 +26,7 @@
#include "config.h"
#include "APIWebsitePolicies.h"
+#include "WebProcessPool.h"
#include "WebUserContentControllerProxy.h"
#include "WebsiteDataStore.h"
#include "WebsitePoliciesData.h"
@@ -72,6 +73,7 @@
policies->setAllowSiteSpecificQuirksToOverrideContentMode(m_allowSiteSpecificQuirksToOverrideContentMode);
policies->setApplicationNameForDesktopUserAgent(m_applicationNameForDesktopUserAgent);
policies->setAllowsContentJavaScript(m_allowsContentJavaScript);
+ policies->setCaptivePortalModeEnabled(m_captivePortalModeEnabled);
policies->setMouseEventPolicy(m_mouseEventPolicy);
return policies;
}
@@ -123,5 +125,10 @@
};
}
+bool WebsitePolicies::captivePortalModeEnabled() const
+{
+ return m_captivePortalModeEnabled ? *m_captivePortalModeEnabled : WebKit::captivePortalModeEnabledBySystem();
}
+}
+
Modified: trunk/Source/WebKit/UIProcess/API/APIWebsitePolicies.h (285593 => 285594)
--- trunk/Source/WebKit/UIProcess/API/APIWebsitePolicies.h 2021-11-10 19:04:38 UTC (rev 285593)
+++ trunk/Source/WebKit/UIProcess/API/APIWebsitePolicies.h 2021-11-10 19:14:25 UTC (rev 285594)
@@ -125,6 +125,9 @@
WebCore::AllowsContentJavaScript allowsContentJavaScript() const { return m_allowsContentJavaScript; }
void setAllowsContentJavaScript(WebCore::AllowsContentJavaScript allows) { m_allowsContentJavaScript = allows; }
+ bool captivePortalModeEnabled() const;
+ void setCaptivePortalModeEnabled(std::optional<bool> captivePortalModeEnabled) { m_captivePortalModeEnabled = captivePortalModeEnabled; }
+
WebCore::MouseEventPolicy mouseEventPolicy() const { return m_mouseEventPolicy; }
void setMouseEventPolicy(WebCore::MouseEventPolicy policy) { m_mouseEventPolicy = policy; }
@@ -157,6 +160,7 @@
WebCore::AllowsContentJavaScript m_allowsContentJavaScript { WebCore::AllowsContentJavaScript::Yes };
WebCore::MouseEventPolicy m_mouseEventPolicy { WebCore::MouseEventPolicy::Default };
bool m_idempotentModeAutosizingOnlyHonorsPercentages { false };
+ std::optional<bool> m_captivePortalModeEnabled;
};
} // namespace API
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebpagePreferences.h (285593 => 285594)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebpagePreferences.h 2021-11-10 19:04:38 UTC (rev 285593)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebpagePreferences.h 2021-11-10 19:14:25 UTC (rev 285594)
@@ -71,4 +71,9 @@
*/
@property (nonatomic) BOOL allowsContentJavaScript WK_API_AVAILABLE(macos(11.0), ios(14.0));
+/*! @abstract A boolean indicating whether Captive Portal mode is enabled.
+ @discussion The default value is NO on macOS. On iOS, the default value depends on the system setting.
+ */
+@property (nonatomic) BOOL captivePortalModeEnabled WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+
@end
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebpagePreferences.mm (285593 => 285594)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebpagePreferences.mm 2021-11-10 19:04:38 UTC (rev 285593)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebpagePreferences.mm 2021-11-10 19:14:25 UTC (rev 285594)
@@ -36,6 +36,10 @@
#import <WebCore/WebCoreObjCExtras.h>
#import <wtf/RetainPtr.h>
+#if PLATFORM(IOS_FAMILY)
+#import <wtf/cocoa/Entitlements.h>
+#endif
+
namespace WebKit {
#if PLATFORM(IOS_FAMILY)
@@ -387,8 +391,22 @@
}
}
+- (void)setCaptivePortalModeEnabled:(BOOL)captivePortalModeEnabled
+{
#if PLATFORM(IOS_FAMILY)
+ if (!WTF::processHasEntitlement("com.apple.developer.web-browser"))
+ return;
+#endif
+ _websitePolicies->setCaptivePortalModeEnabled(!!captivePortalModeEnabled);
+}
+- (BOOL)captivePortalModeEnabled
+{
+ return _websitePolicies->captivePortalModeEnabled();
+}
+
+#if PLATFORM(IOS_FAMILY)
+
- (void)setPreferredContentMode:(WKContentMode)contentMode
{
_websitePolicies->setPreferredContentMode(WebKit::webContentMode(contentMode));
Modified: trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm (285593 => 285594)
--- trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm 2021-11-10 19:04:38 UTC (rev 285593)
+++ trunk/Source/WebKit/UIProcess/Cocoa/WebProcessPoolCocoa.mm 2021-11-10 19:14:25 UTC (rev 285594)
@@ -961,6 +961,18 @@
}
#if PLATFORM(IOS_FAMILY)
+
+bool captivePortalModeEnabledBySystem()
+{
+ static std::optional<bool> cachedCaptivePortalModeEnabledGlobally;
+ // FIXME: We should invalidate the cached value when the NSUserDefault changes.
+ if (!cachedCaptivePortalModeEnabledGlobally) {
+ // FIXME: Using NSUserDefaults is a temporary workaround. This setting should be stored elsewhere (TCC?).
+ cachedCaptivePortalModeEnabledGlobally = [[NSUserDefaults standardUserDefaults] boolForKey:@"WebKitCaptivePortalModeEnabled"];
+ }
+ return *cachedCaptivePortalModeEnabledGlobally;
+}
+
void WebProcessPool::applicationIsAboutToSuspend()
{
WEBPROCESSPOOL_RELEASE_LOG(ProcessSuspension, "applicationIsAboutToSuspend: Terminating non-critical processes");
Modified: trunk/Source/WebKit/UIProcess/Launcher/ProcessLauncher.h (285593 => 285594)
--- trunk/Source/WebKit/UIProcess/Launcher/ProcessLauncher.h 2021-11-10 19:04:38 UTC (rev 285593)
+++ trunk/Source/WebKit/UIProcess/Launcher/ProcessLauncher.h 2021-11-10 19:14:25 UTC (rev 285594)
@@ -62,6 +62,7 @@
virtual bool shouldConfigureJSCForTesting() const { return false; }
virtual bool isJITEnabled() const { return true; }
virtual bool shouldEnableSharedArrayBuffer() const { return false; }
+ virtual bool shouldEnableCaptivePortalMode() const { return false; }
#if PLATFORM(COCOA)
virtual RefPtr<XPCEventHandler> xpcEventHandler() const { return nullptr; }
#endif
Modified: trunk/Source/WebKit/UIProcess/Launcher/mac/ProcessLauncherMac.mm (285593 => 285594)
--- trunk/Source/WebKit/UIProcess/Launcher/mac/ProcessLauncherMac.mm 2021-11-10 19:04:38 UTC (rev 285593)
+++ trunk/Source/WebKit/UIProcess/Launcher/mac/ProcessLauncherMac.mm 2021-11-10 19:14:25 UTC (rev 285594)
@@ -203,6 +203,8 @@
xpc_dictionary_set_bool(bootstrapMessage.get(), "disable-jit", true);
if (m_client->shouldEnableSharedArrayBuffer())
xpc_dictionary_set_bool(bootstrapMessage.get(), "enable-shared-array-buffer", true);
+ if (m_client->shouldEnableCaptivePortalMode())
+ xpc_dictionary_set_bool(bootstrapMessage.get(), "enable-captive-portal-mode", true);
}
xpc_dictionary_set_string(bootstrapMessage.get(), "message-name", "bootstrap");
Modified: trunk/Source/WebKit/UIProcess/SuspendedPageProxy.cpp (285593 => 285594)
--- trunk/Source/WebKit/UIProcess/SuspendedPageProxy.cpp 2021-11-10 19:04:38 UTC (rev 285593)
+++ trunk/Source/WebKit/UIProcess/SuspendedPageProxy.cpp 2021-11-10 19:14:25 UTC (rev 285594)
@@ -34,7 +34,6 @@
#include "WebPageProxyMessages.h"
#include "WebProcessMessages.h"
#include "WebProcessPool.h"
-#include "WebProcessProxy.h"
#include <wtf/DebugUtilities.h>
#include <wtf/HexNumber.h>
#include <wtf/URL.h>
@@ -50,11 +49,11 @@
return map;
}
-RefPtr<WebProcessProxy> SuspendedPageProxy::findReusableSuspendedPageProcess(WebProcessPool& processPool, const RegistrableDomain& registrableDomain, WebsiteDataStore& dataStore)
+RefPtr<WebProcessProxy> SuspendedPageProxy::findReusableSuspendedPageProcess(WebProcessPool& processPool, const RegistrableDomain& registrableDomain, WebsiteDataStore& dataStore, WebProcessProxy::CaptivePortalMode captivePortalMode)
{
for (auto* suspendedPage : allSuspendedPages()) {
auto& process = suspendedPage->process();
- if (&process.processPool() == &processPool && process.registrableDomain() == registrableDomain && &process.websiteDataStore() == &dataStore && process.crossOriginMode() != CrossOriginMode::Isolated)
+ if (&process.processPool() == &processPool && process.registrableDomain() == registrableDomain && &process.websiteDataStore() == &dataStore && process.crossOriginMode() != CrossOriginMode::Isolated && process.captivePortalMode() == captivePortalMode)
return &process;
}
return nullptr;
Modified: trunk/Source/WebKit/UIProcess/SuspendedPageProxy.h (285593 => 285594)
--- trunk/Source/WebKit/UIProcess/SuspendedPageProxy.h 2021-11-10 19:04:38 UTC (rev 285593)
+++ trunk/Source/WebKit/UIProcess/SuspendedPageProxy.h 2021-11-10 19:14:25 UTC (rev 285594)
@@ -30,6 +30,7 @@
#include "ProcessThrottler.h"
#include "WebBackForwardListItem.h"
#include "WebPageProxyMessagesReplies.h"
+#include "WebProcessProxy.h"
#include <WebCore/FrameIdentifier.h>
#include <wtf/RefCounted.h>
#include <wtf/WeakPtr.h>
@@ -43,7 +44,6 @@
class WebBackForwardCache;
class WebPageProxy;
class WebProcessPool;
-class WebProcessProxy;
class WebsiteDataStore;
#if HAVE(VISIBILITY_PROPAGATION_VIEW)
@@ -58,7 +58,7 @@
SuspendedPageProxy(WebPageProxy&, Ref<WebProcessProxy>&&, WebCore::FrameIdentifier mainFrameID, ShouldDelayClosingUntilFirstLayerFlush);
~SuspendedPageProxy();
- static RefPtr<WebProcessProxy> findReusableSuspendedPageProcess(WebProcessPool&, const WebCore::RegistrableDomain&, WebsiteDataStore&);
+ static RefPtr<WebProcessProxy> findReusableSuspendedPageProcess(WebProcessPool&, const WebCore::RegistrableDomain&, WebsiteDataStore&, WebProcessProxy::CaptivePortalMode);
WebPageProxy& page() const { return m_page; }
WebCore::PageIdentifier webPageID() const { return m_webPageID; }
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (285593 => 285594)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2021-11-10 19:04:38 UTC (rev 285593)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2021-11-10 19:14:25 UTC (rev 285594)
@@ -861,7 +861,7 @@
if (relatedPage && !relatedPage->isClosed())
m_process = relatedPage->ensureRunningProcess();
else
- m_process = processPool.processForRegistrableDomain(m_websiteDataStore.get(), this, registrableDomain);
+ m_process = processPool.processForRegistrableDomain(m_websiteDataStore.get(), registrableDomain, shouldEnableCaptivePortalMode() ? WebProcessProxy::CaptivePortalMode::Enabled : WebProcessProxy::CaptivePortalMode::Disabled);
m_hasRunningProcess = true;
m_process->addExistingWebPage(*this, WebProcessProxy::BeginsUsingDataStore::Yes);
@@ -3436,7 +3436,8 @@
}
}
- process().processPool().processForNavigation(*this, *navigation, sourceProcess.copyRef(), sourceURL, processSwapRequestedByClient, frameInfo, WTFMove(websiteDataStore), [this, protectedThis = Ref { *this }, policyAction, navigation = Ref { *navigation }, navigationAction = WTFMove(navigationAction), sourceProcess = sourceProcess.copyRef(),
+ 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 {
// If the navigation has been destroyed, then no need to proceed.
if (isClosed() || !navigationState().hasNavigation(navigation->navigationID())) {
@@ -5639,9 +5640,9 @@
RefPtr<WebProcessProxy> processForNavigation;
if (browsingContextGroupSwitchDecision == BrowsingContextGroupSwitchDecision::NewIsolatedGroup)
- processForNavigation = m_process->processPool().createNewWebProcess(&websiteDataStore(), WebProcessProxy::IsPrewarmed::No, CrossOriginMode::Isolated);
+ processForNavigation = m_process->processPool().createNewWebProcess(&websiteDataStore(), m_process->captivePortalMode(), WebProcessProxy::IsPrewarmed::No, CrossOriginMode::Isolated);
else
- processForNavigation = m_process->processPool().processForRegistrableDomain(websiteDataStore(), this, responseDomain);
+ processForNavigation = m_process->processPool().processForRegistrableDomain(websiteDataStore(), responseDomain, m_process->captivePortalMode());
continueNavigationInNewProcess(*navigation, nullptr, processForNavigation.releaseNonNull(), ProcessSwapRequestedByClient::No, ShouldTreatAsContinuingLoad::YesAfterProvisionalLoadStarted, nullptr, existingNetworkResourceLoadIdentifierToResume);
completionHandler(true);
@@ -8322,6 +8323,7 @@
void WebPageProxy::isJITEnabled(CompletionHandler<void(bool)>&& completionHandler)
{
+ launchInitialProcessIfNecessary();
sendWithAsyncReply(Messages::WebProcess::IsJITEnabled(), WTFMove(completionHandler), 0);
}
@@ -10870,6 +10872,11 @@
send(Messages::WebPage::ScrollToRect(targetRect, origin));
}
+bool WebPageProxy::shouldEnableCaptivePortalMode() const
+{
+ return m_configuration->captivePortalModeEnabled();
+}
+
#if PLATFORM(COCOA)
void WebPageProxy::appPrivacyReportTestingData(CompletionHandler<void(const AppPrivacyReportTestingData&)>&& completionHandler)
{
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (285593 => 285594)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2021-11-10 19:04:38 UTC (rev 285593)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2021-11-10 19:14:25 UTC (rev 285594)
@@ -494,6 +494,8 @@
void addPreviouslyVisitedPath(const String&);
+ bool shouldEnableCaptivePortalMode() const;
+
#if ENABLE(DATA_DETECTION)
NSArray *dataDetectionResults() { return m_dataDetectionResults.get(); }
void detectDataInAllFrames(OptionSet<WebCore::DataDetectorType>, CompletionHandler<void(const DataDetectionResult&)>&&);
Modified: trunk/Source/WebKit/UIProcess/WebProcessCache.cpp (285593 => 285594)
--- trunk/Source/WebKit/UIProcess/WebProcessCache.cpp 2021-11-10 19:04:38 UTC (rev 285593)
+++ trunk/Source/WebKit/UIProcess/WebProcessCache.cpp 2021-11-10 19:14:25 UTC (rev 285594)
@@ -29,7 +29,6 @@
#include "LegacyGlobalSettings.h"
#include "Logging.h"
#include "WebProcessPool.h"
-#include "WebProcessProxy.h"
#include <wtf/RAMSize.h>
#include <wtf/StdLibExtras.h>
@@ -148,7 +147,7 @@
return true;
}
-RefPtr<WebProcessProxy> WebProcessCache::takeProcess(const WebCore::RegistrableDomain& registrableDomain, WebsiteDataStore& dataStore)
+RefPtr<WebProcessProxy> WebProcessCache::takeProcess(const WebCore::RegistrableDomain& registrableDomain, WebsiteDataStore& dataStore, WebProcessProxy::CaptivePortalMode captivePortalMode)
{
auto it = m_processesPerRegistrableDomain.find(registrableDomain);
if (it == m_processesPerRegistrableDomain.end())
@@ -157,6 +156,9 @@
if (&it->value->process().websiteDataStore() != &dataStore)
return nullptr;
+ if (it->value->process().captivePortalMode() != captivePortalMode)
+ return nullptr;
+
auto process = it->value->takeProcess();
m_processesPerRegistrableDomain.remove(it);
WEBPROCESSCACHE_RELEASE_LOG("takeProcess: Taking process from WebProcess cache (size=%u, capacity=%u)", process->processIdentifier(), size(), capacity());
Modified: trunk/Source/WebKit/UIProcess/WebProcessCache.h (285593 => 285594)
--- trunk/Source/WebKit/UIProcess/WebProcessCache.h 2021-11-10 19:04:38 UTC (rev 285593)
+++ trunk/Source/WebKit/UIProcess/WebProcessCache.h 2021-11-10 19:14:25 UTC (rev 285594)
@@ -26,6 +26,7 @@
#pragma once
+#include "WebProcessProxy.h"
#include <WebCore/RegistrableDomain.h>
#include <pal/SessionID.h>
#include <wtf/HashMap.h>
@@ -35,7 +36,6 @@
namespace WebKit {
class WebProcessPool;
-class WebProcessProxy;
class WebsiteDataStore;
class WebProcessCache {
@@ -44,7 +44,7 @@
explicit WebProcessCache(WebProcessPool&);
bool addProcessIfPossible(Ref<WebProcessProxy>&&);
- RefPtr<WebProcessProxy> takeProcess(const WebCore::RegistrableDomain&, WebsiteDataStore&);
+ RefPtr<WebProcessProxy> takeProcess(const WebCore::RegistrableDomain&, WebsiteDataStore&, WebProcessProxy::CaptivePortalMode);
void updateCapacity(WebProcessPool&);
unsigned capacity() const { return m_capacity; }
Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.cpp (285593 => 285594)
--- trunk/Source/WebKit/UIProcess/WebProcessPool.cpp 2021-11-10 19:04:38 UTC (rev 285593)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.cpp 2021-11-10 19:14:25 UTC (rev 285594)
@@ -617,7 +617,7 @@
platformResolvePathsForSandboxExtensions();
}
-Ref<WebProcessProxy> WebProcessPool::createNewWebProcess(WebsiteDataStore* websiteDataStore, WebProcessProxy::IsPrewarmed isPrewarmed, CrossOriginMode crossOriginMode)
+Ref<WebProcessProxy> WebProcessPool::createNewWebProcess(WebsiteDataStore* websiteDataStore, WebProcessProxy::CaptivePortalMode captivePortalMode, WebProcessProxy::IsPrewarmed isPrewarmed, CrossOriginMode crossOriginMode)
{
#if PLATFORM(COCOA)
m_tccPreferenceEnabled = doesAppHaveITPEnabled();
@@ -625,7 +625,7 @@
websiteDataStore->setResourceLoadStatisticsEnabled(m_tccPreferenceEnabled);
#endif
- auto processProxy = WebProcessProxy::create(*this, websiteDataStore, isPrewarmed, crossOriginMode);
+ auto processProxy = WebProcessProxy::create(*this, websiteDataStore, captivePortalMode, isPrewarmed, crossOriginMode);
initializeNewWebProcess(processProxy, websiteDataStore, isPrewarmed);
m_processes.append(processProxy.copyRef());
@@ -632,7 +632,7 @@
return processProxy;
}
-RefPtr<WebProcessProxy> WebProcessPool::tryTakePrewarmedProcess(WebsiteDataStore& websiteDataStore)
+RefPtr<WebProcessProxy> WebProcessPool::tryTakePrewarmedProcess(WebsiteDataStore& websiteDataStore, WebProcessProxy::CaptivePortalMode captivePortalMode)
{
if (!m_prewarmedProcess)
return nullptr;
@@ -645,6 +645,9 @@
return nullptr;
}
+ if (m_prewarmedProcess->captivePortalMode() != captivePortalMode)
+ return nullptr;
+
#if PLATFORM(GTK) || PLATFORM(WPE)
// In platforms using Bubblewrap for sandboxing, prewarmed process is launched using the WebProcessPool primary WebsiteDataStore,
// so we don't use it in case of using a different WebsiteDataStore.
@@ -893,7 +896,12 @@
return;
WEBPROCESSPOOL_RELEASE_LOG(PerformanceLogging, "prewarmProcess: Prewarming a WebProcess for performance");
- createNewWebProcess(nullptr, WebProcessProxy::IsPrewarmed::Yes);
+
+ auto captivePortalMode = WebProcessProxy::CaptivePortalMode::Disabled;
+ if (!m_processes.isEmpty())
+ captivePortalMode = m_processes.last()->captivePortalMode();
+
+ createNewWebProcess(nullptr, captivePortalMode, WebProcessProxy::IsPrewarmed::Yes);
}
void WebProcessPool::enableProcessTermination()
@@ -993,16 +1001,16 @@
removeProcessFromOriginCacheSet(process);
}
-Ref<WebProcessProxy> WebProcessPool::processForRegistrableDomain(WebsiteDataStore& websiteDataStore, WebPageProxy* page, const RegistrableDomain& registrableDomain)
+Ref<WebProcessProxy> WebProcessPool::processForRegistrableDomain(WebsiteDataStore& websiteDataStore, const RegistrableDomain& registrableDomain, WebProcessProxy::CaptivePortalMode captivePortalMode)
{
if (!registrableDomain.isEmpty()) {
- if (auto process = webProcessCache().takeProcess(registrableDomain, websiteDataStore)) {
+ if (auto process = webProcessCache().takeProcess(registrableDomain, websiteDataStore, captivePortalMode)) {
ASSERT(m_processes.contains(*process));
return process.releaseNonNull();
}
// Check if we have a suspended page for the given registrable domain and use its process if we do, for performance reasons.
- if (auto process = SuspendedPageProxy::findReusableSuspendedPageProcess(*this, registrableDomain, websiteDataStore)) {
+ if (auto process = SuspendedPageProxy::findReusableSuspendedPageProcess(*this, registrableDomain, websiteDataStore, captivePortalMode)) {
WEBPROCESSPOOL_RELEASE_LOG(ProcessSwapping, "processForRegistrableDomain: Using WebProcess from a SuspendedPage (process=%p, PID=%i)", process.get(), process->processIdentifier());
ASSERT(m_processes.contains(*process));
return process.releaseNonNull();
@@ -1009,7 +1017,7 @@
}
}
- if (auto process = tryTakePrewarmedProcess(websiteDataStore)) {
+ if (auto process = tryTakePrewarmedProcess(websiteDataStore, captivePortalMode)) {
WEBPROCESSPOOL_RELEASE_LOG(ProcessSwapping, "processForRegistrableDomain: Using prewarmed process (process=%p, PID=%i)", process.get(), process->processIdentifier());
if (!registrableDomain.isEmpty())
tryPrewarmWithDomainInformation(*process, registrableDomain);
@@ -1036,7 +1044,7 @@
return process;
}
}
- return createNewWebProcess(&websiteDataStore);
+ return createNewWebProcess(&websiteDataStore, captivePortalMode);
}
#if ENABLE(SERVICE_WORKER)
@@ -1067,6 +1075,7 @@
}
RefPtr<WebProcessProxy> process;
+ auto captivePortalMode = pageConfiguration->captivePortalModeEnabled() ? WebProcessProxy::CaptivePortalMode::Enabled : WebProcessProxy::CaptivePortalMode::Disabled;
auto* relatedPage = pageConfiguration->relatedPage();
if (relatedPage && !relatedPage->isClosed()) {
// Sharing processes, e.g. when creating the page via window.open().
@@ -1078,12 +1087,12 @@
// In the common case, we delay process launch until something is actually loaded in the page.
process = dummyProcessProxy(pageConfiguration->websiteDataStore()->sessionID());
if (!process) {
- process = WebProcessProxy::create(*this, pageConfiguration->websiteDataStore(), WebProcessProxy::IsPrewarmed::No, CrossOriginMode::Shared, WebProcessProxy::ShouldLaunchProcess::No);
+ process = WebProcessProxy::create(*this, pageConfiguration->websiteDataStore(), captivePortalMode, WebProcessProxy::IsPrewarmed::No, CrossOriginMode::Shared, WebProcessProxy::ShouldLaunchProcess::No);
m_dummyProcessProxies.add(pageConfiguration->websiteDataStore()->sessionID(), *process);
m_processes.append(*process);
}
} else
- process = processForRegistrableDomain(*pageConfiguration->websiteDataStore(), nullptr, { });
+ process = processForRegistrableDomain(*pageConfiguration->websiteDataStore(), { }, captivePortalMode);
RefPtr<WebUserContentControllerProxy> userContentController = pageConfiguration->userContentController();
@@ -1804,9 +1813,9 @@
m_swappedProcessesPerRegistrableDomain.remove(registrableDomain);
}
-void WebProcessPool::processForNavigation(WebPageProxy& page, const API::Navigation& navigation, Ref<WebProcessProxy>&& sourceProcess, const URL& sourceURL, ProcessSwapRequestedByClient processSwapRequestedByClient, const FrameInfoData& frameInfo, Ref<WebsiteDataStore>&& dataStore, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&& completionHandler)
+void WebProcessPool::processForNavigation(WebPageProxy& page, const API::Navigation& navigation, Ref<WebProcessProxy>&& sourceProcess, const URL& sourceURL, ProcessSwapRequestedByClient processSwapRequestedByClient, WebProcessProxy::CaptivePortalMode captivePortalMode, const FrameInfoData& frameInfo, Ref<WebsiteDataStore>&& dataStore, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&& completionHandler)
{
- processForNavigationInternal(page, navigation, sourceProcess.copyRef(), sourceURL, processSwapRequestedByClient, frameInfo, WTFMove(dataStore), [this, page = Ref { page }, navigation = Ref { navigation }, sourceProcess = sourceProcess.copyRef(), sourceURL, processSwapRequestedByClient, completionHandler = WTFMove(completionHandler)](Ref<WebProcessProxy>&& process, SuspendedPageProxy* suspendedPage, const String& reason) mutable {
+ processForNavigationInternal(page, navigation, sourceProcess.copyRef(), sourceURL, processSwapRequestedByClient, captivePortalMode, frameInfo, WTFMove(dataStore), [this, page = Ref { page }, navigation = Ref { navigation }, sourceProcess = sourceProcess.copyRef(), sourceURL, processSwapRequestedByClient, completionHandler = WTFMove(completionHandler)](Ref<WebProcessProxy>&& process, SuspendedPageProxy* suspendedPage, const String& reason) mutable {
// We are process-swapping so automatic process prewarming would be beneficial if the client has not explicitly enabled / disabled it.
bool doingAnAutomaticProcessSwap = processSwapRequestedByClient == ProcessSwapRequestedByClient::No && process.ptr() != sourceProcess.ptr();
if (doingAnAutomaticProcessSwap && !configuration().wasAutomaticProcessWarmingSetByClient() && !configuration().clientWouldBenefitFromAutomaticProcessPrewarming()) {
@@ -1829,18 +1838,21 @@
});
}
-void WebProcessPool::processForNavigationInternal(WebPageProxy& page, const API::Navigation& navigation, Ref<WebProcessProxy>&& sourceProcess, const URL& pageSourceURL, ProcessSwapRequestedByClient processSwapRequestedByClient, const FrameInfoData& frameInfo, Ref<WebsiteDataStore>&& dataStore, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&& completionHandler)
+void WebProcessPool::processForNavigationInternal(WebPageProxy& page, const API::Navigation& navigation, Ref<WebProcessProxy>&& sourceProcess, const URL& pageSourceURL, ProcessSwapRequestedByClient processSwapRequestedByClient, WebProcessProxy::CaptivePortalMode captivePortalMode, const FrameInfoData& frameInfo, Ref<WebsiteDataStore>&& dataStore, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&& completionHandler)
{
auto& targetURL = navigation.currentRequest().url();
auto targetRegistrableDomain = WebCore::RegistrableDomain { targetURL };
- auto createNewProcess = [this, protectedThis = Ref { *this }, page = Ref { page }, targetRegistrableDomain, dataStore] () -> Ref<WebProcessProxy> {
- return processForRegistrableDomain(dataStore, page.ptr(), targetRegistrableDomain);
+ auto createNewProcess = [this, protectedThis = Ref { *this }, targetRegistrableDomain, dataStore, captivePortalMode] () -> Ref<WebProcessProxy> {
+ return processForRegistrableDomain(dataStore, targetRegistrableDomain, captivePortalMode);
};
if (usesSingleWebProcess())
return completionHandler(WTFMove(sourceProcess), nullptr, "Single WebProcess mode is enabled"_s);
+ if (sourceProcess->captivePortalMode() != captivePortalMode)
+ return completionHandler(createNewProcess(), nullptr, "Process swap due to captive portal mode change"_s);
+
if (processSwapRequestedByClient == ProcessSwapRequestedByClient::Yes)
return completionHandler(createNewProcess(), nullptr, "Process swap was requested by the client"_s);
@@ -2108,4 +2120,11 @@
}
#endif
+#if !PLATFORM(IOS_FAMILY)
+bool captivePortalModeEnabledBySystem()
+{
+ return false;
+}
+#endif
+
} // namespace WebKit
Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.h (285593 => 285594)
--- trunk/Source/WebKit/UIProcess/WebProcessPool.h 2021-11-10 19:04:38 UTC (rev 285593)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.h 2021-11-10 19:14:25 UTC (rev 285594)
@@ -119,6 +119,7 @@
int webProcessLatencyQOS();
int webProcessThroughputQOS();
#endif
+bool captivePortalModeEnabledBySystem();
enum class CallDownloadDidStart : bool;
enum class ProcessSwapRequestedByClient : bool;
@@ -303,7 +304,7 @@
void reportWebContentCPUTime(Seconds cpuTime, uint64_t activityState);
- Ref<WebProcessProxy> processForRegistrableDomain(WebsiteDataStore&, WebPageProxy*, const WebCore::RegistrableDomain&); // Will return an existing one if limit is met or due to caching.
+ Ref<WebProcessProxy> processForRegistrableDomain(WebsiteDataStore&, const WebCore::RegistrableDomain&, WebProcessProxy::CaptivePortalMode); // Will return an existing one if limit is met or due to caching.
void prewarmProcess();
@@ -438,7 +439,7 @@
bool hasForegroundWebProcesses() const { return m_foregroundWebProcessCounter.value(); }
bool hasBackgroundWebProcesses() const { return m_backgroundWebProcessCounter.value(); }
- void processForNavigation(WebPageProxy&, const API::Navigation&, Ref<WebProcessProxy>&& sourceProcess, const URL& sourceURL, ProcessSwapRequestedByClient, const FrameInfoData&, Ref<WebsiteDataStore>&&, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&&);
+ void processForNavigation(WebPageProxy&, const API::Navigation&, Ref<WebProcessProxy>&& sourceProcess, const URL& sourceURL, ProcessSwapRequestedByClient, WebProcessProxy::CaptivePortalMode, const FrameInfoData&, Ref<WebsiteDataStore>&&, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&&);
void didReachGoodTimeToPrewarm();
@@ -507,7 +508,7 @@
static String containerTemporaryDirectory();
#endif
- Ref<WebProcessProxy> createNewWebProcess(WebsiteDataStore*, WebProcessProxy::IsPrewarmed = WebProcessProxy::IsPrewarmed::No, WebCore::CrossOriginMode = WebCore::CrossOriginMode::Shared);
+ Ref<WebProcessProxy> createNewWebProcess(WebsiteDataStore*, WebProcessProxy::CaptivePortalMode, WebProcessProxy::IsPrewarmed = WebProcessProxy::IsPrewarmed::No, WebCore::CrossOriginMode = WebCore::CrossOriginMode::Shared);
private:
void platformInitialize();
@@ -515,9 +516,9 @@
void platformInitializeWebProcess(const WebProcessProxy&, WebProcessCreationParameters&);
void platformInvalidateContext();
- void processForNavigationInternal(WebPageProxy&, const API::Navigation&, Ref<WebProcessProxy>&& sourceProcess, const URL& sourceURL, ProcessSwapRequestedByClient, const FrameInfoData&, Ref<WebsiteDataStore>&&, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&&);
+ void processForNavigationInternal(WebPageProxy&, const API::Navigation&, Ref<WebProcessProxy>&& sourceProcess, const URL& sourceURL, ProcessSwapRequestedByClient, WebProcessProxy::CaptivePortalMode, const FrameInfoData&, Ref<WebsiteDataStore>&&, CompletionHandler<void(Ref<WebProcessProxy>&&, SuspendedPageProxy*, const String&)>&&);
- RefPtr<WebProcessProxy> tryTakePrewarmedProcess(WebsiteDataStore&);
+ RefPtr<WebProcessProxy> tryTakePrewarmedProcess(WebsiteDataStore&, WebProcessProxy::CaptivePortalMode);
void initializeNewWebProcess(WebProcessProxy&, WebsiteDataStore*, WebProcessProxy::IsPrewarmed = WebProcessProxy::IsPrewarmed::No);
Modified: trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp (285593 => 285594)
--- trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp 2021-11-10 19:04:38 UTC (rev 285593)
+++ trunk/Source/WebKit/UIProcess/WebProcessProxy.cpp 2021-11-10 19:14:25 UTC (rev 285594)
@@ -164,9 +164,9 @@
}
}
-Ref<WebProcessProxy> WebProcessProxy::create(WebProcessPool& processPool, WebsiteDataStore* websiteDataStore, IsPrewarmed isPrewarmed, CrossOriginMode crossOriginMode, ShouldLaunchProcess shouldLaunchProcess)
+Ref<WebProcessProxy> WebProcessProxy::create(WebProcessPool& processPool, WebsiteDataStore* websiteDataStore, CaptivePortalMode captivePortalMode, IsPrewarmed isPrewarmed, CrossOriginMode crossOriginMode, ShouldLaunchProcess shouldLaunchProcess)
{
- auto proxy = adoptRef(*new WebProcessProxy(processPool, websiteDataStore, isPrewarmed, crossOriginMode));
+ auto proxy = adoptRef(*new WebProcessProxy(processPool, websiteDataStore, isPrewarmed, crossOriginMode, captivePortalMode));
if (shouldLaunchProcess == ShouldLaunchProcess::Yes) {
if (liveProcessesLRU().size() >= s_maxProcessCount) {
for (auto& processPool : WebProcessPool::allProcessPools())
@@ -184,7 +184,7 @@
#if ENABLE(SERVICE_WORKER)
Ref<WebProcessProxy> WebProcessProxy::createForServiceWorkers(WebProcessPool& processPool, RegistrableDomain&& registrableDomain, WebsiteDataStore& websiteDataStore)
{
- auto proxy = adoptRef(*new WebProcessProxy(processPool, &websiteDataStore, IsPrewarmed::No, CrossOriginMode::Shared));
+ auto proxy = adoptRef(*new WebProcessProxy(processPool, &websiteDataStore, IsPrewarmed::No, CrossOriginMode::Shared, CaptivePortalMode::Disabled));
proxy->m_registrableDomain = WTFMove(registrableDomain);
proxy->enableServiceWorkers(processPool.userContentControllerIdentifierForServiceWorkers());
proxy->connect();
@@ -220,7 +220,7 @@
};
#endif
-WebProcessProxy::WebProcessProxy(WebProcessPool& processPool, WebsiteDataStore* websiteDataStore, IsPrewarmed isPrewarmed, CrossOriginMode crossOriginMode)
+WebProcessProxy::WebProcessProxy(WebProcessPool& processPool, WebsiteDataStore* websiteDataStore, IsPrewarmed isPrewarmed, CrossOriginMode crossOriginMode, CaptivePortalMode captivePortalMode)
: AuxiliaryProcessProxy(processPool.alwaysRunsAtBackgroundPriority())
, m_backgroundResponsivenessTimer(*this)
, m_processPool(processPool, isPrewarmed == IsPrewarmed::Yes ? IsWeak::Yes : IsWeak::No)
@@ -237,6 +237,7 @@
, m_userMediaCaptureManagerProxy(makeUnique<UserMediaCaptureManagerProxy>(makeUniqueRef<UIProxyForCapture>(*this)))
#endif
, m_isPrewarmed(isPrewarmed == IsPrewarmed::Yes)
+ , m_captivePortalMode(captivePortalMode)
, m_crossOriginMode(crossOriginMode)
, m_shutdownPreventingScopeCounter([this](RefCounterEvent event) { if (event == RefCounterEvent::Decrement) maybeShutDown(); })
{
Modified: trunk/Source/WebKit/UIProcess/WebProcessProxy.h (285593 => 285594)
--- trunk/Source/WebKit/UIProcess/WebProcessProxy.h 2021-11-10 19:04:38 UTC (rev 285593)
+++ trunk/Source/WebKit/UIProcess/WebProcessProxy.h 2021-11-10 19:14:25 UTC (rev 285594)
@@ -134,8 +134,9 @@
};
enum class ShouldLaunchProcess : bool { No, Yes };
+ enum class CaptivePortalMode : bool { Disabled, Enabled };
- static Ref<WebProcessProxy> create(WebProcessPool&, WebsiteDataStore*, IsPrewarmed, WebCore::CrossOriginMode = WebCore::CrossOriginMode::Shared, ShouldLaunchProcess = ShouldLaunchProcess::Yes);
+ static Ref<WebProcessProxy> create(WebProcessPool&, WebsiteDataStore*, CaptivePortalMode, IsPrewarmed, WebCore::CrossOriginMode = WebCore::CrossOriginMode::Shared, ShouldLaunchProcess = ShouldLaunchProcess::Yes);
static Ref<WebProcessProxy> createForServiceWorkers(WebProcessPool&, WebCore::RegistrableDomain&&, WebsiteDataStore&);
~WebProcessProxy();
@@ -427,9 +428,10 @@
#endif
WebCore::CrossOriginMode crossOriginMode() const { return m_crossOriginMode; }
+ CaptivePortalMode captivePortalMode() const { return m_captivePortalMode; }
protected:
- WebProcessProxy(WebProcessPool&, WebsiteDataStore*, IsPrewarmed, WebCore::CrossOriginMode);
+ WebProcessProxy(WebProcessPool&, WebsiteDataStore*, IsPrewarmed, WebCore::CrossOriginMode, CaptivePortalMode);
// AuxiliaryProcessProxy
ASCIILiteral processName() const final { return "WebContent"_s; }
@@ -440,16 +442,16 @@
void processWillShutDown(IPC::Connection&) override;
bool shouldSendPendingMessage(const PendingMessage&) final;
- // ProcessLauncher::Client
- void didFinishLaunching(ProcessLauncher*, IPC::Connection::Identifier) override;
-
#if PLATFORM(COCOA)
void cacheMediaMIMETypesInternal(const Vector<String>&);
#endif
+ // ProcessLauncher::Client
+ void didFinishLaunching(ProcessLauncher*, IPC::Connection::Identifier) override;
bool shouldConfigureJSCForTesting() const final;
bool isJITEnabled() const final;
bool shouldEnableSharedArrayBuffer() const final { return m_crossOriginMode == WebCore::CrossOriginMode::Isolated; }
+ bool shouldEnableCaptivePortalMode() const final { return m_captivePortalMode == CaptivePortalMode::Enabled; }
void validateFreezerStatus();
@@ -622,6 +624,7 @@
bool m_hasCommittedAnyProvisionalLoads { false };
bool m_isPrewarmed;
+ CaptivePortalMode m_captivePortalMode { CaptivePortalMode::Disabled };
WebCore::CrossOriginMode m_crossOriginMode { WebCore::CrossOriginMode::Shared };
#if ENABLE(ATTACHMENT_ELEMENT)
bool m_hasIssuedAttachmentElementRelatedSandboxExtensions { false };
Modified: trunk/Tools/ChangeLog (285593 => 285594)
--- trunk/Tools/ChangeLog 2021-11-10 19:04:38 UTC (rev 285593)
+++ trunk/Tools/ChangeLog 2021-11-10 19:14:25 UTC (rev 285594)
@@ -1,3 +1,15 @@
+2021-11-10 Chris Dumez <[email protected]>
+
+ Add basic support for launching CaptivePortalMode WebProcesses
+ https://bugs.webkit.org/show_bug.cgi?id=232737
+ <rdar://84473037>
+
+ Reviewed by Brent Fulgham.
+
+ Add API test coverage.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
+
2021-11-10 Tyler Wilcock <[email protected]>
AX: Make ancestor computation cheaper by setting flags upon child insertion
Modified: trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI-iOS.entitlements (285593 => 285594)
--- trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI-iOS.entitlements 2021-11-10 19:04:38 UTC (rev 285593)
+++ trunk/Tools/TestWebKitAPI/Configurations/TestWebKitAPI-iOS.entitlements 2021-11-10 19:14:25 UTC (rev 285594)
@@ -10,5 +10,7 @@
<true/>
<key>com.apple.Pasteboard.paste-unchecked</key>
<true/>
+ <key>com.apple.developer.web-browser</key>
+ <true/>
</dict>
</plist>
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm (285593 => 285594)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm 2021-11-10 19:04:38 UTC (rev 285593)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm 2021-11-10 19:14:25 UTC (rev 285594)
@@ -7624,3 +7624,123 @@
{
runCOOPProcessSwapTest("same-origin-allow-popup", "unsafe-none", "unsafe-none", "unsafe-none", IsSameOrigin::No, DoServerSideRedirect::No, ExpectSwap::No);
}
+
+static bool isJITEnabled(WKWebView *webView)
+{
+ __block bool gotResponse = false;
+ __block bool isJITEnabledResult = false;
+ [webView _isJITEnabled:^(BOOL isJITEnabled) {
+ isJITEnabledResult = isJITEnabled;
+ gotResponse = true;
+ }];
+ TestWebKitAPI::Util::run(&gotResponse);
+ EXPECT_NE([webView _webProcessIdentifier], 0);
+ return isJITEnabledResult;
+}
+
+TEST(ProcessSwap, NavigatingToCaptivePortalMode)
+{
+ auto webView = adoptNS([WKWebView new]);
+ 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()));
+
+ delegate.get().decidePolicyForNavigationActionWithPreferences = ^(WKNavigationAction *action, WKWebpagePreferences *preferences, void (^completionHandler)(WKNavigationActionPolicy, WKWebpagePreferences *)) {
+ EXPECT_FALSE(preferences.captivePortalModeEnabled);
+ preferences.captivePortalModeEnabled = YES;
+ completionHandler(WKNavigationActionPolicyAllow, preferences);
+ };
+
+ finishedNavigation = false;
+ url = "" mainBundle] URLForResource:@"simple2" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
+ [webView loadRequest:[NSURLRequest requestWithURL:url]];
+ TestWebKitAPI::Util::run(&finishedNavigation);
+
+ // We should have process-swap for transitioning to captive portal mode.
+ EXPECT_NE(pid1, [webView _webProcessIdentifier]);
+ EXPECT_FALSE(isJITEnabled(webView.get()));
+}
+
+TEST(ProcessSwap, CaptivePortalModeEnabledByDefaultThenOptOut)
+{
+ auto webViewConfiguration = adoptNS([WKWebViewConfiguration new]);
+ EXPECT_FALSE(webViewConfiguration.get().defaultWebpagePreferences.captivePortalModeEnabled);
+ webViewConfiguration.get().defaultWebpagePreferences.captivePortalModeEnabled = YES;
+
+ 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()));
+ pid_t pid1 = [webView _webProcessIdentifier];
+
+ __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);
+ completionHandler(WKNavigationActionPolicyAllow, preferences);
+ };
+
+ NSURL *url = "" mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
+ [webView loadRequest:[NSURLRequest requestWithURL:url]];
+ TestWebKitAPI::Util::run(&finishedNavigation);
+
+ EXPECT_FALSE(isJITEnabled(webView.get()));
+ EXPECT_EQ(pid1, [webView _webProcessIdentifier]);
+
+ finishedNavigation = false;
+ url = "" mainBundle] URLForResource:@"simple2" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
+ [webView loadRequest:[NSURLRequest requestWithURL:url]];
+ TestWebKitAPI::Util::run(&finishedNavigation);
+
+ EXPECT_EQ(pid1, [webView _webProcessIdentifier]); // Shouldn't have process-swapped since we're staying in captive portal mode.
+ EXPECT_FALSE(isJITEnabled(webView.get()));
+
+ delegate.get().decidePolicyForNavigationActionWithPreferences = ^(WKNavigationAction *action, WKWebpagePreferences *preferences, void (^completionHandler)(WKNavigationActionPolicy, WKWebpagePreferences *)) {
+ EXPECT_TRUE(preferences.captivePortalModeEnabled);
+ preferences.captivePortalModeEnabled = NO; // Opt out of captive portal mode for this load.
+ completionHandler(WKNavigationActionPolicyAllow, preferences);
+ };
+
+ finishedNavigation = false;
+ url = "" mainBundle] URLForResource:@"simple3" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
+ [webView loadRequest:[NSURLRequest requestWithURL:url]];
+ TestWebKitAPI::Util::run(&finishedNavigation);
+
+ // We should have process-swapped to get out of captive portal mode.
+ EXPECT_NE(pid1, [webView _webProcessIdentifier]);
+ EXPECT_TRUE(isJITEnabled(webView.get()));
+
+ // captive portal mode should be disabled in new WebViews since it is not enabled globally.
+ auto webView2 = adoptNS([WKWebView new]);
+ [webView2 setNavigationDelegate:delegate.get()];
+ EXPECT_TRUE(isJITEnabled(webView2.get()));
+ pid_t pid2 = [webView2 _webProcessIdentifier];
+
+ delegate.get().decidePolicyForNavigationActionWithPreferences = nil;
+
+ finishedNavigation = false;
+ url = "" mainBundle] URLForResource:@"simple" withExtension:@"html" subdirectory:@"TestWebKitAPI.resources"];
+ [webView2 loadRequest:[NSURLRequest requestWithURL:url]];
+ TestWebKitAPI::Util::run(&finishedNavigation);
+ EXPECT_TRUE(isJITEnabled(webView2.get()));
+ EXPECT_EQ(pid2, [webView2 _webProcessIdentifier]);
+}