Make SessionStorage work with process swapping.
authorbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Apr 2018 20:01:27 +0000 (20:01 +0000)
committerbeidson@apple.com <beidson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 3 Apr 2018 20:01:27 +0000 (20:01 +0000)
https://bugs.webkit.org/show_bug.cgi?id=184270

Reviewed by Andy Estes.

Source/WebKit:

Due to a minor process accounting error, WebPageProxys weren't always being reconnected with their
WebsiteDataStore's StorageManager when doing process swaps.

Fix that error, and SessionStorage "just works."

* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::webProcessWillShutDown):
(WebKit::WebPageProxy::processDidTerminate): For NavigationSwap termination, make sure to tell the
  process lifetime tracker that this page was removed.

* UIProcess/WebProcessLifetimeObserver.h:
(WebKit::WebProcessLifetimeObserver::webPageWasInvalidated): Renamed from "webPageWasRemoved"
(WebKit::WebProcessLifetimeObserver::webPageWasRemoved): Deleted.

* UIProcess/WebProcessLifetimeTracker.cpp:
(WebKit::WebProcessLifetimeTracker::webPageLeavingWebProcess): Renamed from "webProcessWillShutDown"
(WebKit::WebProcessLifetimeTracker::pageWasInvalidated):
(WebKit::WebProcessLifetimeTracker::webProcessWillShutDown): Deleted.
* UIProcess/WebProcessLifetimeTracker.h:

* UIProcess/WebsiteData/WebsiteDataStore.cpp:
(WebKit::WebsiteDataStore::webPageWasInvalidated):
(WebKit::WebsiteDataStore::webPageWasRemoved): Deleted.
* UIProcess/WebsiteData/WebsiteDataStore.h:

Tools:

* TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
(-[PSONMessageHandler userContentController:didReceiveScriptMessage:]):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@230219 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit/ChangeLog
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/WebProcessLifetimeObserver.h
Source/WebKit/UIProcess/WebProcessLifetimeTracker.cpp
Source/WebKit/UIProcess/WebProcessLifetimeTracker.h
Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.cpp
Source/WebKit/UIProcess/WebsiteData/WebsiteDataStore.h
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm

index d670ad9..1e2764e 100644 (file)
@@ -1,3 +1,35 @@
+2018-04-03  Brady Eidson  <beidson@apple.com>
+
+        Make SessionStorage work with process swapping.
+        https://bugs.webkit.org/show_bug.cgi?id=184270
+
+        Reviewed by Andy Estes.
+
+        Due to a minor process accounting error, WebPageProxys weren't always being reconnected with their
+        WebsiteDataStore's StorageManager when doing process swaps.
+
+        Fix that error, and SessionStorage "just works."
+
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::webProcessWillShutDown):
+        (WebKit::WebPageProxy::processDidTerminate): For NavigationSwap termination, make sure to tell the 
+          process lifetime tracker that this page was removed.
+
+        * UIProcess/WebProcessLifetimeObserver.h:
+        (WebKit::WebProcessLifetimeObserver::webPageWasInvalidated): Renamed from "webPageWasRemoved"
+        (WebKit::WebProcessLifetimeObserver::webPageWasRemoved): Deleted.
+
+        * UIProcess/WebProcessLifetimeTracker.cpp:
+        (WebKit::WebProcessLifetimeTracker::webPageLeavingWebProcess): Renamed from "webProcessWillShutDown"
+        (WebKit::WebProcessLifetimeTracker::pageWasInvalidated):
+        (WebKit::WebProcessLifetimeTracker::webProcessWillShutDown): Deleted.
+        * UIProcess/WebProcessLifetimeTracker.h:
+
+        * UIProcess/WebsiteData/WebsiteDataStore.cpp:
+        (WebKit::WebsiteDataStore::webPageWasInvalidated):
+        (WebKit::WebsiteDataStore::webPageWasRemoved): Deleted.
+        * UIProcess/WebsiteData/WebsiteDataStore.h:
+
 2018-04-03  Commit Queue  <commit-queue@webkit.org>
 
         Unreviewed, rolling out r230210.
index cfad873..03b0c6c 100644 (file)
@@ -4167,7 +4167,7 @@ void WebPageProxy::connectionWillOpen(IPC::Connection& connection)
 
 void WebPageProxy::webProcessWillShutDown()
 {
-    m_webProcessLifetimeTracker.webProcessWillShutDown();
+    m_webProcessLifetimeTracker.webPageLeavingWebProcess();
 }
 
 void WebPageProxy::processDidFinishLaunching()
@@ -5619,7 +5619,9 @@ void WebPageProxy::processDidTerminate(ProcessTerminationReason reason)
     // For bringup of process swapping, NavigationSwap termination will not go out to clients.
     // If it does *during* process swapping, and the client triggers a reload, that causes bizarre WebKit re-entry.
     // FIXME: This might have to change
-    if (reason != ProcessTerminationReason::NavigationSwap) {
+    if (reason == ProcessTerminationReason::NavigationSwap)
+        m_webProcessLifetimeTracker.webPageLeavingWebProcess();
+    else {
         navigationState().clearAllNavigations();
 
         if (m_navigationClient)
index 5c5bfea..48f7a0e 100644 (file)
@@ -56,7 +56,7 @@ private:
     virtual void webPageWillOpenConnection(WebPageProxy&, IPC::Connection&) { }
     virtual void webPageDidCloseConnection(WebPageProxy&, IPC::Connection&) { }
     virtual void webProcessDidCloseConnection(WebProcessProxy&, IPC::Connection&) { }
-    virtual void webPageWasRemoved(WebPageProxy&) { }
+    virtual void webPageWasInvalidated(WebPageProxy&) { }
 
     HashCountedSet<WebProcessProxy*> m_processes;
 };
index 3d74ed5..7f2599a 100644 (file)
@@ -61,7 +61,7 @@ void WebProcessLifetimeTracker::connectionWillOpen(IPC::Connection&)
         observer->addWebPage(m_webPageProxy);
 }
 
-void WebProcessLifetimeTracker::webProcessWillShutDown()
+void WebProcessLifetimeTracker::webPageLeavingWebProcess()
 {
     ASSERT(processIsRunning());
 
@@ -77,7 +77,7 @@ void WebProcessLifetimeTracker::pageWasInvalidated()
     for (auto& observer : m_observers) {
         observer->removeWebPage(m_webPageProxy);
 
-        observer->webPageWasRemoved(m_webPageProxy);
+        observer->webPageWasInvalidated(m_webPageProxy);
     }
 }
 
index 7a73b73..dc85777 100644 (file)
@@ -45,7 +45,7 @@ public:
     void addObserver(WebProcessLifetimeObserver&);
 
     void connectionWillOpen(IPC::Connection&);
-    void webProcessWillShutDown();
+    void webPageLeavingWebProcess();
 
     void pageWasInvalidated();
 
index 0f9e9ac..f993d32 100644 (file)
@@ -1263,7 +1263,7 @@ void WebsiteDataStore::webPageWasAdded(WebPageProxy& webPageProxy)
         m_storageManager->createSessionStorageNamespace(webPageProxy.pageID(), std::numeric_limits<unsigned>::max());
 }
 
-void WebsiteDataStore::webPageWasRemoved(WebPageProxy& webPageProxy)
+void WebsiteDataStore::webPageWasInvalidated(WebPageProxy& webPageProxy)
 {
     if (m_storageManager)
         m_storageManager->destroySessionStorageNamespace(webPageProxy.pageID());
index f8b4903..aa90743 100644 (file)
@@ -173,7 +173,7 @@ private:
 
     // WebProcessLifetimeObserver.
     void webPageWasAdded(WebPageProxy&) override;
-    void webPageWasRemoved(WebPageProxy&) override;
+    void webPageWasInvalidated(WebPageProxy&) override;
     void webProcessWillOpenConnection(WebProcessProxy&, IPC::Connection&) override;
     void webPageWillOpenConnection(WebPageProxy&, IPC::Connection&) override;
     void webPageDidCloseConnection(WebPageProxy&, IPC::Connection&) override;
index 84d4bdd..50c2af4 100644 (file)
@@ -1,3 +1,13 @@
+2018-04-03  Brady Eidson  <beidson@apple.com>
+
+        Make SessionStorage work with process swapping.
+        https://bugs.webkit.org/show_bug.cgi?id=184270
+
+        Reviewed by Andy Estes.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/ProcessSwapOnNavigation.mm:
+        (-[PSONMessageHandler userContentController:didReceiveScriptMessage:]):
+
 2018-04-03  Chris Dumez  <cdumez@apple.com>
 
         Drop MainFrame class
index 71a8ac3..2f51b15 100644 (file)
@@ -67,7 +67,11 @@ static HashSet<pid_t> seenPIDs;
 @implementation PSONMessageHandler
 - (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message
 {
-    [receivedMessages addObject:[message body]];
+    if ([message body])
+        [receivedMessages addObject:[message body]];
+    else
+        [receivedMessages addObject:@""];
+
     receivedMessage = true;
 }
 @end
@@ -606,5 +610,81 @@ TEST(ProcessSwap, ServerRedirect2)
     EXPECT_EQ(2u, seenPIDs.size());
 }
 
+static const char* sessionStorageTestBytes = R"PSONRESOURCE(
+<head>
+<script>
+
+function log(msg)
+{
+    window.webkit.messageHandlers.pson.postMessage(msg);
+}
+
+window.onload = function(evt) {
+    log(sessionStorage.psonKey);
+    sessionStorage.psonKey = "I exist!";
+}
+
+</script>
+</head>
+)PSONRESOURCE";
+
+TEST(ProcessSwap, SessionStorage)
+{
+    auto processPoolConfiguration = adoptNS([[_WKProcessPoolConfiguration alloc] init]);
+    [processPoolConfiguration setProcessSwapsOnNavigation:YES];
+    auto processPool = adoptNS([[WKProcessPool alloc] _initWithConfiguration:processPoolConfiguration.get()]);
+
+    auto webViewConfiguration = adoptNS([[WKWebViewConfiguration alloc] init]);
+    [webViewConfiguration setProcessPool:processPool.get()];
+    auto handler1 = adoptNS([[PSONScheme alloc] initWithBytes:sessionStorageTestBytes]);
+    auto handler2 = adoptNS([[PSONScheme alloc] init]);
+    [webViewConfiguration setURLSchemeHandler:handler1.get() forURLScheme:@"PSON1"];
+    [webViewConfiguration setURLSchemeHandler:handler2.get() forURLScheme:@"PSON2"];
+
+    auto messageHandler = adoptNS([[PSONMessageHandler alloc] init]);
+    [[webViewConfiguration userContentController] addScriptMessageHandler:messageHandler.get() name:@"pson"];
+
+    auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:webViewConfiguration.get()]);
+    auto delegate = adoptNS([[PSONNavigationDelegate alloc] init]);
+    [webView setNavigationDelegate:delegate.get()];
+
+    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson1://host/main.html"]];
+    [webView loadRequest:request];
+
+    TestWebKitAPI::Util::run(&receivedMessage);
+    receivedMessage = false;
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    auto pid1 = [webView _webProcessIdentifier];
+
+    request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson2://host/main.html"]];
+    [webView loadRequest:request];
+
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    auto pid2 = [webView _webProcessIdentifier];
+
+    request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"pson1://host/main.html"]];
+    [webView loadRequest:request];
+
+    TestWebKitAPI::Util::run(&receivedMessage);
+    receivedMessage = false;
+    TestWebKitAPI::Util::run(&done);
+    done = false;
+
+    auto pid3 = [webView _webProcessIdentifier];
+
+    // Verify the web pages are in different processes
+    EXPECT_NE(pid1, pid2);
+    EXPECT_NE(pid1, pid3);
+    EXPECT_NE(pid2, pid3);
+
+    // Verify the sessionStorage values were as expected
+    EXPECT_EQ([receivedMessages count], 2u);
+    EXPECT_TRUE([receivedMessages.get()[0] isEqualToString:@""]);
+    EXPECT_TRUE([receivedMessages.get()[1] isEqualToString:@"I exist!"]);
+}
 
 #endif // WK_API_ENABLED