Title: [204716] trunk/Source/WebKit2
Revision
204716
Author
[email protected]
Date
2016-08-22 08:39:44 -0700 (Mon, 22 Aug 2016)

Log Message

[iOS] Wait a few seconds before release network activity assertion after a load
https://bugs.webkit.org/show_bug.cgi?id=160975
<rdar://problem/27910964>

Reviewed by Darin Adler.

Some apps do several loads one after the other in a non-visible view.
This causes us to release the background assertion every time a load
completes and then take one again less than a second after. Every
time we release the assertion, we send a PrepareToSuspend IPC to the
WebContent process, which does all the clean up to get ready to
suspend, only to get a CancelPrepareReadyToSuspend later on because
the next load has started. To work around this problem, we now wait
a few seconds before releasing the background activity after a load.

* UIProcess/Cocoa/NavigationState.h:
* UIProcess/Cocoa/NavigationState.mm:
(WebKit::NavigationState::NavigationState):
(WebKit::NavigationState::releaseNetworkActivityToken):
(WebKit::NavigationState::didChangeIsLoading):

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (204715 => 204716)


--- trunk/Source/WebKit2/ChangeLog	2016-08-22 15:18:10 UTC (rev 204715)
+++ trunk/Source/WebKit2/ChangeLog	2016-08-22 15:39:44 UTC (rev 204716)
@@ -1,3 +1,26 @@
+2016-08-22  Chris Dumez  <[email protected]>
+
+        [iOS] Wait a few seconds before release network activity assertion after a load
+        https://bugs.webkit.org/show_bug.cgi?id=160975
+        <rdar://problem/27910964>
+
+        Reviewed by Darin Adler.
+
+        Some apps do several loads one after the other in a non-visible view.
+        This causes us to release the background assertion every time a load
+        completes and then take one again less than a second after. Every
+        time we release the assertion, we send a PrepareToSuspend IPC to the
+        WebContent process, which does all the clean up to get ready to
+        suspend, only to get a CancelPrepareReadyToSuspend later on because
+        the next load has started. To work around this problem, we now wait
+        a few seconds before releasing the background activity after a load.
+
+        * UIProcess/Cocoa/NavigationState.h:
+        * UIProcess/Cocoa/NavigationState.mm:
+        (WebKit::NavigationState::NavigationState):
+        (WebKit::NavigationState::releaseNetworkActivityToken):
+        (WebKit::NavigationState::didChangeIsLoading):
+
 2016-08-22  Youenn Fablet  <[email protected]>
 
         [Fetch API] Activate fetch api runtime flag by default

Modified: trunk/Source/WebKit2/UIProcess/Cocoa/NavigationState.h (204715 => 204716)


--- trunk/Source/WebKit2/UIProcess/Cocoa/NavigationState.h	2016-08-22 15:18:10 UTC (rev 204715)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/NavigationState.h	2016-08-22 15:39:44 UTC (rev 204716)
@@ -35,6 +35,7 @@
 #import "PageLoadState.h"
 #import "ProcessThrottler.h"
 #import "WeakObjCPtr.h"
+#import <WebCore/Timer.h>
 #import <wtf/RetainPtr.h>
 
 @class WKWebView;
@@ -152,6 +153,10 @@
     void willChangeWebProcessIsResponsive() override;
     void didChangeWebProcessIsResponsive() override;
 
+#if PLATFORM(IOS)
+    void releaseNetworkActivityToken();
+#endif
+
     WKWebView *m_webView;
     WeakObjCPtr<id <WKNavigationDelegate> > m_navigationDelegate;
 
@@ -199,6 +204,7 @@
 
 #if PLATFORM(IOS)
     ProcessThrottler::BackgroundActivityToken m_activityToken;
+    WebCore::Timer m_releaseActivityTimer;
 #endif
 };
 

Modified: trunk/Source/WebKit2/UIProcess/Cocoa/NavigationState.mm (204715 => 204716)


--- trunk/Source/WebKit2/UIProcess/Cocoa/NavigationState.mm	2016-08-22 15:18:10 UTC (rev 204715)
+++ trunk/Source/WebKit2/UIProcess/Cocoa/NavigationState.mm	2016-08-22 15:39:44 UTC (rev 204716)
@@ -89,6 +89,9 @@
     : m_webView(webView)
     , m_navigationDelegateMethods()
     , m_historyDelegateMethods()
+#if PLATFORM(IOS)
+    , m_releaseActivityTimer(*this, &NavigationState::releaseNetworkActivityToken)
+#endif
 {
     ASSERT(m_webView->_page);
     ASSERT(!navigationStates().contains(m_webView->_page.get()));
@@ -819,15 +822,30 @@
     [m_webView willChangeValueForKey:@"loading"];
 }
 
+#if PLATFORM(IOS)
+void NavigationState::releaseNetworkActivityToken()
+{
+    RELEASE_LOG_IF(m_webView->_page->isAlwaysOnLoggingAllowed(), "%p UIProcess is releasing a background assertion because a page load completed", this);
+    ASSERT(m_activityToken);
+    m_activityToken = nullptr;
+}
+#endif
+
 void NavigationState::didChangeIsLoading()
 {
 #if PLATFORM(IOS)
     if (m_webView->_page->pageLoadState().isLoading()) {
-        RELEASE_LOG_IF(m_webView->_page->isAlwaysOnLoggingAllowed(), "UIProcess is taking a background assertion because a page load started");
-        m_activityToken = m_webView->_page->process().throttler().backgroundActivityToken();
+        if (m_releaseActivityTimer.isActive())
+            m_releaseActivityTimer.stop();
+        else {
+            RELEASE_LOG_IF(m_webView->_page->isAlwaysOnLoggingAllowed(), "%p - UIProcess is taking a background assertion because a page load started", this);
+            ASSERT(!m_activityToken);
+            m_activityToken = m_webView->_page->process().throttler().backgroundActivityToken();
+        }
     } else {
-        RELEASE_LOG_IF(m_webView->_page->isAlwaysOnLoggingAllowed(), "UIProcess is releasing a background assertion because a page load completed");
-        m_activityToken = nullptr;
+        // Delay releasing the background activity for 3 seconds to give the application a chance to start another navigation
+        // before suspending the WebContent process <rdar://problem/27910964>.
+        m_releaseActivityTimer.startOneShot(3s);
     }
 #endif
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to