Title: [186523] trunk/Source/WebKit2
Revision
186523
Author
ander...@apple.com
Date
2015-07-08 13:36:09 -0700 (Wed, 08 Jul 2015)

Log Message

Make ApplicationStateTracker be per view instead of being a singleton
https://bugs.webkit.org/show_bug.cgi?id=146737

Reviewed by Andreas Kling.

* UIProcess/ApplicationStateTracker.h:
Update to be per view instead of a singleton.

* UIProcess/ApplicationStateTracker.mm:
(WebKit::ApplicationStateTracker::ApplicationStateTracker):
Change to take a view + selectors.

(WebKit::ApplicationStateTracker::~ApplicationStateTracker):
Invalidate the state monitor and remove the listeners.

(WebKit::ApplicationStateTracker::applicationDidEnterBackground):
Just call the single background method.

(WebKit::ApplicationStateTracker::applicationWillEnterForeground):
Just call the single foreground method.

(WebKit::ApplicationStateTracker::singleton): Deleted.
(WebKit::ApplicationStateTracker::addListener): Deleted.
(WebKit::ApplicationStateTracker::invokeListeners): Deleted.
(WebKit::ApplicationStateTracker::pruneListeners): Deleted.

* UIProcess/ios/WKContentView.mm:
(-[WKContentView _commonInitializationWithProcessPool:configuration:]):
Create the ApplicationStateTracker here.

(-[WKContentView isBackground]):
Get the ivar instead of the singleton.

Modified Paths

Diff

Modified: trunk/Source/WebKit2/ChangeLog (186522 => 186523)


--- trunk/Source/WebKit2/ChangeLog	2015-07-08 20:20:09 UTC (rev 186522)
+++ trunk/Source/WebKit2/ChangeLog	2015-07-08 20:36:09 UTC (rev 186523)
@@ -1,3 +1,38 @@
+2015-07-08  Anders Carlsson  <ander...@apple.com>
+
+        Make ApplicationStateTracker be per view instead of being a singleton
+        https://bugs.webkit.org/show_bug.cgi?id=146737
+
+        Reviewed by Andreas Kling.
+
+        * UIProcess/ApplicationStateTracker.h:
+        Update to be per view instead of a singleton.
+
+        * UIProcess/ApplicationStateTracker.mm:
+        (WebKit::ApplicationStateTracker::ApplicationStateTracker):
+        Change to take a view + selectors.
+
+        (WebKit::ApplicationStateTracker::~ApplicationStateTracker):
+        Invalidate the state monitor and remove the listeners.
+
+        (WebKit::ApplicationStateTracker::applicationDidEnterBackground):
+        Just call the single background method.
+
+        (WebKit::ApplicationStateTracker::applicationWillEnterForeground):
+        Just call the single foreground method.
+
+        (WebKit::ApplicationStateTracker::singleton): Deleted.
+        (WebKit::ApplicationStateTracker::addListener): Deleted.
+        (WebKit::ApplicationStateTracker::invokeListeners): Deleted.
+        (WebKit::ApplicationStateTracker::pruneListeners): Deleted.
+
+        * UIProcess/ios/WKContentView.mm:
+        (-[WKContentView _commonInitializationWithProcessPool:configuration:]):
+        Create the ApplicationStateTracker here.
+
+        (-[WKContentView isBackground]):
+        Get the ivar instead of the singleton.
+
 2015-07-08  Beth Dakin  <bda...@apple.com>
 
         InteractionInformationAtPosition bounds seem wrong on many sites, affects 

Modified: trunk/Source/WebKit2/Platform/spi/ios/AssertionServicesSPI.h (186522 => 186523)


--- trunk/Source/WebKit2/Platform/spi/ios/AssertionServicesSPI.h	2015-07-08 20:20:09 UTC (rev 186522)
+++ trunk/Source/WebKit2/Platform/spi/ios/AssertionServicesSPI.h	2015-07-08 20:36:09 UTC (rev 186523)
@@ -53,6 +53,7 @@
 @property (nonatomic, copy) BKSApplicationStateChangedHandler handler;
 
 - (BKSApplicationState)mostElevatedApplicationStateForPID:(pid_t)pid;
+- (void)invalidate;
 
 @end
 

Modified: trunk/Source/WebKit2/UIProcess/ApplicationStateTracker.h (186522 => 186523)


--- trunk/Source/WebKit2/UIProcess/ApplicationStateTracker.h	2015-07-08 20:20:09 UTC (rev 186522)
+++ trunk/Source/WebKit2/UIProcess/ApplicationStateTracker.h	2015-07-08 20:36:09 UTC (rev 186523)
@@ -30,40 +30,36 @@
 
 #import "WeakObjCPtr.h"
 #import <wtf/Forward.h>
-#import <wtf/Vector.h>
+#import <wtf/WeakPtr.h>
 
+OBJC_CLASS BKSApplicationStateMonitor;
+OBJC_CLASS UIView;
+
 namespace WebKit {
 
 class ApplicationStateTracker {
-    friend NeverDestroyed<ApplicationStateTracker>;
-
 public:
-    static ApplicationStateTracker& singleton();
+    ApplicationStateTracker(UIView *, SEL didEnterBackgroundSelector, SEL willEnterForegroundSelector);
+    ~ApplicationStateTracker();
 
     bool isInBackground() const { return m_isInBackground; }
 
-    void addListener(id, SEL willEnterForegroundSelector, SEL didEnterBackgroundSelector);
-
 private:
-    ApplicationStateTracker();
-    ~ApplicationStateTracker() = delete;
-
     void applicationDidEnterBackground();
     void applicationWillEnterForeground();
 
-    struct Listener;
+    WeakObjCPtr<UIView> m_view;
+    SEL m_didEnterBackgroundSelector;
+    SEL m_willEnterForegroundSelector;
 
-    void invokeListeners(SEL Listener::*);
-    void pruneListeners();
-
     bool m_isInBackground;
 
-    struct Listener {
-        WeakObjCPtr<id> object;
-        SEL didEnterBackgroundSelector;
-        SEL willEnterForegroundSelector;
-    };
-    Vector<Listener> m_listeners;
+    WeakPtrFactory<ApplicationStateTracker> m_weakPtrFactory;
+
+    RetainPtr<BKSApplicationStateMonitor> m_applicationStateMonitor;
+
+    id m_didEnterBackgroundObserver;
+    id m_willEnterForegroundObserver;
 };
 
 }

Modified: trunk/Source/WebKit2/UIProcess/ApplicationStateTracker.mm (186522 => 186523)


--- trunk/Source/WebKit2/UIProcess/ApplicationStateTracker.mm	2015-07-08 20:20:09 UTC (rev 186522)
+++ trunk/Source/WebKit2/UIProcess/ApplicationStateTracker.mm	2015-07-08 20:36:09 UTC (rev 186523)
@@ -37,13 +37,6 @@
 
 namespace WebKit {
 
-ApplicationStateTracker& ApplicationStateTracker::singleton()
-{
-    static NeverDestroyed<ApplicationStateTracker> applicationStateTracker;
-
-    return applicationStateTracker;
-}
-
 static bool hasEntitlement(NSString *entitlement)
 {
 #if PLATFORM(IOS_SIMULATOR)
@@ -88,14 +81,24 @@
     }
 }
 
-ApplicationStateTracker::ApplicationStateTracker()
+ApplicationStateTracker::ApplicationStateTracker(UIView *view, SEL didEnterBackgroundSelector, SEL willEnterForegroundSelector)
+    : m_view(view)
+    , m_didEnterBackgroundSelector(didEnterBackgroundSelector)
+    , m_willEnterForegroundSelector(willEnterForegroundSelector)
+    , m_weakPtrFactory(this)
+    , m_didEnterBackgroundObserver(nullptr)
+    , m_willEnterForegroundObserver(nullptr)
 {
+    ASSERT([m_view.get() respondsToSelector:m_didEnterBackgroundSelector]);
+    ASSERT([m_view.get() respondsToSelector:m_willEnterForegroundSelector]);
+
     if (isViewService()) {
-        BKSApplicationStateMonitor *applicationStateMonitor = [[BKSApplicationStateMonitor alloc] init];
+        m_applicationStateMonitor = adoptNS([[BKSApplicationStateMonitor alloc] init]);
 
-        m_isInBackground = isBackgroundState([applicationStateMonitor mostElevatedApplicationStateForPID:getpid()]);
+        m_isInBackground = isBackgroundState([m_applicationStateMonitor mostElevatedApplicationStateForPID:getpid()]);
 
-        applicationStateMonitor.handler = [this](NSDictionary *userInfo) {
+        auto weakThis = m_weakPtrFactory.createWeakPtr();
+        [m_applicationStateMonitor setHandler:[weakThis](NSDictionary *userInfo) {
             pid_t pid = [userInfo[BKSApplicationStateProcessIDKey] integerValue];
             if (pid != getpid())
                 return;
@@ -103,82 +106,62 @@
             BKSApplicationState newState = (BKSApplicationState)[userInfo[BKSApplicationStateMostElevatedStateForProcessIDKey] unsignedIntValue];
             bool newInBackground = isBackgroundState(newState);
 
-            dispatch_async(dispatch_get_main_queue(), [this, newInBackground] {
-                if (!m_isInBackground && newInBackground)
-                    applicationDidEnterBackground();
-                else if (m_isInBackground && !newInBackground)
-                    applicationWillEnterForeground();
+            dispatch_async(dispatch_get_main_queue(), [weakThis, newInBackground] {
+                auto applicationStateTracker = weakThis.get();
+                if (!applicationStateTracker)
+                    return;
+
+                if (!applicationStateTracker->m_isInBackground && newInBackground)
+                    applicationStateTracker->applicationDidEnterBackground();
+                else if (applicationStateTracker->m_isInBackground && !newInBackground)
+                    applicationStateTracker->applicationWillEnterForeground();
             });
-        };
+        }];
     } else {
         UIApplication *application = [UIApplication sharedApplication];
         NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
 
         m_isInBackground = application.applicationState == UIApplicationStateBackground;
 
-        [notificationCenter addObserverForName:UIApplicationDidEnterBackgroundNotification object:application queue:nil usingBlock:[this](NSNotification *) {
+        m_didEnterBackgroundObserver = [notificationCenter addObserverForName:UIApplicationDidEnterBackgroundNotification object:application queue:nil usingBlock:[this](NSNotification *) {
             applicationDidEnterBackground();
         }];
 
-        [notificationCenter addObserverForName:UIApplicationWillEnterForegroundNotification object:application queue:nil usingBlock:[this](NSNotification *) {
+        m_willEnterForegroundObserver = [notificationCenter addObserverForName:UIApplicationWillEnterForegroundNotification object:application queue:nil usingBlock:[this](NSNotification *) {
             applicationWillEnterForeground();
         }];
+
     }
 }
 
-void ApplicationStateTracker::addListener(id object, SEL willEnterForegroundSelector, SEL didEnterBackgroundSelector)
+ApplicationStateTracker::~ApplicationStateTracker()
 {
-    ASSERT([object respondsToSelector:willEnterForegroundSelector]);
-    ASSERT([object respondsToSelector:didEnterBackgroundSelector]);
+    if (m_applicationStateMonitor) {
+        [m_applicationStateMonitor invalidate];
+        return;
+    }
 
-    m_listeners.append({ object, willEnterForegroundSelector, didEnterBackgroundSelector });
+    NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
+    [notificationCenter removeObserver:m_didEnterBackgroundObserver];
+    [notificationCenter removeObserver:m_willEnterForegroundObserver];
 }
 
 void ApplicationStateTracker::applicationDidEnterBackground()
 {
     m_isInBackground = true;
 
-    invokeListeners(&Listener::didEnterBackgroundSelector);
+    if (auto view = m_view.get())
+        wtfObjcMsgSend<void>(view.get(), m_didEnterBackgroundSelector);
 }
 
 void ApplicationStateTracker::applicationWillEnterForeground()
 {
     m_isInBackground = false;
 
-    invokeListeners(&Listener::willEnterForegroundSelector);
+    if (auto view = m_view.get())
+        wtfObjcMsgSend<void>(view.get(), m_willEnterForegroundSelector);
 }
 
-void ApplicationStateTracker::invokeListeners(SEL Listener::* selector)
-{
-    bool shouldPruneListeners = false;
-
-    for (auto& listener : m_listeners) {
-        auto object = listener.object.get();
-        if (!object) {
-            shouldPruneListeners = true;
-            continue;
-        }
-
-        wtfObjcMsgSend<void>(object.get(), listener.*selector);
-    }
-
-    if (shouldPruneListeners)
-        pruneListeners();
 }
 
-void ApplicationStateTracker::pruneListeners()
-{
-    auto listeners = WTF::move(m_listeners);
-    ASSERT(m_listeners.isEmpty());
-
-    for (auto& listener : listeners) {
-        if (!listener.object)
-            continue;
-
-        m_listeners.append(WTF::move(listener));
-    }
-}
-
-}
-
 #endif

Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm (186522 => 186523)


--- trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm	2015-07-08 20:20:09 UTC (rev 186522)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm	2015-07-08 20:36:09 UTC (rev 186523)
@@ -177,6 +177,8 @@
     HistoricalVelocityData _historicalKinematicData;
 
     RetainPtr<NSUndoManager> _undoManager;
+
+    std::unique_ptr<ApplicationStateTracker> _applicationStateTracker;
 }
 
 - (instancetype)_commonInitializationWithProcessPool:(WebKit::WebProcessPool&)processPool configuration:(WebKit::WebPageConfiguration)webPageConfiguration
@@ -210,7 +212,7 @@
 
     self.layer.hitTestsAsOpaque = YES;
 
-    ApplicationStateTracker::singleton().addListener(self, @selector(_applicationDidEnterBackground), @selector(_applicationWillEnterForeground));
+    _applicationStateTracker = std::make_unique<ApplicationStateTracker>(self, @selector(_applicationDidEnterBackground), @selector(_applicationWillEnterForeground));
 
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_applicationWillResignActive:) name:UIApplicationWillResignActiveNotification object:[UIApplication sharedApplication]];
     [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(_applicationDidBecomeActive:) name:UIApplicationDidBecomeActiveNotification object:[UIApplication sharedApplication]];
@@ -305,7 +307,7 @@
 
 - (BOOL)isBackground
 {
-    return ApplicationStateTracker::singleton().isInBackground();
+    return _applicationStateTracker->isInBackground();
 }
 
 - (void)_showInspectorHighlight:(const WebCore::Highlight&)highlight
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to