Tab suspension code shouldn't use page cache cacheability logic
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 30 Jan 2016 01:29:33 +0000 (01:29 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 30 Jan 2016 01:29:33 +0000 (01:29 +0000)
https://bugs.webkit.org/show_bug.cgi?id=153680

Reviewed by Andreas Kling.

Most of PageCache::canCache() is unnecessary for tab suspension.

Also improve robustness.

* page/Page.cpp:
(WebCore::Page::setPageActivityState):
(WebCore::Page::setIsVisible):
(WebCore::Page::setIsVisibleInternal):
(WebCore::Page::setIsPrerender):
(WebCore::Page::canTabSuspend):

    Include visibility test here.

    Instead of calling PageCache::canCache() just check for each frame that
    - that the document is loaded
    - that active DOM objects allow suspension

(WebCore::Page::setIsTabSuspended):
(WebCore::Page::setTabSuspensionEnabled):
(WebCore::Page::updateTabSuspensionState):

    Refactor for robustness.

(WebCore::Page::tabSuspensionTimerFired):

    Call canTabSuspend, the result might have changed.

(WebCore::Page::scheduleTabSuspension): Deleted.
* page/Page.h:

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

Source/WebCore/ChangeLog
Source/WebCore/page/Page.cpp
Source/WebCore/page/Page.h

index 2b46c07..3758f25 100644 (file)
@@ -1,3 +1,40 @@
+2016-01-29  Antti Koivisto  <antti@apple.com>
+
+        Tab suspension code shouldn't use page cache cacheability logic
+        https://bugs.webkit.org/show_bug.cgi?id=153680
+
+        Reviewed by Andreas Kling.
+
+        Most of PageCache::canCache() is unnecessary for tab suspension.
+
+        Also improve robustness.
+
+        * page/Page.cpp:
+        (WebCore::Page::setPageActivityState):
+        (WebCore::Page::setIsVisible):
+        (WebCore::Page::setIsVisibleInternal):
+        (WebCore::Page::setIsPrerender):
+        (WebCore::Page::canTabSuspend):
+
+            Include visibility test here.
+
+            Instead of calling PageCache::canCache() just check for each frame that
+            - that the document is loaded
+            - that active DOM objects allow suspension
+
+        (WebCore::Page::setIsTabSuspended):
+        (WebCore::Page::setTabSuspensionEnabled):
+        (WebCore::Page::updateTabSuspensionState):
+
+            Refactor for robustness.
+
+        (WebCore::Page::tabSuspensionTimerFired):
+
+            Call canTabSuspend, the result might have changed.
+
+        (WebCore::Page::scheduleTabSuspension): Deleted.
+        * page/Page.h:
+
 2016-01-29  Ryosuke Niwa  <rniwa@webkit.org>
 
         fast/shadow-dom/Element-interface-attachShadow.html fails on iOS
index 407760d..c3dd9e7 100644 (file)
@@ -1305,10 +1305,7 @@ void Page::setPageActivityState(PageActivityState::Flags activityState)
 {
     chrome().client().setPageActivityState(activityState);
     
-    if (activityState == PageActivityState::NoFlags && !isVisible())
-        scheduleTabSuspension(true);
-    else
-        scheduleTabSuspension(false);
+    updateTabSuspensionState();
 }
 
 void Page::setIsVisible(bool isVisible)
@@ -1361,7 +1358,7 @@ void Page::setIsVisibleInternal(bool isVisible)
             view->hide();
     }
 
-    scheduleTabSuspension(!isVisible);
+    updateTabSuspensionState();
 }
 
 void Page::setIsPrerender()
@@ -1867,17 +1864,29 @@ bool Page::canTabSuspend()
         return false;
     if (m_isPrerender)
         return false;
-    if (m_pageThrottler.activityState() != PageActivityState::NoFlags)
+    if (isVisible())
         return false;
-    // FIXME: PageCache::canCache does a bunch of checks that are not needed for the tab suspension case. There should be a specific check.
-    if (!PageCache::singleton().canCache(*this))
+    if (m_pageThrottler.activityState() != PageActivityState::NoFlags)
         return false;
 
+    for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
+        if (frame->loader().state() == FrameStateProvisional)
+            return false;
+        if (frame->loader().isLoading())
+            return false;
+        if (!frame->document() || !frame->document()->canSuspendActiveDOMObjectsForDocumentSuspension(nullptr))
+            return false;
+    }
+
     return true;
 }
 
 void Page::setIsTabSuspended(bool shouldSuspend)
 {
+    if (m_isTabSuspended == shouldSuspend)
+        return;
+    m_isTabSuspended = shouldSuspend;
+
     for (Frame* frame = &mainFrame(); frame; frame = frame->tree().traverseNext()) {
         if (auto* document = frame->document()) {
             if (shouldSuspend)
@@ -1893,26 +1902,19 @@ void Page::setTabSuspensionEnabled(bool enable)
     s_tabSuspensionIsEnabled = enable;
 }
 
-void Page::scheduleTabSuspension(bool shouldSuspend)
+void Page::updateTabSuspensionState()
 {
-    if (m_shouldTabSuspend == shouldSuspend)
-        return;
-    
-    if (shouldSuspend && canTabSuspend()) {
-        m_shouldTabSuspend = shouldSuspend;
+    if (canTabSuspend()) {
         m_tabSuspensionTimer.startOneShot(0);
-    } else {
-        m_tabSuspensionTimer.stop();
-        if (!shouldSuspend) {
-            m_shouldTabSuspend = shouldSuspend;
-            setIsTabSuspended(false);
-        }
+        return;
     }
+    m_tabSuspensionTimer.stop();
+    setIsTabSuspended(false);
 }
 
 void Page::tabSuspensionTimerFired()
 {
-    setIsTabSuspended(true);
+    setIsTabSuspended(canTabSuspend());
 }
 
 } // namespace WebCore
index d9b7e12..5f6ef08 100644 (file)
@@ -521,7 +521,7 @@ private:
     void hiddenPageDOMTimerThrottlingStateChanged();
     void setTimerThrottlingEnabled(bool);
     bool canTabSuspend();
-    void scheduleTabSuspension(bool);
+    void updateTabSuspensionState();
     void tabSuspensionTimerFired();
 
     const std::unique_ptr<Chrome> m_chrome;
@@ -663,7 +663,7 @@ private:
     SessionID m_sessionID;
 
     bool m_isClosing;
-    bool m_shouldTabSuspend { false };
+    bool m_isTabSuspended { false };
     Timer m_tabSuspensionTimer;
 
     MediaProducer::MediaStateFlags m_mediaState { MediaProducer::IsNotPlaying };