Bug 193967 - Regression (r240046): [PSON] Spurious changes to [WKWebView url] and [WKWebView loading] after [WKWebView loadRequest]
Summary: Regression (r240046): [PSON] Spurious changes to [WKWebView url] and [WKWebVi...
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: Page Loading (show other bugs)
Version: WebKit Local Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Chris Dumez
URL:
Keywords: InRadar
Depends on:
Blocks:
 
Reported: 2019-01-29 09:47 PST by Ali Juma
Modified: 2019-01-29 13:00 PST (History)
8 users (show)

See Also:


Attachments
Patch (8.84 KB, patch)
2019-01-29 10:41 PST, Chris Dumez
no flags Details | Formatted Diff | Diff
Patch (9.27 KB, patch)
2019-01-29 12:15 PST, Chris Dumez
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Ali Juma 2019-01-29 09:47:21 PST
After r240046, on a cross-origin [WKWebView loadRequest], [WKWebView url] will first change to the new URL, then *change back* to the old URL, then change again to the new URL. Similarly, [WKWebView loading] will become true, then become false, and then become true again.

More specifically, we get the following sequence:
1) [WKWebView loadRequest] --> [WKWebView ur] becomes the request URL and [WKWebView loading] becomes true
2) WebPageProxy::receivedPolicyDecision --> [WKWebView url] reverts to the previous URL and [WKWebView loading] becomes false
3) WebPageProxy::didStartProvisionalLoadForFrameShared --> [WKWebView url] becomes the requested URL again, and [WKWebView loading] becomes true again

The extra changes in (2) and (3) are confusing to embedders (like Chrome) that are doing KVO on [WKWebView url] and [WKWebView loading], since the change in (2) makes it look like the load was aborted.

The cause of these changes is that in r240046, WebPageProxy::receivedNavigationPolicyDecision sets policyAction to Ignore (instead of Suspend) on navigations which trigger process swaps, which then makes WebPageProxy::receivedPolicyDecision call PageLoadState::clearPendingAPIRequestURL, and this has the effect of reverting [WKWebView url] to the old URL and making [WKWebView loading] false.

Navigations initiated by [WKWebView goToBackForwardListItem] also have this broken behavior.
Comment 1 Radar WebKit Bug Importer 2019-01-29 09:48:49 PST
<rdar://problem/47635348>
Comment 2 Chris Dumez 2019-01-29 09:54:11 PST
Thanks for reporting this Ali, will fix ASAP.
Comment 3 Chris Dumez 2019-01-29 10:09:46 PST
Ali, how/when is it observable by the client exactly?

I tried to write the following API test but it is passing:
TEST(ProcessSwap, LoadingStateAfterPolicyDecision)
{
    auto processPoolConfiguration = adoptNS([[_WKProcessPoolConfiguration alloc] init]);
    processPoolConfiguration.get().processSwapsOnNavigation = YES;
    auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);

    auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
    [webViewConfiguration setProcessPool:processPool.get()];
    auto handler = adoptNS([[PSONScheme alloc] init]);
    [webViewConfiguration setURLSchemeHandler:handler.get() forURLScheme:@"PSON"];

    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
    auto navigationDelegate = adoptNS([[PSONNavigationDelegate alloc] init]);
    [webView setNavigationDelegate:navigationDelegate.get()];

    [webView configuration].preferences.safeBrowsingEnabled = NO;

    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.webkit.org/main.html"]]];
    TestWebKitAPI::Util::run(&done);
    done = false;

    didStartProvisionalLoad = false;
    [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"pson://www.apple.com/main.html"]]];
    EXPECT_WK_STREQ(@"pson://www.apple.com/main.html", [[webView URL] absoluteString]);
    EXPECT_TRUE([webView isLoading]);

    navigationDelegate->decidePolicyForNavigationAction = ^(WKNavigationAction *, void (^decisionHandler)(WKNavigationActionPolicy)) {
        EXPECT_WK_STREQ(@"pson://www.apple.com/main.html", [[webView URL] absoluteString]);
        EXPECT_TRUE([webView isLoading]);

        decisionHandler(WKNavigationActionPolicyAllow);

        EXPECT_WK_STREQ(@"pson://www.apple.com/main.html", [[webView URL] absoluteString]);
        EXPECT_TRUE([webView isLoading]);
    };

    TestWebKitAPI::Util::run(&didStartProvisionalLoad);
    didStartProvisionalLoad = false;

    EXPECT_WK_STREQ(@"pson://www.apple.com/main.html", [[webView URL] absoluteString]);
    EXPECT_TRUE([webView isLoading]);

    TestWebKitAPI::Util::run(&done);
    done = false;

    EXPECT_WK_STREQ(@"pson://www.apple.com/main.html", [[webView URL] absoluteString]);
    EXPECT_FALSE([webView isLoading]);
}
Comment 4 Chris Dumez 2019-01-29 10:28:14 PST
(In reply to Chris Dumez from comment #3)
> Ali, how/when is it observable by the client exactly?
> 
> I tried to write the following API test but it is passing:
> TEST(ProcessSwap, LoadingStateAfterPolicyDecision)
> {
>     auto processPoolConfiguration = adoptNS([[_WKProcessPoolConfiguration
> alloc] init]);
>     processPoolConfiguration.get().processSwapsOnNavigation = YES;
>     auto processPool = adoptNS([[WKProcessPool alloc]
> _initWithConfiguration:processPoolConfiguration.get()]);
> 
>     auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc]
> init]);
>     [webViewConfiguration setProcessPool:processPool.get()];
>     auto handler = adoptNS([[PSONScheme alloc] init]);
>     [webViewConfiguration setURLSchemeHandler:handler.get()
> forURLScheme:@"PSON"];
> 
>     auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0,
> 800, 600) configuration:webViewConfiguration.get()]);
>     auto navigationDelegate = adoptNS([[PSONNavigationDelegate alloc] init]);
>     [webView setNavigationDelegate:navigationDelegate.get()];
> 
>     [webView configuration].preferences.safeBrowsingEnabled = NO;
> 
>     [webView loadRequest:[NSURLRequest requestWithURL:[NSURL
> URLWithString:@"pson://www.webkit.org/main.html"]]];
>     TestWebKitAPI::Util::run(&done);
>     done = false;
> 
>     didStartProvisionalLoad = false;
>     [webView loadRequest:[NSURLRequest requestWithURL:[NSURL
> URLWithString:@"pson://www.apple.com/main.html"]]];
>     EXPECT_WK_STREQ(@"pson://www.apple.com/main.html", [[webView URL]
> absoluteString]);
>     EXPECT_TRUE([webView isLoading]);
> 
>     navigationDelegate->decidePolicyForNavigationAction =
> ^(WKNavigationAction *, void (^decisionHandler)(WKNavigationActionPolicy)) {
>         EXPECT_WK_STREQ(@"pson://www.apple.com/main.html", [[webView URL]
> absoluteString]);
>         EXPECT_TRUE([webView isLoading]);
> 
>         decisionHandler(WKNavigationActionPolicyAllow);
> 
>         EXPECT_WK_STREQ(@"pson://www.apple.com/main.html", [[webView URL]
> absoluteString]);
>         EXPECT_TRUE([webView isLoading]);
>     };
> 
>     TestWebKitAPI::Util::run(&didStartProvisionalLoad);
>     didStartProvisionalLoad = false;
> 
>     EXPECT_WK_STREQ(@"pson://www.apple.com/main.html", [[webView URL]
> absoluteString]);
>     EXPECT_TRUE([webView isLoading]);
> 
>     TestWebKitAPI::Util::run(&done);
>     done = false;
> 
>     EXPECT_WK_STREQ(@"pson://www.apple.com/main.html", [[webView URL]
> absoluteString]);
>     EXPECT_FALSE([webView isLoading]);
> }

Nevermind, I can reproduce using KVO for "loading" key instead.
Comment 5 Chris Dumez 2019-01-29 10:41:44 PST
Created attachment 360473 [details]
Patch
Comment 6 EWS Watchlist 2019-01-29 10:44:19 PST
Attachment 360473 [details] did not pass style-queue:


ERROR: Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:3475:  This { should be at the end of the previous line  [whitespace/braces] [4]
Total errors found: 1 in 5 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 7 Ali Juma 2019-01-29 11:03:30 PST
Thanks for uploading a fix Chris!

(In reply to Chris Dumez from comment #4)
> Nevermind, I can reproduce using KVO for "loading" key instead.

Yeah, this is observable by the client when doing KVO on 'loading' or on 'url'.
Comment 8 Alex Christensen 2019-01-29 12:01:07 PST
Comment on attachment 360473 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=360473&action=review

> Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:3476
> +    EXPECT_WK_STREQ(@"loading", keyPath);

Should the test observe url also?
Comment 9 Chris Dumez 2019-01-29 12:09:39 PST
Comment on attachment 360473 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=360473&action=review

>> Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:3476
>> +    EXPECT_WK_STREQ(@"loading", keyPath);
> 
> Should the test observe url also?

Why not. Let me look up how to do that.
Comment 10 Chris Dumez 2019-01-29 12:15:06 PST
Created attachment 360487 [details]
Patch
Comment 11 Chris Dumez 2019-01-29 12:15:20 PST
(In reply to Chris Dumez from comment #9)
> Comment on attachment 360473 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=360473&action=review
> 
> >> Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:3476
> >> +    EXPECT_WK_STREQ(@"loading", keyPath);
> > 
> > Should the test observe url also?
> 
> Why not. Let me look up how to do that.

Done.
Comment 12 EWS Watchlist 2019-01-29 12:18:09 PST
Attachment 360487 [details] did not pass style-queue:


ERROR: Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:3476:  This { should be at the end of the previous line  [whitespace/braces] [4]
Total errors found: 1 in 5 files


If any of these errors are false positives, please file a bug against check-webkit-style.
Comment 13 Chris Dumez 2019-01-29 13:00:04 PST
Comment on attachment 360487 [details]
Patch

Clearing flags on attachment: 360487

Committed r240675: <https://trac.webkit.org/changeset/240675>
Comment 14 Chris Dumez 2019-01-29 13:00:06 PST
All reviewed patches have been landed.  Closing bug.