- Revision
- 202347
- Author
- [email protected]
- Date
- 2016-06-22 13:39:49 -0700 (Wed, 22 Jun 2016)
Log Message
Mail snapshot has black webview in multitasking switcher
https://bugs.webkit.org/show_bug.cgi?id=159036
<rdar://problem/25972938>
Reviewed by Simon Fraser.
There is a window of time between an application going into the background
and SpringBoard's snapshotting mechanism completing where it is possible
(though difficult, timing-wise) for RemoteLayerBackingStoreCollection to
make still-needed surfaces volatile (and, even worse, for them to get emptied).
UIKit suggested instead waiting for the window context teardown notification,
which does indeed seem to fire after the snapshotting is complete.
This may have the convenient side effect of making the volatility timer
repeat fewer times in general, because it is now started closer to the
last time that the surfaces will be in-use.
* UIProcess/ApplicationStateTracker.h:
* UIProcess/ApplicationStateTracker.mm:
(WebKit::ApplicationStateTracker::ApplicationStateTracker):
(WebKit::ApplicationStateTracker::~ApplicationStateTracker):
(WebKit::ApplicationStateTracker::applicationDidFinishSnapshottingAfterEnteringBackground):
* UIProcess/WebPageProxy.h:
* UIProcess/ios/WKContentView.mm:
(-[WKContentView didMoveToWindow]):
(-[WKContentView _applicationDidFinishSnapshottingAfterEnteringBackground]):
* UIProcess/ios/WKPDFView.mm:
(-[WKPDFView didMoveToWindow]):
(-[WKPDFView _applicationDidFinishSnapshottingAfterEnteringBackground]):
* UIProcess/ios/WebPageProxyIOS.mm:
(WebKit::WebPageProxy::applicationDidFinishSnapshottingAfterEnteringBackground):
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:
* WebProcess/WebPage/ios/WebPageIOS.mm:
(WebKit::WebPage::applicationDidEnterBackground):
(WebKit::WebPage::applicationDidFinishSnapshottingAfterEnteringBackground):
Modified Paths
Diff
Modified: trunk/Source/WebKit2/ChangeLog (202346 => 202347)
--- trunk/Source/WebKit2/ChangeLog 2016-06-22 20:38:15 UTC (rev 202346)
+++ trunk/Source/WebKit2/ChangeLog 2016-06-22 20:39:49 UTC (rev 202347)
@@ -1,3 +1,42 @@
+2016-06-22 Tim Horton <[email protected]>
+
+ Mail snapshot has black webview in multitasking switcher
+ https://bugs.webkit.org/show_bug.cgi?id=159036
+ <rdar://problem/25972938>
+
+ Reviewed by Simon Fraser.
+
+ There is a window of time between an application going into the background
+ and SpringBoard's snapshotting mechanism completing where it is possible
+ (though difficult, timing-wise) for RemoteLayerBackingStoreCollection to
+ make still-needed surfaces volatile (and, even worse, for them to get emptied).
+
+ UIKit suggested instead waiting for the window context teardown notification,
+ which does indeed seem to fire after the snapshotting is complete.
+ This may have the convenient side effect of making the volatility timer
+ repeat fewer times in general, because it is now started closer to the
+ last time that the surfaces will be in-use.
+
+ * UIProcess/ApplicationStateTracker.h:
+ * UIProcess/ApplicationStateTracker.mm:
+ (WebKit::ApplicationStateTracker::ApplicationStateTracker):
+ (WebKit::ApplicationStateTracker::~ApplicationStateTracker):
+ (WebKit::ApplicationStateTracker::applicationDidFinishSnapshottingAfterEnteringBackground):
+ * UIProcess/WebPageProxy.h:
+ * UIProcess/ios/WKContentView.mm:
+ (-[WKContentView didMoveToWindow]):
+ (-[WKContentView _applicationDidFinishSnapshottingAfterEnteringBackground]):
+ * UIProcess/ios/WKPDFView.mm:
+ (-[WKPDFView didMoveToWindow]):
+ (-[WKPDFView _applicationDidFinishSnapshottingAfterEnteringBackground]):
+ * UIProcess/ios/WebPageProxyIOS.mm:
+ (WebKit::WebPageProxy::applicationDidFinishSnapshottingAfterEnteringBackground):
+ * WebProcess/WebPage/WebPage.h:
+ * WebProcess/WebPage/WebPage.messages.in:
+ * WebProcess/WebPage/ios/WebPageIOS.mm:
+ (WebKit::WebPage::applicationDidEnterBackground):
+ (WebKit::WebPage::applicationDidFinishSnapshottingAfterEnteringBackground):
+
2016-06-22 Chris Dumez <[email protected]>
Add logging related to process assertions to help debug process suspension issues
Modified: trunk/Source/WebKit2/UIProcess/ApplicationStateTracker.h (202346 => 202347)
--- trunk/Source/WebKit2/UIProcess/ApplicationStateTracker.h 2016-06-22 20:38:15 UTC (rev 202346)
+++ trunk/Source/WebKit2/UIProcess/ApplicationStateTracker.h 2016-06-22 20:39:49 UTC (rev 202347)
@@ -39,7 +39,7 @@
class ApplicationStateTracker {
public:
- ApplicationStateTracker(UIView *, SEL didEnterBackgroundSelector, SEL willEnterForegroundSelector);
+ ApplicationStateTracker(UIView *, SEL didEnterBackgroundSelector, SEL didFinishSnapshottingAfterEnteringBackgroundSelector, SEL willEnterForegroundSelector);
~ApplicationStateTracker();
bool isInBackground() const { return m_isInBackground; }
@@ -46,10 +46,12 @@
private:
void applicationDidEnterBackground();
+ void applicationDidFinishSnapshottingAfterEnteringBackground();
void applicationWillEnterForeground();
WeakObjCPtr<UIView> m_view;
SEL m_didEnterBackgroundSelector;
+ SEL m_didFinishSnapshottingAfterEnteringBackgroundSelector;
SEL m_willEnterForegroundSelector;
bool m_isInBackground;
@@ -59,6 +61,7 @@
RetainPtr<BKSApplicationStateMonitor> m_applicationStateMonitor;
id m_didEnterBackgroundObserver;
+ id m_didFinishSnapshottingAfterEnteringBackgroundObserver;
id m_willEnterForegroundObserver;
};
Modified: trunk/Source/WebKit2/UIProcess/ApplicationStateTracker.mm (202346 => 202347)
--- trunk/Source/WebKit2/UIProcess/ApplicationStateTracker.mm 2016-06-22 20:38:15 UTC (rev 202346)
+++ trunk/Source/WebKit2/UIProcess/ApplicationStateTracker.mm 2016-06-22 20:39:49 UTC (rev 202347)
@@ -73,25 +73,36 @@
}
}
-ApplicationStateTracker::ApplicationStateTracker(UIView *view, SEL didEnterBackgroundSelector, SEL willEnterForegroundSelector)
+ApplicationStateTracker::ApplicationStateTracker(UIView *view, SEL didEnterBackgroundSelector, SEL didFinishSnapshottingAfterEnteringBackgroundSelector, SEL willEnterForegroundSelector)
: m_view(view)
, m_didEnterBackgroundSelector(didEnterBackgroundSelector)
+ , m_didFinishSnapshottingAfterEnteringBackgroundSelector(didFinishSnapshottingAfterEnteringBackgroundSelector)
, m_willEnterForegroundSelector(willEnterForegroundSelector)
, m_isInBackground(true)
, m_weakPtrFactory(this)
, m_didEnterBackgroundObserver(nullptr)
+ , m_didFinishSnapshottingAfterEnteringBackgroundObserver(nullptr)
, m_willEnterForegroundObserver(nullptr)
{
ASSERT([m_view.get() respondsToSelector:m_didEnterBackgroundSelector]);
+ ASSERT([m_view.get() respondsToSelector:m_didFinishSnapshottingAfterEnteringBackgroundSelector]);
ASSERT([m_view.get() respondsToSelector:m_willEnterForegroundSelector]);
UIWindow *window = [m_view.get() window];
ASSERT(window);
+ NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
+ auto weakThis = m_weakPtrFactory.createWeakPtr();
+ m_didFinishSnapshottingAfterEnteringBackgroundObserver = [notificationCenter addObserverForName:@"_UIWindowWillDestroyWindowContextNotification" object:window queue:nil usingBlock:[weakThis](NSNotification *) {
+ auto applicationStateTracker = weakThis.get();
+ if (!applicationStateTracker)
+ return;
+ applicationStateTracker->applicationDidFinishSnapshottingAfterEnteringBackground();
+ }];
+
switch (applicationType(window)) {
case ApplicationType::Application: {
UIApplication *application = [UIApplication sharedApplication];
- NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
m_isInBackground = application.applicationState == UIApplicationStateBackground;
@@ -125,7 +136,6 @@
auto applicationStateMonitor = adoptNS([[BKSApplicationStateMonitor alloc] init]);
m_isInBackground = isBackgroundState([m_applicationStateMonitor mostElevatedApplicationStateForPID:applicationPID]);
- NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
m_didEnterBackgroundObserver = [notificationCenter addObserverForName:@"_UIViewServiceHostDidEnterBackgroundNotification" object:serviceViewController queue:nil usingBlock:[this](NSNotification *) {
applicationDidEnterBackground();
}];
@@ -141,7 +151,6 @@
m_isInBackground = isBackgroundState([m_applicationStateMonitor mostElevatedApplicationStateForPID:getpid()]);
- auto weakThis = m_weakPtrFactory.createWeakPtr();
[m_applicationStateMonitor setHandler:[weakThis](NSDictionary *userInfo) {
pid_t pid = [userInfo[BKSApplicationStateProcessIDKey] integerValue];
if (pid != getpid())
@@ -174,6 +183,7 @@
NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
[notificationCenter removeObserver:m_didEnterBackgroundObserver];
+ [notificationCenter removeObserver:m_didFinishSnapshottingAfterEnteringBackgroundObserver];
[notificationCenter removeObserver:m_willEnterForegroundObserver];
}
@@ -185,6 +195,12 @@
wtfObjcMsgSend<void>(view.get(), m_didEnterBackgroundSelector);
}
+void ApplicationStateTracker::applicationDidFinishSnapshottingAfterEnteringBackground()
+{
+ if (auto view = m_view.get())
+ wtfObjcMsgSend<void>(view.get(), m_didFinishSnapshottingAfterEnteringBackgroundSelector);
+}
+
void ApplicationStateTracker::applicationWillEnterForeground()
{
m_isInBackground = false;
Modified: trunk/Source/WebKit2/UIProcess/WebPageProxy.h (202346 => 202347)
--- trunk/Source/WebKit2/UIProcess/WebPageProxy.h 2016-06-22 20:38:15 UTC (rev 202346)
+++ trunk/Source/WebKit2/UIProcess/WebPageProxy.h 2016-06-22 20:39:49 UTC (rev 202347)
@@ -511,6 +511,7 @@
void setAssistedNodeValueAsNumber(double);
void setAssistedNodeSelectedIndex(uint32_t index, bool allowMultipleSelection = false);
void applicationDidEnterBackground();
+ void applicationDidFinishSnapshottingAfterEnteringBackground();
void applicationWillEnterForeground();
void applicationWillResignActive();
void applicationDidBecomeActive();
Modified: trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm (202346 => 202347)
--- trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm 2016-06-22 20:38:15 UTC (rev 202346)
+++ trunk/Source/WebKit2/UIProcess/ios/WKContentView.mm 2016-06-22 20:39:49 UTC (rev 202347)
@@ -284,7 +284,7 @@
return;
ASSERT(!_applicationStateTracker);
- _applicationStateTracker = std::make_unique<ApplicationStateTracker>(self, @selector(_applicationDidEnterBackground), @selector(_applicationWillEnterForeground));
+ _applicationStateTracker = std::make_unique<ApplicationStateTracker>(self, @selector(_applicationDidEnterBackground), @selector(_applicationDidFinishSnapshottingAfterEnteringBackground), @selector(_applicationWillEnterForeground));
}
- (WKBrowsingContextController *)browsingContextController
@@ -601,6 +601,11 @@
_page->viewStateDidChange(ViewState::AllFlags & ~ViewState::IsInWindow);
}
+- (void)_applicationDidFinishSnapshottingAfterEnteringBackground
+{
+ _page->applicationDidFinishSnapshottingAfterEnteringBackground();
+}
+
- (void)_applicationWillEnterForeground
{
_page->applicationWillEnterForeground();
Modified: trunk/Source/WebKit2/UIProcess/ios/WKPDFView.mm (202346 => 202347)
--- trunk/Source/WebKit2/UIProcess/ios/WKPDFView.mm 2016-06-22 20:38:15 UTC (rev 202346)
+++ trunk/Source/WebKit2/UIProcess/ios/WKPDFView.mm 2016-06-22 20:39:49 UTC (rev 202347)
@@ -864,7 +864,7 @@
return;
ASSERT(!_applicationStateTracker);
- _applicationStateTracker = std::make_unique<ApplicationStateTracker>(self, @selector(_applicationDidEnterBackground), @selector(_applicationWillEnterForeground));
+ _applicationStateTracker = std::make_unique<ApplicationStateTracker>(self, @selector(_applicationDidEnterBackground), @selector(_applicationDidFinishSnapshottingAfterEnteringBackground), @selector(_applicationWillEnterForeground));
}
- (BOOL)isBackground
@@ -881,6 +881,11 @@
_webView->_page->viewStateDidChange(ViewState::AllFlags & ~ViewState::IsInWindow);
}
+- (void)_applicationDidFinishSnapshottingAfterEnteringBackground
+{
+ _webView->_page->applicationDidFinishSnapshottingAfterEnteringBackground();
+}
+
- (void)_applicationWillEnterForeground
{
_webView->_page->applicationWillEnterForeground();
Modified: trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm (202346 => 202347)
--- trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm 2016-06-22 20:38:15 UTC (rev 202346)
+++ trunk/Source/WebKit2/UIProcess/ios/WebPageProxyIOS.mm 2016-06-22 20:39:49 UTC (rev 202347)
@@ -640,6 +640,11 @@
m_process->send(Messages::WebPage::ApplicationDidEnterBackground(isSuspendedUnderLock), m_pageID);
}
+void WebPageProxy::applicationDidFinishSnapshottingAfterEnteringBackground()
+{
+ m_process->send(Messages::WebPage::ApplicationDidFinishSnapshottingAfterEnteringBackground(), m_pageID);
+}
+
void WebPageProxy::applicationWillEnterForeground()
{
bool isSuspendedUnderLock = [UIApp isSuspendedUnderLock];
Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h (202346 => 202347)
--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h 2016-06-22 20:38:15 UTC (rev 202346)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.h 2016-06-22 20:39:49 UTC (rev 202347)
@@ -819,6 +819,7 @@
void willStartUserTriggeredZooming();
void applicationWillResignActive();
void applicationDidEnterBackground(bool isSuspendedUnderLock);
+ void applicationDidFinishSnapshottingAfterEnteringBackground();
void applicationWillEnterForeground(bool isSuspendedUnderLock);
void applicationDidBecomeActive();
void zoomToRect(WebCore::FloatRect, double minimumScale, double maximumScale);
Modified: trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in (202346 => 202347)
--- trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in 2016-06-22 20:38:15 UTC (rev 202346)
+++ trunk/Source/WebKit2/WebProcess/WebPage/WebPage.messages.in 2016-06-22 20:39:49 UTC (rev 202347)
@@ -86,6 +86,7 @@
SetAssistedNodeSelectedIndex(uint32_t index, bool allowMultipleSelection)
ApplicationWillResignActive()
ApplicationDidEnterBackground(bool isSuspendedUnderLock)
+ ApplicationDidFinishSnapshottingAfterEnteringBackground()
ApplicationWillEnterForeground(bool isSuspendedUnderLock)
ApplicationDidBecomeActive()
ContentSizeCategoryDidChange(String contentSizeCategory)
Modified: trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm (202346 => 202347)
--- trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm 2016-06-22 20:38:15 UTC (rev 202346)
+++ trunk/Source/WebKit2/WebProcess/WebPage/ios/WebPageIOS.mm 2016-06-22 20:39:49 UTC (rev 202347)
@@ -2978,6 +2978,10 @@
m_isSuspendedUnderLock = isSuspendedUnderLock;
setLayerTreeStateIsFrozen(true);
+}
+
+void WebPage::applicationDidFinishSnapshottingAfterEnteringBackground()
+{
markLayersVolatile();
}