WKWebView loses minimum layout size overrides that happen while the process is terminated
authortimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 4 Jan 2018 22:54:09 +0000 (22:54 +0000)
committertimothy_horton@apple.com <timothy_horton@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 4 Jan 2018 22:54:09 +0000 (22:54 +0000)
https://bugs.webkit.org/show_bug.cgi?id=181306
<rdar://problem/34398288>

Reviewed by Dan Bernstein.

Source/WebKit:

* Shared/WebPageCreationParameters.cpp:
(WebKit::WebPageCreationParameters::encode const):
(WebKit::WebPageCreationParameters::decode):
* Shared/WebPageCreationParameters.h:
* UIProcess/API/Cocoa/WKWebView.mm:
(-[WKWebView _didRelaunchProcess]): Deleted.
* UIProcess/API/Cocoa/WKWebViewPrivate.h:
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::creationParameters):
* UIProcess/WebPageProxy.h:
* UIProcess/ios/PageClientImplIOS.mm:
(WebKit::PageClientImpl::didRelaunchProcess):
* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::setViewportConfigurationMinimumLayoutSize):
(WebKit::WebPageProxy::setForceAlwaysUserScalable):
(WebKit::WebPageProxy::setMaximumUnobscuredSize):
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::WebPage):
Pass the current viewport minimum layout size and maximum unobscured size
in the WebPageCreationParameters instead of re-sending them in _didRelaunchProcess.

The previous approach was problematic when _dispatchSetMinimumLayoutSize:
was changed to not re-send identical updates, because if the client calls
_overrideLayoutParametersWithMinimumLayoutSize before the Web Content process
is re-launched (after terminating), we would cache the size, attempt to send it,
fail silently (because the process is not launched), and then in _didRelaunchProcess
we would choose not to re-send (after the process is successfully relaunched)
because we think we already sent the new value.

Add isValid() checks to our message sends. Ideally send() would assert
if the process is not alive to avoid problems like this, but it doesn't (yet).

Get rid of WKWebView's _didRelaunchProcess, because it does nothing now.

Tools:

* TestWebKitAPI/Tests/WebKitCocoa/AnimatedResize.mm:
(TEST):
Add a test that calling _overrideLayoutParametersWithMinimumLayoutSize
while the process is terminated results in the page getting the correct
minimum layout size.

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

12 files changed:
Source/WebKit/ChangeLog
Source/WebKit/Shared/WebPageCreationParameters.cpp
Source/WebKit/Shared/WebPageCreationParameters.h
Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm
Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h
Source/WebKit/UIProcess/WebPageProxy.cpp
Source/WebKit/UIProcess/WebPageProxy.h
Source/WebKit/UIProcess/ios/PageClientImplIOS.mm
Source/WebKit/UIProcess/ios/WebPageProxyIOS.mm
Source/WebKit/WebProcess/WebPage/WebPage.cpp
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebKitCocoa/AnimatedResize.mm

index 3a00a4e..5fc65c7 100644 (file)
@@ -1,3 +1,45 @@
+2018-01-04  Tim Horton  <timothy_horton@apple.com>
+
+        WKWebView loses minimum layout size overrides that happen while the process is terminated
+        https://bugs.webkit.org/show_bug.cgi?id=181306
+        <rdar://problem/34398288>
+
+        Reviewed by Dan Bernstein.
+
+        * Shared/WebPageCreationParameters.cpp:
+        (WebKit::WebPageCreationParameters::encode const):
+        (WebKit::WebPageCreationParameters::decode):
+        * Shared/WebPageCreationParameters.h:
+        * UIProcess/API/Cocoa/WKWebView.mm:
+        (-[WKWebView _didRelaunchProcess]): Deleted.
+        * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+        * UIProcess/WebPageProxy.cpp:
+        (WebKit::WebPageProxy::creationParameters):
+        * UIProcess/WebPageProxy.h:
+        * UIProcess/ios/PageClientImplIOS.mm:
+        (WebKit::PageClientImpl::didRelaunchProcess):
+        * UIProcess/ios/WebPageProxyIOS.mm:
+        (WebKit::WebPageProxy::setViewportConfigurationMinimumLayoutSize):
+        (WebKit::WebPageProxy::setForceAlwaysUserScalable):
+        (WebKit::WebPageProxy::setMaximumUnobscuredSize):
+        * WebProcess/WebPage/WebPage.cpp:
+        (WebKit::WebPage::WebPage):
+        Pass the current viewport minimum layout size and maximum unobscured size
+        in the WebPageCreationParameters instead of re-sending them in _didRelaunchProcess.
+
+        The previous approach was problematic when _dispatchSetMinimumLayoutSize:
+        was changed to not re-send identical updates, because if the client calls 
+        _overrideLayoutParametersWithMinimumLayoutSize before the Web Content process
+        is re-launched (after terminating), we would cache the size, attempt to send it,
+        fail silently (because the process is not launched), and then in _didRelaunchProcess
+        we would choose not to re-send (after the process is successfully relaunched)
+        because we think we already sent the new value.
+
+        Add isValid() checks to our message sends. Ideally send() would assert
+        if the process is not alive to avoid problems like this, but it doesn't (yet).
+
+        Get rid of WKWebView's _didRelaunchProcess, because it does nothing now.
+
 2018-01-04  Stephan Szabo  <stephan.szabo@sony.com>
 
         NetworkProcess cache files use functions from unistd.h without explicitly including it
index e533a4d..78f509a 100644 (file)
@@ -87,6 +87,8 @@ void WebPageCreationParameters::encode(IPC::Encoder& encoder) const
     encoder << availableScreenSize;
     encoder << textAutosizingWidth;
     encoder << ignoresViewportScaleLimits;
+    encoder << viewportConfigurationMinimumLayoutSize;
+    encoder << maximumUnobscuredSize;
 #endif
 #if PLATFORM(COCOA)
     encoder << smartInsertDeleteEnabled;
@@ -239,6 +241,10 @@ std::optional<WebPageCreationParameters> WebPageCreationParameters::decode(IPC::
         return std::nullopt;
     if (!decoder.decode(parameters.ignoresViewportScaleLimits))
         return std::nullopt;
+    if (!decoder.decode(parameters.viewportConfigurationMinimumLayoutSize))
+        return std::nullopt;
+    if (!decoder.decode(parameters.maximumUnobscuredSize))
+        return std::nullopt;
 #endif
 
 #if PLATFORM(COCOA)
index 7150352..a20996e 100644 (file)
@@ -144,6 +144,8 @@ struct WebPageCreationParameters {
     WebCore::FloatSize availableScreenSize;
     float textAutosizingWidth;
     bool ignoresViewportScaleLimits;
+    WebCore::FloatSize viewportConfigurationMinimumLayoutSize;
+    WebCore::FloatSize maximumUnobscuredSize;
 #endif
 #if PLATFORM(COCOA)
     bool smartInsertDeleteEnabled;
index fe26381..323b968 100644 (file)
@@ -4155,15 +4155,6 @@ static int32_t activeOrientation(WKWebView *webView)
 
 #endif
 
-- (void)_didRelaunchProcess
-{
-#if PLATFORM(IOS)
-    CGRect bounds = self.bounds;
-    [self _dispatchSetMinimumLayoutSize:activeMinimumLayoutSize(self, bounds)];
-    [self _dispatchSetMaximumUnobscuredSize:activeMaximumUnobscuredSize(self, bounds)];
-#endif
-}
-
 - (NSData *)_sessionStateData
 {
     WebKit::SessionState sessionState = _page->sessionState();
index a5a7087..768489e 100644 (file)
@@ -239,7 +239,6 @@ typedef NS_OPTIONS(NSInteger, _WKRectEdge) {
 - (void)_setOverlaidAccessoryViewsInset:(CGSize)inset;
 
 - (void)_killWebContentProcess;
-- (void)_didRelaunchProcess;
 
 // Puts the view into a state where being taken out of the view hierarchy and resigning first responder
 // will not count as becoming inactive and unfocused. The returned block must be called to exit the state.
index c150129..84dd857 100644 (file)
@@ -5813,6 +5813,8 @@ WebPageCreationParameters WebPageProxy::creationParameters()
     parameters.textAutosizingWidth = textAutosizingWidth();
     parameters.mimeTypesWithCustomContentProviders = m_pageClient.mimeTypesWithCustomContentProviders();
     parameters.ignoresViewportScaleLimits = m_forceAlwaysUserScalable;
+    parameters.viewportConfigurationMinimumLayoutSize = m_viewportConfigurationMinimumLayoutSize;
+    parameters.maximumUnobscuredSize = m_maximumUnobscuredSize;
 #endif
 
 #if PLATFORM(MAC)
index 2dce6ba..1891110 100644 (file)
@@ -2064,6 +2064,8 @@ private:
     bool m_hasDeferredStartAssistingNode { false };
     std::unique_ptr<NodeAssistanceArguments> m_deferredNodeAssistanceArguments;
     bool m_forceAlwaysUserScalable { false };
+    WebCore::FloatSize m_viewportConfigurationMinimumLayoutSize;
+    WebCore::FloatSize m_maximumUnobscuredSize;
 #endif
 
 #if ENABLE(POINTER_LOCK)
index b58405d..05c6696 100644 (file)
@@ -211,7 +211,6 @@ void PageClientImpl::processDidExit()
 void PageClientImpl::didRelaunchProcess()
 {
     [m_contentView _didRelaunchProcess];
-    [m_webView _didRelaunchProcess];
 }
 
 void PageClientImpl::pageClosed()
index 371a6c6..c3e6f2d 100644 (file)
@@ -333,7 +333,10 @@ void WebPageProxy::synchronizeDynamicViewportUpdate()
 
 void WebPageProxy::setViewportConfigurationMinimumLayoutSize(const WebCore::FloatSize& size)
 {
-    m_process->send(Messages::WebPage::SetViewportConfigurationMinimumLayoutSize(size), m_pageID);
+    m_viewportConfigurationMinimumLayoutSize = size;
+
+    if (isValid())
+        m_process->send(Messages::WebPage::SetViewportConfigurationMinimumLayoutSize(size), m_pageID);
 }
 
 void WebPageProxy::setForceAlwaysUserScalable(bool userScalable)
@@ -341,12 +344,17 @@ void WebPageProxy::setForceAlwaysUserScalable(bool userScalable)
     if (m_forceAlwaysUserScalable == userScalable)
         return;
     m_forceAlwaysUserScalable = userScalable;
-    m_process->send(Messages::WebPage::SetForceAlwaysUserScalable(userScalable), m_pageID);
+
+    if (isValid())
+        m_process->send(Messages::WebPage::SetForceAlwaysUserScalable(userScalable), m_pageID);
 }
 
 void WebPageProxy::setMaximumUnobscuredSize(const WebCore::FloatSize& size)
 {
-    m_process->send(Messages::WebPage::SetMaximumUnobscuredSize(size), m_pageID);
+    m_maximumUnobscuredSize = size;
+
+    if (isValid())
+        m_process->send(Messages::WebPage::SetMaximumUnobscuredSize(size), m_pageID);
 }
 
 void WebPageProxy::setDeviceOrientation(int32_t deviceOrientation)
index 029b34a..66c8319 100644 (file)
@@ -583,6 +583,11 @@ WebPage::WebPage(uint64_t pageID, WebPageCreationParameters&& parameters)
 #if ENABLE(CONTENT_EXTENSIONS)
     m_userContentController->addContentRuleLists(parameters.contentRuleLists);
 #endif
+
+#if PLATFORM(IOS)
+    setViewportConfigurationMinimumLayoutSize(parameters.viewportConfigurationMinimumLayoutSize);
+    setMaximumUnobscuredSize(parameters.maximumUnobscuredSize);
+#endif
 }
 
 #if ENABLE(WEB_RTC)
index 06c1b02..ba8552f 100644 (file)
@@ -1,3 +1,17 @@
+2018-01-04  Tim Horton  <timothy_horton@apple.com>
+
+        WKWebView loses minimum layout size overrides that happen while the process is terminated
+        https://bugs.webkit.org/show_bug.cgi?id=181306
+        <rdar://problem/34398288>
+
+        Reviewed by Dan Bernstein.
+
+        * TestWebKitAPI/Tests/WebKitCocoa/AnimatedResize.mm:
+        (TEST):
+        Add a test that calling _overrideLayoutParametersWithMinimumLayoutSize
+        while the process is terminated results in the page getting the correct
+        minimum layout size.
+
 2018-01-04  Eric Carlson  <eric.carlson@apple.com>
 
         [MediaStream] Add Mock screen capture source
index 3979268..597bdab 100644 (file)
@@ -249,4 +249,37 @@ TEST(WebKit, OverrideLayoutSizeIsRestoredAfterProcessRelaunch)
     TestWebKitAPI::Util::run(&didReadLayoutSize);
 }
 
+TEST(WebKit, OverrideLayoutSizeIsRestoredAfterChangingDuringProcessRelaunch)
+{
+    auto webView = createAnimatedResizeWebView();
+    [webView setUIDelegate:webView.get()];
+
+    [webView _overrideLayoutParametersWithMinimumLayoutSize:CGSizeMake(100, 100) maximumUnobscuredSizeOverride:CGSizeMake(100, 100)];
+
+    [webView loadHTMLString:@"<head><meta name='viewport' content='initial-scale=1'></head>" baseURL:nil];
+    [webView _test_waitForDidFinishNavigation];
+
+    auto window = adoptNS([[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 800, 600)]);
+    [window addSubview:webView.get()];
+    [window setHidden:NO];
+
+    [webView _killWebContentProcessAndResetState];
+    [webView _overrideLayoutParametersWithMinimumLayoutSize:CGSizeMake(200, 50) maximumUnobscuredSizeOverride:CGSizeMake(200, 50)];
+
+    [webView loadHTMLString:@"<head><meta name='viewport' content='initial-scale=1'></head>" baseURL:nil];
+    [webView _test_waitForDidFinishNavigation];
+
+    __block bool didReadLayoutSize = false;
+    [webView evaluateJavaScript:@"[window.innerWidth, window.innerHeight]" completionHandler:^(id value, NSError *error) {
+        CGFloat innerWidth = [[value objectAtIndex:0] floatValue];
+        CGFloat innerHeight = [[value objectAtIndex:1] floatValue];
+
+        EXPECT_EQ(innerWidth, 200);
+        EXPECT_EQ(innerHeight, 50);
+
+        didReadLayoutSize = true;
+    }];
+    TestWebKitAPI::Util::run(&didReadLayoutSize);
+}
+
 #endif