Title: [164948] trunk/Source/WebCore
Revision
164948
Author
[email protected]
Date
2014-03-02 12:44:17 -0800 (Sun, 02 Mar 2014)

Log Message

Split UserActivity, simplify PageThrottler
https://bugs.webkit.org/show_bug.cgi?id=129551

Reviewed by Darin Adler.

The class UserActivity currently implements two things – a hysteresis mechanism, and
an abstraction of NSActivity controlled by that mechanism. PageThrottler implements
its own hysteresis mechanism, which directly controls DOM timer throttling and also
controls a couple of UserActivities, giving a total of 3 separate hysteresis mechanisms,
layered two deep.

Split UserActivity into three, with HysteresisActivity implementing an abstract hysteresis
mechanism, UserActivity::Impl controlling the NSActivity, and then UserActivity combining
these two back together. The interface to UserActivity is unchanged.

Remove PageThrottler's bespoke hysteresis, replacing it with a use of HysteresisActivity.
Replace the two UserActivities with a single UserActivity::Impl, so there are no longer
layered hysteresis mechanisms.

* WebCore.exp.in:
    - exports changed.
* WebCore.xcodeproj/project.pbxproj:
    - added HysteresisActivity.h.
* page/PageThrottler.cpp:
(WebCore::PageThrottler::PageThrottler):
    - if the page starts visible, begin activity. If it starts hidden throttle DOM timers.
(WebCore::PageThrottler::hiddenPageDOMTimerThrottlingStateChanged):
    - when the DOM timer throttling setting changes, make sure we update.
(WebCore::PageThrottler::incrementActivityCount):
(WebCore::PageThrottler::decrementActivityCount):
    - when m_activityCount changes update the hysteresis state.
(WebCore::PageThrottler::updateHysteresis):
(WebCore::PageThrottler::setViewState):
    - when IsVisuallyIdle changes update the hysteresis state.
(WebCore::PageThrottler::started):
(WebCore::PageThrottler::stopped):
    - callbacks from HysteresisActivity, these control m_activity and DOM timer throttling.
* page/PageThrottler.h:
(WebCore::PageThrottler::didReceiveUserInput):
(WebCore::PageThrottler::pluginDidEvaluate):
    - call impulse to temporarily enable the activity.
* platform/HysteresisActivity.h: Copied from Source/WebCore/platform/UserActivity.h.
(WebCore::HysteresisActivity::HysteresisActivity):
    - constructor takes a delegate optionally a timeout.
(WebCore::HysteresisActivity::start):
    - start activity immediately. If stopped, call started method on delegate. If in timeout period, cancel the timer.
(WebCore::HysteresisActivity::stop):
    - stop activity after hysteresis. If started, initiate timeout period.
(WebCore::HysteresisActivity::impulse):
    - ensure activity for at least the timeout period.
(WebCore::HysteresisActivity::hysteresisTimerFired):
    - delayed stop - when the timer fires call stopped on the delegate.
* platform/UserActivity.cpp:
(WebCore::UserActivity::Impl::Impl):
(WebCore::UserActivity::Impl::beginActivity):
(WebCore::UserActivity::Impl::endActivity):
    - nop implementation.
(WebCore::UserActivity::UserActivity):
    - UserActivity maintains existing interface with hysteresis.
(WebCore::UserActivity::started):
(WebCore::UserActivity::stopped):
    - callbacks from HysteresisTimer; forward to Impl.
* platform/UserActivity.h:
* platform/mac/UserActivityMac.mm:
(WebCore::UserActivity::Impl::Impl):
    - UserActivity::Impl, abstraction for NSActivity without added hysteresis.
(WebCore::UserActivity::Impl::beginActivity):
    - allocate NSActivity.
(WebCore::UserActivity::Impl::endActivity):
    - release NSActivity.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (164947 => 164948)


--- trunk/Source/WebCore/ChangeLog	2014-03-02 20:34:51 UTC (rev 164947)
+++ trunk/Source/WebCore/ChangeLog	2014-03-02 20:44:17 UTC (rev 164948)
@@ -1,3 +1,76 @@
+2014-03-01  Gavin Barraclough  <[email protected]>
+
+        Split UserActivity, simplify PageThrottler
+        https://bugs.webkit.org/show_bug.cgi?id=129551
+
+        Reviewed by Darin Adler.
+
+        The class UserActivity currently implements two things – a hysteresis mechanism, and
+        an abstraction of NSActivity controlled by that mechanism. PageThrottler implements
+        its own hysteresis mechanism, which directly controls DOM timer throttling and also
+        controls a couple of UserActivities, giving a total of 3 separate hysteresis mechanisms,
+        layered two deep.
+
+        Split UserActivity into three, with HysteresisActivity implementing an abstract hysteresis
+        mechanism, UserActivity::Impl controlling the NSActivity, and then UserActivity combining
+        these two back together. The interface to UserActivity is unchanged.
+
+        Remove PageThrottler's bespoke hysteresis, replacing it with a use of HysteresisActivity.
+        Replace the two UserActivities with a single UserActivity::Impl, so there are no longer
+        layered hysteresis mechanisms.
+
+        * WebCore.exp.in:
+            - exports changed.
+        * WebCore.xcodeproj/project.pbxproj:
+            - added HysteresisActivity.h.
+        * page/PageThrottler.cpp:
+        (WebCore::PageThrottler::PageThrottler):
+            - if the page starts visible, begin activity. If it starts hidden throttle DOM timers.
+        (WebCore::PageThrottler::hiddenPageDOMTimerThrottlingStateChanged):
+            - when the DOM timer throttling setting changes, make sure we update.
+        (WebCore::PageThrottler::incrementActivityCount):
+        (WebCore::PageThrottler::decrementActivityCount):
+            - when m_activityCount changes update the hysteresis state.
+        (WebCore::PageThrottler::updateHysteresis):
+        (WebCore::PageThrottler::setViewState):
+            - when IsVisuallyIdle changes update the hysteresis state.
+        (WebCore::PageThrottler::started):
+        (WebCore::PageThrottler::stopped):
+            - callbacks from HysteresisActivity, these control m_activity and DOM timer throttling.
+        * page/PageThrottler.h:
+        (WebCore::PageThrottler::didReceiveUserInput):
+        (WebCore::PageThrottler::pluginDidEvaluate):
+            - call impulse to temporarily enable the activity.
+        * platform/HysteresisActivity.h: Copied from Source/WebCore/platform/UserActivity.h.
+        (WebCore::HysteresisActivity::HysteresisActivity):
+            - constructor takes a delegate optionally a timeout.
+        (WebCore::HysteresisActivity::start):
+            - start activity immediately. If stopped, call started method on delegate. If in timeout period, cancel the timer.
+        (WebCore::HysteresisActivity::stop):
+            - stop activity after hysteresis. If started, initiate timeout period.
+        (WebCore::HysteresisActivity::impulse):
+            - ensure activity for at least the timeout period.
+        (WebCore::HysteresisActivity::hysteresisTimerFired):
+            - delayed stop - when the timer fires call stopped on the delegate.
+        * platform/UserActivity.cpp:
+        (WebCore::UserActivity::Impl::Impl):
+        (WebCore::UserActivity::Impl::beginActivity):
+        (WebCore::UserActivity::Impl::endActivity):
+            - nop implementation.
+        (WebCore::UserActivity::UserActivity):
+            - UserActivity maintains existing interface with hysteresis.
+        (WebCore::UserActivity::started):
+        (WebCore::UserActivity::stopped):
+            - callbacks from HysteresisTimer; forward to Impl.
+        * platform/UserActivity.h:
+        * platform/mac/UserActivityMac.mm:
+        (WebCore::UserActivity::Impl::Impl):
+            - UserActivity::Impl, abstraction for NSActivity without added hysteresis.
+        (WebCore::UserActivity::Impl::beginActivity):
+            - allocate NSActivity.
+        (WebCore::UserActivity::Impl::endActivity):
+            - release NSActivity.
+
 2014-03-02  Brian Burg  <[email protected]>
 
         DocumentLoader should keep maps of ResourceLoaders instead of sets

Modified: trunk/Source/WebCore/GNUmakefile.list.am (164947 => 164948)


--- trunk/Source/WebCore/GNUmakefile.list.am	2014-03-02 20:34:51 UTC (rev 164947)
+++ trunk/Source/WebCore/GNUmakefile.list.am	2014-03-02 20:44:17 UTC (rev 164948)
@@ -5491,7 +5491,8 @@
 	Source/WebCore/platform/ThreadGlobalData.cpp \
 	Source/WebCore/platform/ThreadGlobalData.h \
 	Source/WebCore/platform/UserActivity.cpp \
-	Source/WebCore/platform/UserActivity.h
+	Source/WebCore/platform/UserActivity.h \
+	Source/WebCore/platform/HysteresisActivity.h
 
 platform_sources += \
 	Source/WebCore/platform/animation/AnimationUtilities.h \

Modified: trunk/Source/WebCore/WebCore.exp.in (164947 => 164948)


--- trunk/Source/WebCore/WebCore.exp.in	2014-03-02 20:34:51 UTC (rev 164947)
+++ trunk/Source/WebCore/WebCore.exp.in	2014-03-02 20:44:17 UTC (rev 164948)
@@ -240,8 +240,7 @@
 __ZN7WebCore12TextIterator8subrangeEPNS_5RangeEii
 __ZN7WebCore12TextIteratorC1EPKNS_5RangeENS_20TextIteratorBehaviorE
 __ZN7WebCore12TextIteratorD1Ev
-__ZN7WebCore12UserActivity4stopEv
-__ZN7WebCore12UserActivity5startEv
+__ZN7WebCore12UserActivity7startedEv
 __ZN7WebCore12UserActivityC1EPKc
 __ZN7WebCore12UTF8EncodingEv
 __ZN7WebCore12WorkerThread17workerThreadCountEv
@@ -318,8 +317,7 @@
 __ZN7WebCore13NodeTraversal13deepLastChildEPNS_4NodeE
 __ZN7WebCore13NodeTraversal19nextAncestorSiblingEPKNS_4NodeE
 __ZN7WebCore13NodeTraversal19nextAncestorSiblingEPKNS_4NodeES3_
-__ZN7WebCore13PageThrottler22reportInterestingEventEv
-__ZN7WebCore13PageThrottlerD1Ev
+__ZN7WebCore13PageThrottler7startedEv
 __ZN7WebCore13QualifiedNameD1Ev
 __ZN7WebCore13ResourceErrorC1EP7NSError
 __ZN7WebCore13ResourceErrorC1EP9__CFError

Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj (164947 => 164948)


--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj	2014-03-02 20:34:51 UTC (rev 164947)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj	2014-03-02 20:44:17 UTC (rev 164948)
@@ -19002,6 +19002,7 @@
     <ClInclude Include="..\platform\Timer.h" />
     <ClInclude Include="..\platform\TreeShared.h" />
     <ClInclude Include="..\platform\UserActivity.h" />
+    <ClInclude Include="..\platform\HysteresisActivity.h" />
     <ClInclude Include="..\platform\UUID.h" />
     <ClInclude Include="..\platform\Widget.h" />
     <ClInclude Include="..\platform\win\BitmapInfo.h" />

Modified: trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters (164947 => 164948)


--- trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters	2014-03-02 20:34:51 UTC (rev 164947)
+++ trunk/Source/WebCore/WebCore.vcxproj/WebCore.vcxproj.filters	2014-03-02 20:44:17 UTC (rev 164948)
@@ -8120,6 +8120,9 @@
     <ClInclude Include="..\platform\UserActivity.h">
       <Filter>platform</Filter>
     </ClInclude>
+    <ClInclude Include="..\platform\HysteresisActivity.h">
+      <Filter>platform</Filter>
+    </ClInclude>
     <ClInclude Include="..\platform\UUID.h">
       <Filter>platform</Filter>
     </ClInclude>

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (164947 => 164948)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2014-03-02 20:34:51 UTC (rev 164947)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2014-03-02 20:44:17 UTC (rev 164948)
@@ -2937,6 +2937,7 @@
 		861C2EA413FB4FDD00062ABB /* DocumentLoadTiming.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 861C2EA313FB4FDD00062ABB /* DocumentLoadTiming.cpp */; };
 		861C2EA613FB4FFF00062ABB /* ResourceLoadTiming.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 861C2EA513FB4FFF00062ABB /* ResourceLoadTiming.cpp */; };
 		862F129E18C1576F005C54AF /* CountedUserActivity.h in Headers */ = {isa = PBXBuildFile; fileRef = 862F129D18C1572C005C54AF /* CountedUserActivity.h */; settings = {ATTRIBUTES = (Private, ); }; };
+		862F12A018C1DD02005C54AF /* HysteresisActivity.h in Headers */ = {isa = PBXBuildFile; fileRef = 862F129F18C1DCE4005C54AF /* HysteresisActivity.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		86512EDE154A2AEF00A90426 /* PerformanceResourceTiming.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 86512EDB154A2AEE00A90426 /* PerformanceResourceTiming.cpp */; };
 		86512EDF154A2AEF00A90426 /* PerformanceResourceTiming.h in Headers */ = {isa = PBXBuildFile; fileRef = 86512EDC154A2AEF00A90426 /* PerformanceResourceTiming.h */; };
 		8678D0BB1878E891003ABDE6 /* ViewState.h in Headers */ = {isa = PBXBuildFile; fileRef = 8678D0BA1878E810003ABDE6 /* ViewState.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -9840,6 +9841,7 @@
 		861C2EA313FB4FDD00062ABB /* DocumentLoadTiming.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DocumentLoadTiming.cpp; sourceTree = "<group>"; };
 		861C2EA513FB4FFF00062ABB /* ResourceLoadTiming.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ResourceLoadTiming.cpp; sourceTree = "<group>"; };
 		862F129D18C1572C005C54AF /* CountedUserActivity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CountedUserActivity.h; sourceTree = "<group>"; };
+		862F129F18C1DCE4005C54AF /* HysteresisActivity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HysteresisActivity.h; sourceTree = "<group>"; };
 		86512EDB154A2AEE00A90426 /* PerformanceResourceTiming.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PerformanceResourceTiming.cpp; sourceTree = "<group>"; };
 		86512EDC154A2AEF00A90426 /* PerformanceResourceTiming.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PerformanceResourceTiming.h; sourceTree = "<group>"; };
 		86512EDD154A2AEF00A90426 /* PerformanceResourceTiming.idl */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = PerformanceResourceTiming.idl; sourceTree = "<group>"; };
@@ -20730,6 +20732,7 @@
 				D6FDAEF2149C06190037B1E1 /* HistogramSupport.cpp */,
 				D630E2AB149BF344005B2F93 /* HistogramSupport.h */,
 				BC3BC29B0E91AB0F00835588 /* HostWindow.h */,
+				862F129F18C1DCE4005C54AF /* HysteresisActivity.h */,
 				1AE00D57182DAC8D00087DD7 /* KeyedCoding.h */,
 				521D46F711AEC9B100514613 /* KillRing.h */,
 				4306E4E514955543007F17AC /* KillRingNone.cpp */,
@@ -23771,6 +23774,7 @@
 				4415292E0E1AE8A000C4A2D0 /* HTMLPlugInImageElement.h in Headers */,
 				A8EA7CB00A192B9C00A8EF5F /* HTMLPreElement.h in Headers */,
 				977B3873122883E900B81FF8 /* HTMLPreloadScanner.h in Headers */,
+				862F12A018C1DD02005C54AF /* HysteresisActivity.h in Headers */,
 				A43BF5991149290A00C643CA /* HTMLProgressElement.h in Headers */,
 				A8CFF7A30A156978000A4234 /* HTMLQuoteElement.h in Headers */,
 				A8D223FE16B52E4E00157288 /* HTMLResourcePreloader.h in Headers */,

Modified: trunk/Source/WebCore/page/PageThrottler.cpp (164947 => 164948)


--- trunk/Source/WebCore/page/PageThrottler.cpp	2014-03-02 20:34:51 UTC (rev 164947)
+++ trunk/Source/WebCore/page/PageThrottler.cpp	2014-03-02 20:44:17 UTC (rev 164948)
@@ -35,34 +35,25 @@
 
 namespace WebCore {
 
-static const double kThrottleHysteresisSeconds = 2.0;
-
 PageThrottler::PageThrottler(Page& page, ViewState::Flags viewState)
     : m_page(page)
     , m_viewState(viewState)
-    , m_throttleState(PageNotThrottledState)
-    , m_throttleHysteresisTimer(this, &PageThrottler::throttleHysteresisTimerFired)
     , m_weakPtrFactory(this)
+    , m_hysteresis(*this)
+    , m_activity("Page is active.")
     , m_activityCount(0)
-    , m_visuallyNonIdle("Page is not visually idle.")
-    , m_pageActivity("Page is active.")
 {
-    m_pageActivity.increment();
-
-    setIsVisuallyIdle(viewState & ViewState::IsVisuallyIdle);
+    if (m_viewState & ViewState::IsVisuallyIdle)
+        m_page.setTimerThrottlingEnabled(true);
+    else
+        m_hysteresis.start();
 }
 
-PageThrottler::~PageThrottler()
-{
-    m_page.setTimerThrottlingEnabled(false);
-
-    if (m_throttleState != PageThrottledState)
-        m_pageActivity.decrement();
-}
-
 void PageThrottler::hiddenPageDOMTimerThrottlingStateChanged()
 {
-    m_page.setTimerThrottlingEnabled(m_throttleState != PageNotThrottledState);
+    // If timer throttling is enabled, this will temporarily disable it.
+    // After a timeout it will be reenabled, rereading the setting.
+    m_hysteresis.impulse();
 }
 
 std::unique_ptr<PageActivityAssertionToken> PageThrottler::mediaActivityToken()
@@ -75,27 +66,24 @@
     return std::make_unique<PageActivityAssertionToken>(*this);
 }
 
-void PageThrottler::throttlePage()
+void PageThrottler::incrementActivityCount()
 {
-    m_throttleState = PageThrottledState;
-
-    m_pageActivity.decrement();
-
-    m_page.setTimerThrottlingEnabled(true);
+    ++m_activityCount;
+    updateHysteresis();
 }
 
-void PageThrottler::unthrottlePage()
+void PageThrottler::decrementActivityCount()
 {
-    PageThrottleState oldState = m_throttleState;
-    m_throttleState = PageNotThrottledState;
+    --m_activityCount;
+    updateHysteresis();
+}
 
-    if (oldState == PageNotThrottledState)
-        return;
-
-    if (oldState == PageThrottledState)
-        m_pageActivity.increment();
-    
-    m_page.setTimerThrottlingEnabled(false);
+void PageThrottler::updateHysteresis()
+{
+    if (m_activityCount || !(m_viewState & ViewState::IsVisuallyIdle))
+        m_hysteresis.start();
+    else
+        m_hysteresis.stop();
 }
 
 void PageThrottler::setViewState(ViewState::Flags viewState)
@@ -103,88 +91,20 @@
     ViewState::Flags changed = m_viewState ^ viewState;
     m_viewState = viewState;
 
-    if (changed & ViewState::IsVisible)
-        setIsVisible(viewState & ViewState::IsVisible);
     if (changed & ViewState::IsVisuallyIdle)
-        setIsVisuallyIdle(viewState & ViewState::IsVisuallyIdle);
+        updateHysteresis();
 }
 
-void PageThrottler::setIsVisible(bool isVisible)
+void PageThrottler::started()
 {
-    if (isVisible)
-        m_page.setTimerThrottlingEnabled(false);
-    else if (m_throttleState != PageNotThrottledState)
-        m_page.setTimerThrottlingEnabled(true);
+    m_page.setTimerThrottlingEnabled(false);
+    m_activity.beginActivity();
 }
 
-void PageThrottler::setIsVisuallyIdle(bool isVisuallyIdle)
+void PageThrottler::stopped()
 {
-    if (isVisuallyIdle) {
-        m_throttleState = PageWaitingToThrottleState;
-        startThrottleHysteresisTimer();
-        m_visuallyNonIdle.stop();
-    } else {
-        unthrottlePage();
-        stopThrottleHysteresisTimer();
-        m_visuallyNonIdle.start();
-    }
+    m_page.setTimerThrottlingEnabled(true);
+    m_activity.endActivity();
 }
 
-void PageThrottler::stopThrottleHysteresisTimer()
-{
-    m_throttleHysteresisTimer.stop();
 }
-
-void PageThrottler::reportInterestingEvent()
-{
-    if (m_throttleState == PageNotThrottledState)
-        return;
-    if (m_throttleState == PageThrottledState)
-        unthrottlePage();
-    m_throttleState = PageWaitingToThrottleState;
-    startThrottleHysteresisTimer();
-}
-
-void PageThrottler::startThrottleHysteresisTimer()
-{
-    if (m_throttleHysteresisTimer.isActive())
-        m_throttleHysteresisTimer.stop();
-    if (!m_activityCount)
-        m_throttleHysteresisTimer.startOneShot(kThrottleHysteresisSeconds);
-}
-
-void PageThrottler::throttleHysteresisTimerFired(Timer<PageThrottler>&)
-{
-    ASSERT(!m_activityCount);
-    throttlePage();
-}
-
-void PageThrottler::incrementActivityCount()
-{
-    // If we've already got events that block throttling we can return early
-    if (m_activityCount++)
-        return;
-
-    if (m_throttleState == PageNotThrottledState)
-        return;
-
-    if (m_throttleState == PageThrottledState)
-        unthrottlePage();
-
-    m_throttleState = PageWaitingToThrottleState;
-    stopThrottleHysteresisTimer();
-}
-
-void PageThrottler::decrementActivityCount()
-{
-    if (--m_activityCount)
-        return;
-
-    if (m_throttleState == PageNotThrottledState)
-        return;
-
-    ASSERT(m_throttleState == PageWaitingToThrottleState);
-    startThrottleHysteresisTimer();
-}
-
-}

Modified: trunk/Source/WebCore/page/PageThrottler.h (164947 => 164948)


--- trunk/Source/WebCore/page/PageThrottler.h	2014-03-02 20:34:51 UTC (rev 164947)
+++ trunk/Source/WebCore/page/PageThrottler.h	2014-03-02 20:44:17 UTC (rev 164948)
@@ -28,7 +28,7 @@
 
 #include "Timer.h"
 
-#include "CountedUserActivity.h"
+#include "UserActivity.h"
 #include "ViewState.h"
 #include <wtf/HashSet.h>
 #include <wtf/OwnPtr.h>
@@ -43,49 +43,34 @@
 class PageThrottler {
 public:
     PageThrottler(Page&, ViewState::Flags);
-    ~PageThrottler();
 
     void setViewState(ViewState::Flags);
 
-    void didReceiveUserInput() { reportInterestingEvent(); }
-    void pluginDidEvaluate() { reportInterestingEvent(); }
+    void didReceiveUserInput() { m_hysteresis.impulse(); }
+    void pluginDidEvaluate() { m_hysteresis.impulse(); }
     std::unique_ptr<PageActivityAssertionToken> mediaActivityToken();
     std::unique_ptr<PageActivityAssertionToken> pageLoadActivityToken();
 
     void hiddenPageDOMTimerThrottlingStateChanged();
 
 private:
-    enum PageThrottleState {
-        PageNotThrottledState,
-        PageWaitingToThrottleState,
-        PageThrottledState
-    };
-
     friend class PageActivityAssertionToken;
     WeakPtr<PageThrottler> weakPtr() { return m_weakPtrFactory.createWeakPtr(); }
     void incrementActivityCount();
     void decrementActivityCount();
 
-    void reportInterestingEvent();
+    void updateHysteresis();
 
-    void startThrottleHysteresisTimer();
-    void stopThrottleHysteresisTimer();
-    void throttleHysteresisTimerFired(Timer<PageThrottler>&);
+    friend class HysteresisActivity<PageThrottler>;
+    void started();
+    void stopped();
 
-    void throttlePage();
-    void unthrottlePage();
-
-    void setIsVisuallyIdle(bool);
-    void setIsVisible(bool);
-
     Page& m_page;
     ViewState::Flags m_viewState;
-    PageThrottleState m_throttleState;
-    Timer<PageThrottler> m_throttleHysteresisTimer;
     WeakPtrFactory<PageThrottler> m_weakPtrFactory;
+    HysteresisActivity<PageThrottler> m_hysteresis;
+    UserActivity::Impl m_activity;
     size_t m_activityCount;
-    UserActivity m_visuallyNonIdle;
-    CountedUserActivity m_pageActivity;
 };
 
 }

Copied: trunk/Source/WebCore/platform/HysteresisActivity.h (from rev 164913, trunk/Source/WebCore/platform/UserActivity.h) (0 => 164948)


--- trunk/Source/WebCore/platform/HysteresisActivity.h	                        (rev 0)
+++ trunk/Source/WebCore/platform/HysteresisActivity.h	2014-03-02 20:44:17 UTC (rev 164948)
@@ -0,0 +1,90 @@
+/*
+ * Copyright (C) 2014 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HysteresisActivity_h
+#define HysteresisActivity_h
+
+#include <wtf/RunLoop.h>
+
+namespace WebCore {
+
+static const double DefaultHysteresisSeconds = 5.0;
+
+template<typename Delegate>
+class HysteresisActivity {
+public:
+    explicit HysteresisActivity(Delegate& delegate, double hysteresisSeconds = DefaultHysteresisSeconds)
+        : m_delegate(delegate)
+        , m_hysteresisSeconds(hysteresisSeconds)
+        , m_active(false)
+        , m_timer(RunLoop::main(), this, &HysteresisActivity<Delegate>::hysteresisTimerFired)
+    {
+    }
+
+    void start()
+    {
+        if (m_active)
+            return;
+        m_active = true;
+
+        if (m_timer.isActive())
+            m_timer.stop();
+        else
+            m_delegate.started();
+    }
+
+    void stop()
+    {
+        if (!m_active)
+            return;
+        m_active = false;
+
+        m_timer.startOneShot(m_hysteresisSeconds);
+    }
+
+    void impulse()
+    {
+        if (!m_active) {
+            start();
+            stop();
+        }
+    }
+
+private:
+    void hysteresisTimerFired()
+    {
+        m_delegate.stopped();
+        m_timer.stop();
+    }
+
+    Delegate& m_delegate;
+    double m_hysteresisSeconds;
+    bool m_active;
+    RunLoop::Timer<HysteresisActivity> m_timer;
+};
+
+} // namespace WebCore
+
+#endif // HysteresisActivity_h

Modified: trunk/Source/WebCore/platform/UserActivity.cpp (164947 => 164948)


--- trunk/Source/WebCore/platform/UserActivity.cpp	2014-03-02 20:34:51 UTC (rev 164947)
+++ trunk/Source/WebCore/platform/UserActivity.cpp	2014-03-02 20:44:17 UTC (rev 164948)
@@ -30,18 +30,34 @@
 
 #if !HAVE(NS_ACTIVITY)
 
-UserActivity::UserActivity(const char*)
+UserActivity::Impl::Impl(const char*)
 {
 }
 
-void UserActivity::start()
+void UserActivity::Impl::beginActivity()
 {
 }
 
-void UserActivity::stop()
+void UserActivity::Impl::endActivity()
 {
 }
 
 #endif
 
+UserActivity::UserActivity(const char* description)
+    : HysteresisActivity<UserActivity>(*this)
+    , m_impl(description)
+{
+}
+
+void UserActivity::started()
+{
+    m_impl.beginActivity();
+}
+
+void UserActivity::stopped()
+{
+    m_impl.endActivity();
+}
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/UserActivity.h (164947 => 164948)


--- trunk/Source/WebCore/platform/UserActivity.h	2014-03-02 20:34:51 UTC (rev 164947)
+++ trunk/Source/WebCore/platform/UserActivity.h	2014-03-02 20:44:17 UTC (rev 164948)
@@ -26,9 +26,10 @@
 #ifndef UserActivity_h
 #define UserActivity_h
 
+#include "HysteresisActivity.h"
+
 #if HAVE(NS_ACTIVITY)
 #include <wtf/RetainPtr.h>
-#include <wtf/RunLoop.h>
 OBJC_CLASS NSString;
 #endif
 
@@ -37,23 +38,31 @@
 // The UserActivity type is used to indicate to the operating system that
 // a user initiated or visible action is taking place, and as such that
 // resources should be allocated to the process accordingly.
-class UserActivity {
+class UserActivity : public HysteresisActivity<UserActivity> {
 public:
-    UserActivity(const char* description);
+    class Impl {
+    public:
+        explicit Impl(const char* description);
 
-    void start();
-    void stop();
+        void beginActivity();
+        void endActivity();
 
-private:
 #if HAVE(NS_ACTIVITY)
-    void hysteresisTimerFired();
-    bool isValid();
+    private:
+        RetainPtr<id> m_activity;
+        RetainPtr<NSString> m_description;
+#endif
+    };
 
-    bool m_active;
-    RetainPtr<NSString> m_description;
-    RunLoop::Timer<UserActivity> m_timer;
-    RetainPtr<id> m_activity;
-#endif
+    explicit UserActivity(const char* description);
+
+private:
+    friend class HysteresisActivity<UserActivity>;
+
+    void started();
+    void stopped();
+
+    Impl m_impl;
 };
 
 } // namespace WebCore

Modified: trunk/Source/WebCore/platform/mac/UserActivityMac.mm (164947 => 164948)


--- trunk/Source/WebCore/platform/mac/UserActivityMac.mm	2014-03-02 20:34:51 UTC (rev 164947)
+++ trunk/Source/WebCore/platform/mac/UserActivityMac.mm	2014-03-02 20:44:17 UTC (rev 164948)
@@ -30,65 +30,23 @@
 
 #if HAVE(NS_ACTIVITY)
 
-static const double kHysteresisSeconds = 5.0;
-
-UserActivity::UserActivity(const char* description)
-    : m_active(false)
-    , m_description([NSString stringWithUTF8String:description])
-    , m_timer(RunLoop::main(), this, &UserActivity::hysteresisTimerFired)
+UserActivity::Impl::Impl(const char* description)
+    : m_description([NSString stringWithUTF8String:description])
 {
-    ASSERT(isValid());
 }
 
-bool UserActivity::isValid()
+void UserActivity::Impl::beginActivity()
 {
-    // If count is non-zero then we should be holding an activity, and the hysteresis timer should not be running.
-    // Else if count is zero then:
-    //  (a) if we're holding an activity there should be an active timer to clear this,
-    //  (b) if we're not holding an activity there should be no active timer.
-    return m_active ? m_activity && !m_timer.isActive() : !!m_activity == m_timer.isActive();
-}
-
-void UserActivity::start()
-{
-    ASSERT(isValid());
-
-    if (m_active)
-        return;
-    m_active = true;
-
-    if (m_timer.isActive())
-        m_timer.stop();
     if (!m_activity) {
         NSActivityOptions options = (NSActivityUserInitiatedAllowingIdleSystemSleep | NSActivityLatencyCritical) & ~(NSActivitySuddenTerminationDisabled | NSActivityAutomaticTerminationDisabled);
         m_activity = [[NSProcessInfo processInfo] beginActivityWithOptions:options reason:m_description.get()];
     }
-
-    ASSERT(isValid());
 }
 
-void UserActivity::stop()
+void UserActivity::Impl::endActivity()
 {
-    ASSERT(isValid());
-
-    if (!m_active)
-        return;
-    m_active = false;
-
-    m_timer.startOneShot(kHysteresisSeconds);
-
-    ASSERT(isValid());
-}
-
-void UserActivity::hysteresisTimerFired()
-{
-    ASSERT(isValid());
-
     [[NSProcessInfo processInfo] endActivity:m_activity.get()];
     m_activity.clear();
-    m_timer.stop();
-
-    ASSERT(isValid());
 }
 
 #endif
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to