Changeset 291606 in webkit


Ignore:
Timestamp:
Mar 22, 2022 12:44:10 AM (4 months ago)
Author:
youenn@apple.com
Message:

Website policies are not respected when doing COOP based process swap
https://bugs.webkit.org/show_bug.cgi?id=238036
<rdar://89616625>

Reviewed by Chris Dumez.

Source/WebKit:

In case of normal process swap, we make use of website policies so everything is fine.
For COOP based process swap, this happens later on, at a point where we lost website policies.
To overcome this, we store the website policies used by a navigation inside the API::Navigation object.
It is used by continueNavigationInNewProcess to correctly initialize the new WebPage website policies.
We then set the website policies in the navigation object just before continuing the load in the same process,
as process swap may happen later when inspecting the response.
Minor refactoring in continueNavigationInNewProcess to get the policies directly from the given Navigation object.
Minor refactoring in receivedNavigationPolicyDecision to make the code doing process swap clearer.

Covered by API test.

  • UIProcess/API/APINavigation.h:

(API::Navigation::setWebsitePoliciesForProcessSwap):
(API::Navigation::takeWebsitePoliciesForProcessSwap):

  • UIProcess/WebPageProxy.cpp:

(WebKit::WebPageProxy::receivedNavigationPolicyDecision):
(WebKit::WebPageProxy::receivedPolicyDecision):
(WebKit::WebPageProxy::continueNavigationInNewProcess):
(WebKit::WebPageProxy::triggerBrowsingContextGroupSwitchForNavigation):

  • UIProcess/WebPageProxy.h:

Tools:

  • TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
Location:
trunk
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r291604 r291606  
     12022-03-22  Youenn Fablet  <youenn@apple.com>
     2
     3        Website policies are not respected when doing COOP based process swap
     4        https://bugs.webkit.org/show_bug.cgi?id=238036
     5        <rdar://89616625>
     6
     7        Reviewed by Chris Dumez.
     8
     9        In case of normal process swap, we make use of website policies so everything is fine.
     10        For COOP based process swap, this happens later on, at a point where we lost website policies.
     11        To overcome this, we store the website policies used by a navigation inside the API::Navigation object.
     12        It is used by continueNavigationInNewProcess to correctly initialize the new WebPage website policies.
     13        We then set the website policies in the navigation object just before continuing the load in the same process,
     14        as process swap may happen later when inspecting the response.
     15        Minor refactoring in continueNavigationInNewProcess to get the policies directly from the given Navigation object.
     16        Minor refactoring in receivedNavigationPolicyDecision to make the code doing process swap clearer.
     17
     18        Covered by API test.
     19
     20        * UIProcess/API/APINavigation.h:
     21        (API::Navigation::setWebsitePoliciesForProcessSwap):
     22        (API::Navigation::takeWebsitePoliciesForProcessSwap):
     23        * UIProcess/WebPageProxy.cpp:
     24        (WebKit::WebPageProxy::receivedNavigationPolicyDecision):
     25        (WebKit::WebPageProxy::receivedPolicyDecision):
     26        (WebKit::WebPageProxy::continueNavigationInNewProcess):
     27        (WebKit::WebPageProxy::triggerBrowsingContextGroupSwitchForNavigation):
     28        * UIProcess/WebPageProxy.h:
     29
    1302022-03-21  Said Abou-Hallawa  <said@apple.com>
    231
  • trunk/Source/WebKit/UIProcess/API/APINavigation.h

    r284610 r291606  
    2727
    2828#include "APIObject.h"
     29#include "APIWebsitePolicies.h"
    2930#include "DataReference.h"
    3031#include "FrameInfoData.h"
     
    172173    bool isLoadedWithNavigationShared() const { return m_isLoadedWithNavigationShared; }
    173174
     175    void setWebsitePolicies(RefPtr<API::WebsitePolicies>&& policies) { m_websitePolicies = WTFMove(policies); }
     176    API::WebsitePolicies* websitePolicies() { return m_websitePolicies.get(); }
     177
    174178private:
    175179    explicit Navigation(WebKit::WebNavigationState&);
     
    198202    WebKit::ProcessThrottler::TimedActivity m_clientNavigationActivity;
    199203    bool m_isLoadedWithNavigationShared { false };
     204    RefPtr<API::WebsitePolicies> m_websitePolicies;
    200205};
    201206
  • trunk/Source/WebKit/UIProcess/WebPageProxy.cpp

    r291491 r291606  
    34233423}
    34243424
    3425 void WebPageProxy::receivedNavigationPolicyDecision(PolicyAction policyAction, API::Navigation* navigation, Ref<API::NavigationAction>&& navigationAction, ProcessSwapRequestedByClient processSwapRequestedByClient, WebFrameProxy& frame, const FrameInfoData& frameInfo, RefPtr<API::WebsitePolicies>&& policies, Ref<PolicyDecisionSender>&& sender)
     3425void WebPageProxy::receivedNavigationPolicyDecision(PolicyAction policyAction, API::Navigation* navigation, Ref<API::NavigationAction>&& navigationAction, ProcessSwapRequestedByClient processSwapRequestedByClient, WebFrameProxy& frame, const FrameInfoData& frameInfo, Ref<PolicyDecisionSender>&& sender)
    34263426{
    34273427    WEBPAGEPROXY_RELEASE_LOG(Loading, "receivedNavigationPolicyDecision: frameID=%llu, isMainFrame=%d, navigationID=%llu, policyAction=%u", frame.frameID().toUInt64(), frame.isMainFrame(), navigation ? navigation->navigationID() : 0, (unsigned)policyAction);
    34283428
    34293429    Ref<WebsiteDataStore> websiteDataStore = m_websiteDataStore.copyRef();
    3430     if (policies) {
     3430    if (auto* policies = navigation->websitePolicies()) {
    34313431        if (policies->websiteDataStore() && policies->websiteDataStore() != websiteDataStore.ptr()) {
    34323432            websiteDataStore = *policies->websiteDataStore();
     
    34383438
    34393439    if (navigation && !navigation->userContentExtensionsEnabled()) {
    3440         if (!policies)
    3441             policies = API::WebsitePolicies::create();
    3442         policies->setContentBlockersEnabled(false);
     3440        if (!navigation->websitePolicies())
     3441            navigation->setWebsitePolicies(API::WebsitePolicies::create());
     3442        navigation->websitePolicies()->setContentBlockersEnabled(false);
    34433443    }
    34443444
    34453445#if ENABLE(DEVICE_ORIENTATION)
    3446     if (navigation && (!policies || policies->deviceOrientationAndMotionAccessState() == WebCore::DeviceOrientationOrMotionPermissionState::Prompt)) {
     3446    if (navigation && (!navigation->websitePolicies() || navigation->websitePolicies()->deviceOrientationAndMotionAccessState() == WebCore::DeviceOrientationOrMotionPermissionState::Prompt)) {
    34473447        auto deviceOrientationPermission = websiteDataStore->deviceOrientationAndMotionAccessController().cachedDeviceOrientationPermission(SecurityOriginData::fromURL(navigation->currentRequest().url()));
    34483448        if (deviceOrientationPermission != WebCore::DeviceOrientationOrMotionPermissionState::Prompt) {
    3449             if (!policies)
    3450                 policies = API::WebsitePolicies::create();
    3451             policies->setDeviceOrientationAndMotionAccessState(deviceOrientationPermission);
     3449            if (!navigation->websitePolicies())
     3450                navigation->setWebsitePolicies(API::WebsitePolicies::create());
     3451            navigation->websitePolicies()->setDeviceOrientationAndMotionAccessState(deviceOrientationPermission);
    34523452        }
    34533453    }
     
    34633463
    34643464    if (policyAction != PolicyAction::Use || !frame.isMainFrame() || !navigation) {
    3465         receivedPolicyDecision(policyAction, navigation, WTFMove(policies), WTFMove(navigationAction), WTFMove(sender));
     3465        receivedPolicyDecision(policyAction, navigation, navigation->websitePolicies(), WTFMove(navigationAction), WTFMove(sender));
    34663466        return;
    34673467    }
     
    34763476    }
    34773477
    3478     m_isCaptivePortalModeExplicitlySet = (policies && policies->isCaptivePortalModeExplicitlySet()) || m_configuration->isCaptivePortalModeExplicitlySet();
    3479     auto captivePortalMode = (policies ? policies->captivePortalModeEnabled() : shouldEnableCaptivePortalMode()) ? WebProcessProxy::CaptivePortalMode::Enabled : WebProcessProxy::CaptivePortalMode::Disabled;
    3480     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(),
    3481         policies = WTFMove(policies), sender = WTFMove(sender), processSwapRequestedByClient] (Ref<WebProcessProxy>&& processForNavigation, SuspendedPageProxy* destinationSuspendedPage, const String& reason) mutable {
     3478    m_isCaptivePortalModeExplicitlySet = (navigation->websitePolicies() && navigation->websitePolicies()->isCaptivePortalModeExplicitlySet()) || m_configuration->isCaptivePortalModeExplicitlySet();
     3479    auto captivePortalMode = (navigation->websitePolicies() ? navigation->websitePolicies()->captivePortalModeEnabled() : shouldEnableCaptivePortalMode()) ? WebProcessProxy::CaptivePortalMode::Enabled : WebProcessProxy::CaptivePortalMode::Disabled;
     3480    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(), sender = WTFMove(sender), processSwapRequestedByClient] (Ref<WebProcessProxy>&& processForNavigation, SuspendedPageProxy* destinationSuspendedPage, const String& reason) mutable {
    34823481        // If the navigation has been destroyed, then no need to proceed.
    34833482        if (isClosed() || !navigationState().hasNavigation(navigation->navigationID())) {
    3484             receivedPolicyDecision(policyAction, navigation.ptr(), WTFMove(policies), WTFMove(navigationAction), WTFMove(sender));
     3483            receivedPolicyDecision(policyAction, navigation.ptr(), navigation->websitePolicies(), WTFMove(navigationAction), WTFMove(sender));
    34853484            return;
    34863485        }
     
    34943493            WEBPAGEPROXY_RELEASE_LOG(ProcessSwapping, "decidePolicyForNavigationAction: keep using process %i for navigation, reason=%" PUBLIC_LOG_STRING, processIdentifier(), reason.utf8().data());
    34953494
    3496         std::optional<SandboxExtension::Handle> optionalHandle;
    34973495        if (shouldProcessSwap) {
    34983496            // Make sure the process to be used for the navigation does not get shutDown now due to destroying SuspendedPageProxy or ProvisionalPageProxy objects.
     
    35123510                suspendedPage = nullptr;
    35133511
    3514             continueNavigationInNewProcess(navigation, WTFMove(suspendedPage), WTFMove(processForNavigation), processSwapRequestedByClient, ShouldTreatAsContinuingLoad::YesAfterNavigationPolicyDecision, std::exchange(policies, nullptr));
    3515         } else {
    3516             auto item = navigation->reloadItem() ? navigation->reloadItem() : navigation->targetItem();
    3517             if (policyAction == PolicyAction::Use && item) {
    3518                 URL fullURL { item->url() };
    3519                 if (fullURL.protocolIs("file"_s)) {
    3520                     SandboxExtension::Handle sandboxExtensionHandle;
    3521                     maybeInitializeSandboxExtensionHandle(processForNavigation.get(), fullURL, item->resourceDirectoryURL(), sandboxExtensionHandle);
    3522                     optionalHandle = WTFMove(sandboxExtensionHandle);
    3523                 }
     3512            continueNavigationInNewProcess(navigation, WTFMove(suspendedPage), WTFMove(processForNavigation), processSwapRequestedByClient, ShouldTreatAsContinuingLoad::YesAfterNavigationPolicyDecision);
     3513
     3514            receivedPolicyDecision(policyAction, navigation.ptr(), nullptr, WTFMove(navigationAction), WTFMove(sender), WillContinueLoadInNewProcess::Yes);
     3515            return;
     3516        }
     3517
     3518        auto item = navigation->reloadItem() ? navigation->reloadItem() : navigation->targetItem();
     3519        std::optional<SandboxExtension::Handle> optionalHandle;
     3520        if (policyAction == PolicyAction::Use && item) {
     3521            URL fullURL { item->url() };
     3522            if (fullURL.protocolIs("file"_s)) {
     3523                SandboxExtension::Handle sandboxExtensionHandle;
     3524                maybeInitializeSandboxExtensionHandle(processForNavigation.get(), fullURL, item->resourceDirectoryURL(), sandboxExtensionHandle);
     3525                optionalHandle = WTFMove(sandboxExtensionHandle);
    35243526            }
    35253527        }
    35263528
    3527         receivedPolicyDecision(policyAction, navigation.ptr(), shouldProcessSwap ? nullptr : WTFMove(policies), WTFMove(navigationAction), WTFMove(sender), WTFMove(optionalHandle), shouldProcessSwap ? WillContinueLoadInNewProcess::Yes : WillContinueLoadInNewProcess::No);
     3529        receivedPolicyDecision(policyAction, navigation.ptr(), navigation->websitePolicies(), WTFMove(navigationAction), WTFMove(sender), WillContinueLoadInNewProcess::No, WTFMove(optionalHandle));
    35283530    });
    35293531}
    35303532
    3531 void WebPageProxy::receivedPolicyDecision(PolicyAction action, API::Navigation* navigation, RefPtr<API::WebsitePolicies>&& websitePolicies, std::variant<Ref<API::NavigationResponse>, Ref<API::NavigationAction>>&& navigationActionOrResponse, Ref<PolicyDecisionSender>&& sender, std::optional<SandboxExtension::Handle> sandboxExtensionHandle, WillContinueLoadInNewProcess willContinueLoadInNewProcess)
     3533void WebPageProxy::receivedPolicyDecision(PolicyAction action, API::Navigation* navigation, RefPtr<API::WebsitePolicies>&& websitePolicies, std::variant<Ref<API::NavigationResponse>, Ref<API::NavigationAction>>&& navigationActionOrResponse, Ref<PolicyDecisionSender>&& sender, WillContinueLoadInNewProcess willContinueLoadInNewProcess, std::optional<SandboxExtension::Handle> sandboxExtensionHandle)
    35323534{
    35333535    if (!hasRunningProcess()) {
     
    36193621}
    36203622
    3621 void WebPageProxy::continueNavigationInNewProcess(API::Navigation& navigation, std::unique_ptr<SuspendedPageProxy>&& suspendedPage, Ref<WebProcessProxy>&& newProcess, ProcessSwapRequestedByClient processSwapRequestedByClient, ShouldTreatAsContinuingLoad shouldTreatAsContinuingLoad, RefPtr<API::WebsitePolicies>&& websitePolicies, std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume)
     3623void WebPageProxy::continueNavigationInNewProcess(API::Navigation& navigation, std::unique_ptr<SuspendedPageProxy>&& suspendedPage, Ref<WebProcessProxy>&& newProcess, ProcessSwapRequestedByClient processSwapRequestedByClient, ShouldTreatAsContinuingLoad shouldTreatAsContinuingLoad, std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume)
    36223624{
    36233625    WEBPAGEPROXY_RELEASE_LOG(Loading, "continueNavigationInNewProcess: newProcessPID=%i, hasSuspendedPage=%i", newProcess->processIdentifier(), !!suspendedPage);
     
    36333635    }
    36343636
     3637    RefPtr websitePolicies = navigation.websitePolicies();
    36353638    bool isServerSideRedirect = shouldTreatAsContinuingLoad == ShouldTreatAsContinuingLoad::YesAfterNavigationPolicyDecision && navigation.currentRequestIsRedirect();
    36363639    bool isProcessSwappingOnNavigationResponse = shouldTreatAsContinuingLoad == ShouldTreatAsContinuingLoad::YesAfterProvisionalLoadStarted;
     
    54945497        WEBPAGEPROXY_RELEASE_LOG(Loading, "decidePolicyForNavigationAction: listener called: frameID=%llu, isMainFrame=%d, navigationID=%llu, policyAction=%u, safeBrowsingWarning=%d, isAppBoundDomain=%d", frame->frameID().toUInt64(), frame->isMainFrame(), navigation ? navigation->navigationID() : 0, (unsigned)policyAction, !!safeBrowsingWarning, !!isAppBoundDomain);
    54955498
    5496         auto completionHandler = [this, protectedThis, frame, frameInfo, sender = WTFMove(sender), navigation, navigationAction = WTFMove(navigationAction), processSwapRequestedByClient, policies = RefPtr { policies }] (PolicyAction policyAction) mutable {
     5499        navigation->setWebsitePolicies(WTFMove(policies));
     5500        auto completionHandler = [this, protectedThis, frame, frameInfo, sender = WTFMove(sender), navigation, navigationAction = WTFMove(navigationAction), processSwapRequestedByClient] (PolicyAction policyAction) mutable {
    54975501            if (frame->isMainFrame()) {
    5498                 if (!policies) {
     5502                if (!navigation->websitePolicies()) {
    54995503                    if (auto* defaultPolicies = m_configuration->defaultWebsitePolicies())
    5500                         policies = defaultPolicies->copy();
     5504                        navigation->setWebsitePolicies(defaultPolicies->copy());
    55015505                }
    5502                 if (policies)
     5506                if (auto* policies = navigation->websitePolicies())
    55035507                    navigation->setEffectiveContentMode(effectiveContentModeAfterAdjustingPolicies(*policies, navigation->currentRequest()));
    55045508            }
    5505             receivedNavigationPolicyDecision(policyAction, navigation.get(), WTFMove(navigationAction), processSwapRequestedByClient, frame, frameInfo, WTFMove(policies), WTFMove(sender));
     5509            receivedNavigationPolicyDecision(policyAction, navigation.get(), WTFMove(navigationAction), processSwapRequestedByClient, frame, frameInfo, WTFMove(sender));
    55065510        };
    55075511
     
    57665770    if (!m_provisionalPage)
    57675771        send(Messages::WebPage::StopLoadingDueToProcessSwap());
    5768     continueNavigationInNewProcess(*navigation, nullptr, processForNavigation.releaseNonNull(), ProcessSwapRequestedByClient::No, ShouldTreatAsContinuingLoad::YesAfterProvisionalLoadStarted, nullptr, existingNetworkResourceLoadIdentifierToResume);
     5772    continueNavigationInNewProcess(*navigation, nullptr, processForNavigation.releaseNonNull(), ProcessSwapRequestedByClient::No, ShouldTreatAsContinuingLoad::YesAfterProvisionalLoadStarted, existingNetworkResourceLoadIdentifierToResume);
    57695773    completionHandler(true);
    57705774}
  • trunk/Source/WebKit/UIProcess/WebPageProxy.h

    r291393 r291606  
    12711271    class PolicyDecisionSender;
    12721272    enum class WillContinueLoadInNewProcess : bool { No, Yes };
    1273     void receivedPolicyDecision(WebCore::PolicyAction, API::Navigation*, RefPtr<API::WebsitePolicies>&&, std::variant<Ref<API::NavigationResponse>, Ref<API::NavigationAction>>&&, Ref<PolicyDecisionSender>&&, std::optional<SandboxExtension::Handle> = { }, WillContinueLoadInNewProcess = WillContinueLoadInNewProcess::No);
    1274     void receivedNavigationPolicyDecision(WebCore::PolicyAction, API::Navigation*, Ref<API::NavigationAction>&&, ProcessSwapRequestedByClient, WebFrameProxy&, const FrameInfoData&, RefPtr<API::WebsitePolicies>&&, Ref<PolicyDecisionSender>&&);
     1273    void receivedPolicyDecision(WebCore::PolicyAction, API::Navigation*, RefPtr<API::WebsitePolicies>&&, std::variant<Ref<API::NavigationResponse>, Ref<API::NavigationAction>>&&, Ref<PolicyDecisionSender>&&, WillContinueLoadInNewProcess = WillContinueLoadInNewProcess::No, std::optional<SandboxExtension::Handle> = { });
     1274    void receivedNavigationPolicyDecision(WebCore::PolicyAction, API::Navigation*, Ref<API::NavigationAction>&&, ProcessSwapRequestedByClient, WebFrameProxy&, const FrameInfoData&, Ref<PolicyDecisionSender>&&);
    12751275
    12761276    void backForwardRemovedItem(const WebCore::BackForwardItemIdentifier&);
     
    25552555    void reportPageLoadResult(const WebCore::ResourceError& = { });
    25562556
    2557     void continueNavigationInNewProcess(API::Navigation&, std::unique_ptr<SuspendedPageProxy>&&, Ref<WebProcessProxy>&&, ProcessSwapRequestedByClient, WebCore::ShouldTreatAsContinuingLoad, RefPtr<API::WebsitePolicies>&&, std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume = std::nullopt);
     2557    void continueNavigationInNewProcess(API::Navigation&, std::unique_ptr<SuspendedPageProxy>&&, Ref<WebProcessProxy>&&, ProcessSwapRequestedByClient, WebCore::ShouldTreatAsContinuingLoad, std::optional<NetworkResourceLoadIdentifier> existingNetworkResourceLoadIdentifierToResume = std::nullopt);
    25582558
    25592559    void setNeedsFontAttributes(bool);
  • trunk/Tools/ChangeLog

    r291604 r291606  
     12022-03-22  Youenn Fablet  <youenn@apple.com>
     2
     3        Website policies are not respected when doing COOP based process swap
     4        https://bugs.webkit.org/show_bug.cgi?id=238036
     5        <rdar://89616625>
     6
     7        Reviewed by Chris Dumez.
     8
     9        * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
     10
    1112022-03-21  Said Abou-Hallawa  <said@apple.com>
    212
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm

    r291579 r291606  
    83098309
    83108310#endif
     8311
     8312#if PLATFORM(IOS_FAMILY)
     8313TEST(ProcessSwap, ContentModeInCaseOfCoopProcessSwap)
     8314{
     8315    using namespace TestWebKitAPI;
     8316
     8317    HTTPServer server({
     8318        { "/source.html", { "foo" } },
     8319        { "/destination.html", { { { "Content-Type", "text/html" }, { "Cross-Origin-Opener-Policy", "same-origin" } }, "bar" } },
     8320    }, HTTPServer::Protocol::Https);
     8321
     8322    auto processPoolConfiguration = psonProcessPoolConfiguration();
     8323    auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
     8324
     8325    auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
     8326    [webViewConfiguration setProcessPool:processPool.get()];
     8327
     8328    auto webpagePreferences = adoptNS([[WKWebpagePreferences alloc] init]);
     8329    [webpagePreferences setPreferredContentMode:WKContentModeDesktop];
     8330    [webViewConfiguration setDefaultWebpagePreferences:webpagePreferences.get()];
     8331
     8332    auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 1024, 768) configuration:webViewConfiguration.get()]);
     8333    auto navigationDelegate = adoptNS([[PSONNavigationDelegate alloc] init]);
     8334    [webView setNavigationDelegate:navigationDelegate.get()];
     8335
     8336    done = false;
     8337    [webView loadRequest:server.request("/source.html")];
     8338    Util::run(&done);
     8339    done = false;
     8340
     8341    [webView evaluateJavaScript:@"navigator.userAgent;" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
     8342        done = true;
     8343
     8344        ASSERT_TRUE(!error);
     8345        NSString *userAgent = (NSString *)response;
     8346        ASSERT_TRUE([userAgent containsString:@"Macintosh; Intel Mac"]);
     8347    }];
     8348    Util::run(&done);
     8349    done = false;
     8350
     8351    auto pid1 = [webView _webProcessIdentifier];
     8352
     8353    [webView loadRequest:server.request("/destination.html")];
     8354    Util::run(&done);
     8355    done = false;
     8356
     8357    [webView evaluateJavaScript:@"navigator.userAgent;" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
     8358        done = true;
     8359
     8360        ASSERT_TRUE(!error);
     8361        NSString *userAgent = (NSString *)response;
     8362        ASSERT_TRUE([userAgent containsString:@"Macintosh; Intel Mac"]);
     8363    }];
     8364    Util::run(&done);
     8365    done = false;
     8366
     8367    auto pid2 = [webView _webProcessIdentifier];
     8368    EXPECT_NE(pid1, pid2);
     8369
     8370    [webView goBack]; // Back to source.html.
     8371    Util::run(&done);
     8372    done = false;
     8373
     8374    [webView evaluateJavaScript:@"navigator.userAgent;" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
     8375        done = true;
     8376
     8377        ASSERT_TRUE(!error);
     8378        NSString *userAgent = (NSString *)response;
     8379        ASSERT_TRUE([userAgent containsString:@"Macintosh; Intel Mac"]);
     8380    }];
     8381    Util::run(&done);
     8382    done = false;
     8383}
     8384
     8385TEST(ProcessSwap, ContentModeInCaseOfPSONThenCoopProcessSwap)
     8386{
     8387    using namespace TestWebKitAPI;
     8388
     8389    HTTPServer server1({
     8390        { "/source.html", { "foo" } },
     8391    }, HTTPServer::Protocol::Https);
     8392
     8393    HTTPServer server2({
     8394        { "/destination.html", { { { "Content-Type", "text/html" }, { "Cross-Origin-Opener-Policy", "same-origin" } }, "bar" } },
     8395    }, HTTPServer::Protocol::Http);
     8396
     8397    auto processPoolConfiguration = psonProcessPoolConfiguration();
     8398    auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
     8399
     8400    auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
     8401    [webViewConfiguration setProcessPool:processPool.get()];
     8402
     8403    auto webpagePreferences = adoptNS([[WKWebpagePreferences alloc] init]);
     8404    [webpagePreferences setPreferredContentMode:WKContentModeDesktop];
     8405    [webViewConfiguration setDefaultWebpagePreferences:webpagePreferences.get()];
     8406
     8407    auto webView = adoptNS([[WKWebView alloc] initWithFrame:CGRectMake(0, 0, 1024, 768) configuration:webViewConfiguration.get()]);
     8408    auto navigationDelegate = adoptNS([[PSONNavigationDelegate alloc] init]);
     8409    [webView setNavigationDelegate:navigationDelegate.get()];
     8410
     8411    done = false;
     8412    [webView loadRequest:server1.request("/source.html")];
     8413    Util::run(&done);
     8414    done = false;
     8415
     8416    [webView evaluateJavaScript:@"navigator.userAgent;" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
     8417        done = true;
     8418
     8419        ASSERT_TRUE(!error);
     8420        NSString *userAgent = (NSString *)response;
     8421        ASSERT_TRUE([userAgent containsString:@"Macintosh; Intel Mac"]);
     8422    }];
     8423    Util::run(&done);
     8424    done = false;
     8425
     8426    auto pid1 = [webView _webProcessIdentifier];
     8427
     8428    [webView loadRequest:server2.request("/destination.html")];
     8429    Util::run(&done);
     8430    done = false;
     8431
     8432    [webView evaluateJavaScript:@"navigator.userAgent;" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
     8433        done = true;
     8434
     8435        ASSERT_TRUE(!error);
     8436        NSString *userAgent = (NSString *)response;
     8437        ASSERT_TRUE([userAgent containsString:@"Macintosh; Intel Mac"]);
     8438    }];
     8439    Util::run(&done);
     8440    done = false;
     8441
     8442    auto pid2 = [webView _webProcessIdentifier];
     8443    EXPECT_NE(pid1, pid2);
     8444
     8445    [webView goBack]; // Back to source.html.
     8446    Util::run(&done);
     8447    done = false;
     8448
     8449    [webView evaluateJavaScript:@"navigator.userAgent;" completionHandler:^(id _Nullable response, NSError * _Nullable error) {
     8450        done = true;
     8451
     8452        ASSERT_TRUE(!error);
     8453        NSString *userAgent = (NSString *)response;
     8454        ASSERT_TRUE([userAgent containsString:@"Macintosh; Intel Mac"]);
     8455    }];
     8456    Util::run(&done);
     8457    done = false;
     8458}
     8459#endif // PLATFORM(IOS_FAMILY)
Note: See TracChangeset for help on using the changeset viewer.