- Revision
- 236973
- Author
- cdu...@apple.com
- Date
- 2018-10-09 12:04:44 -0700 (Tue, 09 Oct 2018)
Log Message
PSON: Doing a cross-site navigation via the URL bar does not swap process on iOS
https://bugs.webkit.org/show_bug.cgi?id=190378
<rdar://problem/45059466>
Reviewed by Geoffrey Garen.
Source/WebKit:
Process swapping was sometimes not happening via URL bar navigation on iOS due to top-hit preloading,
which would use a new WKWebView for the speculative load and rely on the _relatedWebView SPI to use
the same WebContent process as the view currently on screen.
To address the issue, if the source URL is empty and the page has a related page, use the related
page's URL as source URL when doing the process-swap decision.
* UIProcess/API/APIPageConfiguration.cpp:
(API::PageConfiguration::relatedPage const):
(API::PageConfiguration::relatedPage): Deleted.
* UIProcess/API/APIPageConfiguration.h:
* UIProcess/WebProcessPool.cpp:
(WebKit::WebProcessPool::processForNavigationInternal):
Tools:
Add API test coverage.
* TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
Modified Paths
Diff
Modified: trunk/Source/WebKit/ChangeLog (236972 => 236973)
--- trunk/Source/WebKit/ChangeLog 2018-10-09 19:04:18 UTC (rev 236972)
+++ trunk/Source/WebKit/ChangeLog 2018-10-09 19:04:44 UTC (rev 236973)
@@ -1,3 +1,25 @@
+2018-10-09 Chris Dumez <cdu...@apple.com>
+
+ PSON: Doing a cross-site navigation via the URL bar does not swap process on iOS
+ https://bugs.webkit.org/show_bug.cgi?id=190378
+ <rdar://problem/45059466>
+
+ Reviewed by Geoffrey Garen.
+
+ Process swapping was sometimes not happening via URL bar navigation on iOS due to top-hit preloading,
+ which would use a new WKWebView for the speculative load and rely on the _relatedWebView SPI to use
+ the same WebContent process as the view currently on screen.
+
+ To address the issue, if the source URL is empty and the page has a related page, use the related
+ page's URL as source URL when doing the process-swap decision.
+
+ * UIProcess/API/APIPageConfiguration.cpp:
+ (API::PageConfiguration::relatedPage const):
+ (API::PageConfiguration::relatedPage): Deleted.
+ * UIProcess/API/APIPageConfiguration.h:
+ * UIProcess/WebProcessPool.cpp:
+ (WebKit::WebProcessPool::processForNavigationInternal):
+
2018-10-09 Andy Estes <aes...@apple.com>
[iOS] Replace @"UIPreviewDataAttachmentListIsContentManaged" with a UIKit constant
Modified: trunk/Source/WebKit/UIProcess/API/APIPageConfiguration.cpp (236972 => 236973)
--- trunk/Source/WebKit/UIProcess/API/APIPageConfiguration.cpp 2018-10-09 19:04:18 UTC (rev 236972)
+++ trunk/Source/WebKit/UIProcess/API/APIPageConfiguration.cpp 2018-10-09 19:04:44 UTC (rev 236973)
@@ -129,7 +129,7 @@
m_preferences = preferences;
}
-WebPageProxy* PageConfiguration::relatedPage()
+WebPageProxy* PageConfiguration::relatedPage() const
{
return m_relatedPage.get();
}
Modified: trunk/Source/WebKit/UIProcess/API/APIPageConfiguration.h (236972 => 236973)
--- trunk/Source/WebKit/UIProcess/API/APIPageConfiguration.h 2018-10-09 19:04:18 UTC (rev 236972)
+++ trunk/Source/WebKit/UIProcess/API/APIPageConfiguration.h 2018-10-09 19:04:44 UTC (rev 236973)
@@ -72,7 +72,7 @@
WebKit::WebPreferencesStore::ValueMap& preferenceValues() { return m_preferenceValues; }
- WebKit::WebPageProxy* relatedPage();
+ WebKit::WebPageProxy* relatedPage() const;
void setRelatedPage(WebKit::WebPageProxy*);
WebKit::VisitedLinkStore* visitedLinkStore();
Modified: trunk/Source/WebKit/UIProcess/WebProcessPool.cpp (236972 => 236973)
--- trunk/Source/WebKit/UIProcess/WebProcessPool.cpp 2018-10-09 19:04:18 UTC (rev 236972)
+++ trunk/Source/WebKit/UIProcess/WebProcessPool.cpp 2018-10-09 19:04:44 UTC (rev 236973)
@@ -2138,12 +2138,18 @@
}
bool isInitialLoadInNewWindowOpenedByDOM = page.openedByDOM() && !page.hasCommittedAnyProvisionalLoads();
- URL url;
+ URL sourceURL;
if (isInitialLoadInNewWindowOpenedByDOM && !navigation.requesterOrigin().isEmpty())
- url = "" { URL(), navigation.requesterOrigin().toString() };
+ sourceURL = URL { URL(), navigation.requesterOrigin().toString() };
else
- url = "" { { }, page.pageLoadState().url() };
- if (!url.isValid() || !targetURL.isValid() || url.isEmpty() || url.isBlankURL() || registrableDomainsAreEqual(url, targetURL)) {
+ sourceURL = URL { { }, page.pageLoadState().url() };
+
+ if (sourceURL.isEmpty() && page.configuration().relatedPage()) {
+ sourceURL = URL { { }, page.configuration().relatedPage()->pageLoadState().url() };
+ RELEASE_LOG(ProcessSwapping, "Using related page %p's URL as source URL for process swap decision", page.configuration().relatedPage());
+ }
+
+ if (!sourceURL.isValid() || !targetURL.isValid() || sourceURL.isEmpty() || sourceURL.isBlankURL() || registrableDomainsAreEqual(sourceURL, targetURL)) {
reason = "Navigation is same-site"_s;
return page.process();
}
Modified: trunk/Tools/ChangeLog (236972 => 236973)
--- trunk/Tools/ChangeLog 2018-10-09 19:04:18 UTC (rev 236972)
+++ trunk/Tools/ChangeLog 2018-10-09 19:04:44 UTC (rev 236973)
@@ -1,3 +1,15 @@
+2018-10-09 Chris Dumez <cdu...@apple.com>
+
+ PSON: Doing a cross-site navigation via the URL bar does not swap process on iOS
+ https://bugs.webkit.org/show_bug.cgi?id=190378
+ <rdar://problem/45059466>
+
+ Reviewed by Geoffrey Garen.
+
+ Add API test coverage.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
+
2018-10-09 Jer Noble <jer.no...@apple.com>
ISOTrackEncryptionBox returns incorrect defaultKeyID
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm (236972 => 236973)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm 2018-10-09 19:04:18 UTC (rev 236972)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm 2018-10-09 19:04:44 UTC (rev 236973)
@@ -1803,6 +1803,65 @@
EXPECT_NE(pid1, pid3);
}
+enum class ExpectSwap { No, Yes };
+static void runProcessSwapDueToRelatedWebViewTest(NSURL* relatedViewURL, NSURL* targetURL, ExpectSwap expectSwap)
+{
+ auto processPoolConfiguration = adoptNS([[_WKProcessPoolConfiguration alloc] init]);
+ processPoolConfiguration.get().processSwapsOnNavigation = YES;
+ processPoolConfiguration.get().prewarmsProcessesAutomatically = YES;
+ auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
+
+ auto webView1Configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ [webView1Configuration setProcessPool:processPool.get()];
+ auto handler = adoptNS([[PSONScheme alloc] init]);
+ [webView1Configuration setURLSchemeHandler:handler.get() forURLScheme:@"PSON"];
+
+ auto webView1 = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webView1Configuration.get()]);
+ auto delegate = adoptNS([[PSONNavigationDelegate alloc] init]);
+ [webView1 setNavigationDelegate:delegate.get()];
+
+ numberOfDecidePolicyCalls = 0;
+ NSURLRequest *request = [NSURLRequest requestWithURL:relatedViewURL];
+ [webView1 loadRequest:request];
+
+ TestWebKitAPI::Util::run(&done);
+ done = false;
+
+ auto pid1 = [webView1 _webProcessIdentifier];
+
+ auto webView2Configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
+ [webView2Configuration setProcessPool:processPool.get()];
+ [webView2Configuration setURLSchemeHandler:handler.get() forURLScheme:@"PSON"];
+ webView2Configuration.get()._relatedWebView = webView1.get(); // webView2 will be related to webView1 and webView1's URL will be used for process swap decision.
+ auto webView2 = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webView2Configuration.get()]);
+ [webView2 setNavigationDelegate:delegate.get()];
+
+ request = [NSURLRequest requestWithURL:targetURL];
+ [webView2 loadRequest:request];
+
+ TestWebKitAPI::Util::run(&done);
+ done = false;
+
+ auto pid2 = [webView2 _webProcessIdentifier];
+
+ if (expectSwap == ExpectSwap::No)
+ EXPECT_TRUE(pid1 == pid2);
+ else
+ EXPECT_FALSE(pid1 == pid2);
+
+ EXPECT_EQ(2, numberOfDecidePolicyCalls);
+}
+
+TEST(ProcessSwap, ProcessSwapDueToRelatedView)
+{
+ runProcessSwapDueToRelatedWebViewTest([NSURL URLWithString:@"pson://www.webkit.org/main1.html"], [NSURL URLWithString:@"pson://www.apple.com/main2.html"], ExpectSwap::Yes);
+}
+
+TEST(ProcessSwap, NoProcessSwapDueToRelatedView)
+{
+ runProcessSwapDueToRelatedWebViewTest([NSURL URLWithString:@"pson://www.webkit.org/main1.html"], [NSURL URLWithString:@"pson://www.webkit.org/main2.html"], ExpectSwap::No);
+}
+
TEST(ProcessSwap, TerminatedSuspendedPageProcess)
{
auto processPoolConfiguration = adoptNS([[_WKProcessPoolConfiguration alloc] init]);