Changeset 233986 in webkit


Ignore:
Timestamp:
Jul 19, 2018 9:56:58 AM (6 years ago)
Author:
beidson@apple.com
Message:

Add an SPI policy action to allow clients to explicitly ask for a new process on a navigation.
https://bugs.webkit.org/show_bug.cgi?id=187789

Reviewed by Andy Estes.

Source/WebKit:

At navigation policy time, when a client says "use/allow", they can now say "use/allow in a new process if possible"

  • UIProcess/API/C/WKFramePolicyListener.cpp:

(WKFramePolicyListenerUseInNewProcess):
(WKFramePolicyListenerUseInNewProcessWithPolicies):

  • UIProcess/API/C/WKFramePolicyListener.h:
  • UIProcess/API/Cocoa/WKNavigationDelegatePrivate.h:
  • UIProcess/Cocoa/NavigationState.mm:

(WebKit::NavigationState::NavigationClient::decidePolicyForNavigationAction):

  • UIProcess/WebFrameListenerProxy.h:

(WebKit::WebFrameListenerProxy::setApplyPolicyInNewProcessIfPossible):
(WebKit::WebFrameListenerProxy::applyPolicyInNewProcessIfPossible const):

  • UIProcess/WebPageProxy.cpp:

(WebKit::WebPageProxy::receivedPolicyDecision):

  • UIProcess/WebProcessPool.cpp:

(WebKit::WebProcessPool::processForNavigation):
(WebKit::WebProcessPool::processForNavigationInternal):

  • UIProcess/WebProcessPool.h:

Tools:

  • TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:

(-[PSONNavigationDelegate init]):
(-[PSONNavigationDelegate webView:decidePolicyForNavigationAction:decisionHandler:]):

Location:
trunk
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r233983 r233986  
     12018-07-19  Brady Eidson  <beidson@apple.com>
     2
     3        Add an SPI policy action to allow clients to explicitly ask for a new process on a navigation.
     4        https://bugs.webkit.org/show_bug.cgi?id=187789
     5
     6        Reviewed by Andy Estes.
     7
     8        At navigation policy time, when a client says "use/allow", they can now say "use/allow in a new process if possible"
     9
     10        * UIProcess/API/C/WKFramePolicyListener.cpp:
     11        (WKFramePolicyListenerUseInNewProcess):
     12        (WKFramePolicyListenerUseInNewProcessWithPolicies):
     13        * UIProcess/API/C/WKFramePolicyListener.h:
     14
     15        * UIProcess/API/Cocoa/WKNavigationDelegatePrivate.h:
     16
     17        * UIProcess/Cocoa/NavigationState.mm:
     18        (WebKit::NavigationState::NavigationClient::decidePolicyForNavigationAction):
     19
     20        * UIProcess/WebFrameListenerProxy.h:
     21        (WebKit::WebFrameListenerProxy::setApplyPolicyInNewProcessIfPossible):
     22        (WebKit::WebFrameListenerProxy::applyPolicyInNewProcessIfPossible const):
     23
     24        * UIProcess/WebPageProxy.cpp:
     25        (WebKit::WebPageProxy::receivedPolicyDecision):
     26
     27        * UIProcess/WebProcessPool.cpp:
     28        (WebKit::WebProcessPool::processForNavigation):
     29        (WebKit::WebProcessPool::processForNavigationInternal):
     30        * UIProcess/WebProcessPool.h:
     31
    1322018-07-19  Youenn Fablet  <youenn@apple.com>
    233
  • trunk/Source/WebKit/UIProcess/API/C/WKFramePolicyListener.cpp

    r228472 r233986  
    4646}
    4747
     48void WKFramePolicyListenerUseInNewProcess(WKFramePolicyListenerRef policyListenerRef)
     49{
     50    toImpl(policyListenerRef)->setApplyPolicyInNewProcessIfPossible(true);
     51    toImpl(policyListenerRef)->use(std::nullopt);
     52}
     53
    4854void WKFramePolicyListenerUseWithPolicies(WKFramePolicyListenerRef policyListenerRef, WKWebsitePoliciesRef websitePolicies)
    4955{
     
    6167}
    6268
     69void WKFramePolicyListenerUseInNewProcessWithPolicies(WKFramePolicyListenerRef policyListenerRef, WKWebsitePoliciesRef websitePolicies)
     70{
     71    toImpl(policyListenerRef)->setApplyPolicyInNewProcessIfPossible(true);
     72    WKFramePolicyListenerUseWithPolicies(policyListenerRef, websitePolicies);
     73}
     74
    6375void WKFramePolicyListenerDownload(WKFramePolicyListenerRef policyListenerRef)
    6476{
  • trunk/Source/WebKit/UIProcess/API/C/WKFramePolicyListener.h

    r209558 r233986  
    3535
    3636WK_EXPORT void WKFramePolicyListenerUse(WKFramePolicyListenerRef);
     37WK_EXPORT void WKFramePolicyListenerUseInNewProcess(WKFramePolicyListenerRef);
    3738WK_EXPORT void WKFramePolicyListenerDownload(WKFramePolicyListenerRef);
    3839WK_EXPORT void WKFramePolicyListenerIgnore(WKFramePolicyListenerRef);
    3940WK_EXPORT void WKFramePolicyListenerUseWithPolicies(WKFramePolicyListenerRef, WKWebsitePoliciesRef);
     41WK_EXPORT void WKFramePolicyListenerUseInNewProcessWithPolicies(WKFramePolicyListenerRef, WKWebsitePoliciesRef);
    4042
    4143#ifdef __cplusplus
  • trunk/Source/WebKit/UIProcess/API/Cocoa/WKNavigationDelegatePrivate.h

    r230121 r233986  
    5757
    5858static const WKNavigationActionPolicy _WKNavigationActionPolicyDownload = (WKNavigationActionPolicy)(WKNavigationActionPolicyAllow + 1);
    59 static const WKNavigationActionPolicy WK_API_AVAILABLE(macosx(10.11), ios(9.0)) _WKNavigationActionPolicyAllowWithoutTryingAppLink = (WKNavigationActionPolicy)(WKNavigationActionPolicyAllow + 2);
     59static const WKNavigationActionPolicy WK_API_AVAILABLE(macosx(10.11), ios(9.0)) _WKNavigationActionPolicyAllowWithoutTryingAppLink = (WKNavigationActionPolicy)(_WKNavigationActionPolicyDownload + 1);
     60static const WKNavigationActionPolicy WK_API_AVAILABLE(macosx(WK_MAC_TBA), ios(WK_IOS_TBA)) _WKNavigationActionPolicyAllowInNewProcess = (WKNavigationActionPolicy)(_WKNavigationActionPolicyAllowWithoutTryingAppLink + 1);
    6061
    6162static const WKNavigationResponsePolicy _WKNavigationResponsePolicyBecomeDownload = (WKNavigationResponsePolicy)(WKNavigationResponsePolicyAllow + 1);
  • trunk/Source/WebKit/UIProcess/Cocoa/NavigationState.mm

    r232668 r233986  
    546546        switch (actionPolicy) {
    547547        case WKNavigationActionPolicyAllow:
    548             tryAppLink(WTFMove(navigationAction), mainFrameURLString, [localListener = WTFMove(localListener), data = WTFMove(data)](bool followedLinkToApp) mutable {
     548// FIXME: Once we have a new enough compiler everywhere we don't need to ignore -Wswitch.
     549#pragma clang diagnostic push
     550#pragma clang diagnostic ignored "-Wswitch"
     551        case _WKNavigationActionPolicyAllowInNewProcess:
     552#pragma clang diagnostic pop
     553            tryAppLink(WTFMove(navigationAction), mainFrameURLString, [actionPolicy, localListener = WTFMove(localListener), data = WTFMove(data)](bool followedLinkToApp) mutable {
     554                localListener->setApplyPolicyInNewProcessIfPossible(actionPolicy == _WKNavigationActionPolicyAllowInNewProcess);
    549555                if (followedLinkToApp) {
    550556                    localListener->ignore();
  • trunk/Source/WebKit/UIProcess/WebFrameListenerProxy.h

    r228472 r233986  
    4848
    4949    void changeWebsiteDataStore(WebsiteDataStore&);
     50
     51    void setApplyPolicyInNewProcessIfPossible(bool applyPolicyInNewProcessIfPossible) { m_applyPolicyInNewProcessIfPossible = applyPolicyInNewProcessIfPossible; }
     52    bool applyPolicyInNewProcessIfPossible() const { return m_applyPolicyInNewProcessIfPossible; }
     53
    5054    bool isMainFrame() const;
    5155
     
    5963    uint64_t m_listenerID;
    6064    RefPtr<API::Navigation> m_navigation;
     65    bool m_applyPolicyInNewProcessIfPossible { false };
    6166};
    6267
  • trunk/Source/WebKit/UIProcess/WebPageProxy.cpp

    r233866 r233986  
    24392439
    24402440        if (action == PolicyAction::Use && navigation && frame.isMainFrame()) {
    2441             auto proposedProcess = process().processPool().processForNavigation(*this, *navigation, action);
     2441            auto proposedProcess = process().processPool().processForNavigation(*this, *navigation, activePolicyListener->applyPolicyInNewProcessIfPossible(), action);
    24422442
    24432443            if (proposedProcess.ptr() != &process()) {
  • trunk/Source/WebKit/UIProcess/WebProcessPool.cpp

    r233897 r233986  
    21072107}
    21082108
    2109 Ref<WebProcessProxy> WebProcessPool::processForNavigation(WebPageProxy& page, const API::Navigation& navigation, PolicyAction& action)
    2110 {
    2111     auto process = processForNavigationInternal(page, navigation, action);
     2109Ref<WebProcessProxy> WebProcessPool::processForNavigation(WebPageProxy& page, const API::Navigation& navigation, bool shouldProcessSwapIfPossible, PolicyAction& action)
     2110{
     2111    auto process = processForNavigationInternal(page, navigation, shouldProcessSwapIfPossible, action);
    21122112
    21132113    if (m_configuration->alwaysKeepAndReuseSwappedProcesses() && process.ptr() != &page.process()) {
     
    21252125}
    21262126
    2127 Ref<WebProcessProxy> WebProcessPool::processForNavigationInternal(WebPageProxy& page, const API::Navigation& navigation, PolicyAction& action)
    2128 {
    2129     if (!m_configuration->processSwapsOnNavigation())
     2127Ref<WebProcessProxy> WebProcessPool::processForNavigationInternal(WebPageProxy& page, const API::Navigation& navigation, bool shouldProcessSwapIfPossible, PolicyAction& action)
     2128{
     2129    if (!m_configuration->processSwapsOnNavigation() && !shouldProcessSwapIfPossible)
    21302130        return page.process();
    21312131
     
    21702170    }
    21712171
    2172     if (navigation.treatAsSameOriginNavigation())
    2173         return page.process();
    2174 
    21752172    auto targetURL = navigation.currentRequest().url();
    2176     auto url = URL { ParsedURLString, page.pageLoadState().url() };
    2177     if (!url.isValid() || !targetURL.isValid() || url.isEmpty() || url.isBlankURL() || protocolHostAndPortAreEqual(url, targetURL))
    2178         return page.process();
    2179 
     2173    if (!shouldProcessSwapIfPossible) {
     2174        if (navigation.treatAsSameOriginNavigation())
     2175            return page.process();
     2176
     2177        auto url = URL { ParsedURLString, page.pageLoadState().url() };
     2178        if (!url.isValid() || !targetURL.isValid() || url.isEmpty() || url.isBlankURL() || protocolHostAndPortAreEqual(url, targetURL))
     2179            return page.process();
     2180    }
     2181   
    21802182    if (m_configuration->alwaysKeepAndReuseSwappedProcesses()) {
    21812183        auto origin = SecurityOriginData::fromURL(targetURL);
  • trunk/Source/WebKit/UIProcess/WebProcessPool.h

    r233897 r233986  
    453453#endif
    454454
    455     Ref<WebProcessProxy> processForNavigation(WebPageProxy&, const API::Navigation&, WebCore::PolicyAction&);
     455    Ref<WebProcessProxy> processForNavigation(WebPageProxy&, const API::Navigation&, bool shouldProcessSwapIfPossible, WebCore::PolicyAction&);
    456456    void registerSuspendedPageProxy(SuspendedPageProxy&);
    457457    void unregisterSuspendedPageProxy(SuspendedPageProxy&);
     
    471471    void platformInvalidateContext();
    472472
    473     Ref<WebProcessProxy> processForNavigationInternal(WebPageProxy&, const API::Navigation&, WebCore::PolicyAction&);
     473    Ref<WebProcessProxy> processForNavigationInternal(WebPageProxy&, const API::Navigation&, bool shouldProcessSwapIfPossible, WebCore::PolicyAction&);
    474474
    475475    RefPtr<WebProcessProxy> tryTakePrewarmedProcess(WebsiteDataStore&);
  • trunk/Tools/ChangeLog

    r233979 r233986  
     12018-07-19  Brady Eidson  <beidson@apple.com>
     2
     3        Add an SPI policy action to allow clients to explicitly ask for a new process on a navigation.
     4        https://bugs.webkit.org/show_bug.cgi?id=187789
     5
     6        Reviewed by Andy Estes.
     7
     8        * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
     9        (-[PSONNavigationDelegate init]):
     10        (-[PSONNavigationDelegate webView:decidePolicyForNavigationAction:decisionHandler:]):
     11
    1122018-07-19  Thibault Saunier  <tsaunier@igalia.com>
    213
  • trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm

    r231704 r233986  
    2929#import "Test.h"
    3030#import <WebKit/WKInspector.h>
    31 #import <WebKit/WKNavigationDelegate.h>
     31#import <WebKit/WKNavigationDelegatePrivate.h>
    3232#import <WebKit/WKNavigationPrivate.h>
    3333#import <WebKit/WKPreferencesPrivate.h>
     
    8686@end
    8787
    88 @interface PSONNavigationDelegate : NSObject <WKNavigationDelegate>
     88@interface PSONNavigationDelegate : NSObject <WKNavigationDelegate> {
     89    @public WKNavigationActionPolicy navigationActionPolicyToUse;
     90}
    8991@end
    9092
    9193@implementation PSONNavigationDelegate
     94
     95- (instancetype) init
     96{
     97    self = [super init];
     98    navigationActionPolicyToUse = WKNavigationActionPolicyAllow;
     99    return self;
     100}
    92101
    93102- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation withError:(NSError *)error
     
    107116    ++numberOfDecidePolicyCalls;
    108117    seenPIDs.add([webView _webProcessIdentifier]);
    109     decisionHandler(WKNavigationActionPolicyAllow);
     118    decisionHandler(navigationActionPolicyToUse);
    110119}
    111120
     
    14351444}
    14361445
     1446TEST(ProcessSwap, APIControlledProcessSwapping)
     1447{
     1448    auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
     1449    RetainPtr<PSONScheme> handler = adoptNS([[PSONScheme alloc] initWithBytes:"Hello World!"]);
     1450    [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"PSON"];
     1451
     1452    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
     1453    auto navigationDelegate = adoptNS([[PSONNavigationDelegate alloc] init]);
     1454    [webView setNavigationDelegate:navigationDelegate.get()];
     1455
     1456    numberOfDecidePolicyCalls = 0;
     1457    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://host/1"]]];
     1458    TestWebKitAPI::Util::run(&done);
     1459    done = false;
     1460    auto pid1 = [webView _webProcessIdentifier];
     1461
     1462    // Navigating from the above URL to this URL normally should not process swap.
     1463    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://host/2"]]];
     1464    TestWebKitAPI::Util::run(&done);
     1465    done = false;
     1466    auto pid2 = [webView _webProcessIdentifier];
     1467
     1468    EXPECT_EQ(1u, seenPIDs.size());
     1469    EXPECT_EQ(pid1, pid2);
     1470
     1471    // Navigating from the above URL to this URL normally should not process swap,
     1472    // but we'll explicitly ask for a swap.
     1473    navigationDelegate->navigationActionPolicyToUse = _WKNavigationActionPolicyAllowInNewProcess;
     1474    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://host/3"]]];
     1475    TestWebKitAPI::Util::run(&done);
     1476    done = false;
     1477    auto pid3 = [webView _webProcessIdentifier];
     1478   
     1479    EXPECT_EQ(3, numberOfDecidePolicyCalls);
     1480    EXPECT_EQ(2u, seenPIDs.size());
     1481    EXPECT_NE(pid1, pid3);
     1482}
     1483
    14371484#endif // WK_API_ENABLED
Note: See TracChangeset for help on using the changeset viewer.