- 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