Title: [245896] trunk/Source/WebKit
Revision
245896
Author
[email protected]
Date
2019-05-30 11:39:19 -0700 (Thu, 30 May 2019)

Log Message

[iOS] Third-party extensions using WKWebView are unable to render anything
https://bugs.webkit.org/show_bug.cgi?id=198359
<rdar://problem/51105015>

Reviewed by Brent Fulgham and Geoff Garen.

Third-party extensions using WKWebView are unable to render anything because we do not get notified
when the extension's visibility changes. Because we do not recognize the extension showing the
WebView to be foreground, we do not take a process assertion on behalf of the child processes and
they get suspended before they get a chance to render anything.

The root of the issue is that WebKit was relying on BKSApplicationStateMonitor.handler to get
notified when the extension's state switches between foreground and background. However, the handler
never gets called unless the extension has an appropriate entitlement.

To address the issue, we now use the same logic for extensions and we do for view services.
I have verified that the _UIViewServiceHostDidEnterBackgroundNotification / _UIViewServiceHostWillEnterForegroundNotification
notifications get sent to the extensions (even third-party). We also properly detect MobileSafari as
host application and are able to get MobileSafari's foreground state accurately.

* UIProcess/ApplicationStateTracker.mm:

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (245895 => 245896)


--- trunk/Source/WebKit/ChangeLog	2019-05-30 18:06:09 UTC (rev 245895)
+++ trunk/Source/WebKit/ChangeLog	2019-05-30 18:39:19 UTC (rev 245896)
@@ -1,3 +1,27 @@
+2019-05-30  Chris Dumez  <[email protected]>
+
+        [iOS] Third-party extensions using WKWebView are unable to render anything
+        https://bugs.webkit.org/show_bug.cgi?id=198359
+        <rdar://problem/51105015>
+
+        Reviewed by Brent Fulgham and Geoff Garen.
+
+        Third-party extensions using WKWebView are unable to render anything because we do not get notified
+        when the extension's visibility changes. Because we do not recognize the extension showing the
+        WebView to be foreground, we do not take a process assertion on behalf of the child processes and
+        they get suspended before they get a chance to render anything.
+
+        The root of the issue is that WebKit was relying on BKSApplicationStateMonitor.handler to get
+        notified when the extension's state switches between foreground and background. However, the handler
+        never gets called unless the extension has an appropriate entitlement.
+
+        To address the issue, we now use the same logic for extensions and we do for view services.
+        I have verified that the _UIViewServiceHostDidEnterBackgroundNotification / _UIViewServiceHostWillEnterForegroundNotification
+        notifications get sent to the extensions (even third-party). We also properly detect MobileSafari as
+        host application and are able to get MobileSafari's foreground state accurately.
+
+        * UIProcess/ApplicationStateTracker.mm:
+
 2019-05-30  Wenson Hsieh  <[email protected]>
 
         Rare crash under `WebPage::shouldIgnoreMetaViewport const` when shrinking to fit content

Modified: trunk/Source/WebKit/UIProcess/ApplicationStateTracker.mm (245895 => 245896)


--- trunk/Source/WebKit/UIProcess/ApplicationStateTracker.mm	2019-05-30 18:06:09 UTC (rev 245895)
+++ trunk/Source/WebKit/UIProcess/ApplicationStateTracker.mm	2019-05-30 18:39:19 UTC (rev 245896)
@@ -29,6 +29,7 @@
 #if PLATFORM(IOS_FAMILY)
 
 #import "AssertionServicesSPI.h"
+#import "Logging.h"
 #import "SandboxUtilities.h"
 #import "UIKitSPI.h"
 #import <wtf/ObjCRuntimeExtras.h>
@@ -123,6 +124,7 @@
         break;
     }
 
+    case ApplicationType::Extension:
     case ApplicationType::ViewService: {
         UIViewController *serviceViewController = nil;
 
@@ -150,42 +152,20 @@
         if ([serviceViewController._hostApplicationBundleIdentifier isEqualToString:@"com.apple.ios.StoreKitUIService"])
             m_isInBackground = false;
 
-        m_didEnterBackgroundObserver = [notificationCenter addObserverForName:@"_UIViewServiceHostDidEnterBackgroundNotification" object:serviceViewController queue:nil usingBlock:[this](NSNotification *) {
+        RELEASE_LOG(ProcessSuspension, "%{public}s has PID %d, host application PID: %d, isInBackground: %d", _UIApplicationIsExtension() ? "Extension" : "ViewService", getpid(), applicationPID, m_isInBackground);
+
+        m_didEnterBackgroundObserver = [notificationCenter addObserverForName:@"_UIViewServiceHostDidEnterBackgroundNotification" object:serviceViewController queue:nil usingBlock:[this, applicationPID](NSNotification *) {
+            RELEASE_LOG(ProcessSuspension, "%{public}s has PID %d, host application PID: %d, didEnterBackground", _UIApplicationIsExtension() ? "Extension" : "ViewService", getpid(), applicationPID);
             applicationDidEnterBackground();
         }];
-        m_willEnterForegroundObserver = [notificationCenter addObserverForName:@"_UIViewServiceHostWillEnterForegroundNotification" object:serviceViewController queue:nil usingBlock:[this](NSNotification *) {
+        m_willEnterForegroundObserver = [notificationCenter addObserverForName:@"_UIViewServiceHostWillEnterForegroundNotification" object:serviceViewController queue:nil usingBlock:[this, applicationPID](NSNotification *) {
+            RELEASE_LOG(ProcessSuspension, "%{public}s has PID %d, host application PID: %d, willEnterForeground", _UIApplicationIsExtension() ? "Extension" : "ViewService", getpid(), applicationPID);
             applicationWillEnterForeground();
         }];
 
         break;
     }
-
-    case ApplicationType::Extension: {
-        m_applicationStateMonitor = adoptNS([[BKSApplicationStateMonitor alloc] init]);
-
-        m_isInBackground = isBackgroundState([m_applicationStateMonitor mostElevatedApplicationStateForPID:getpid()]);
-
-        [m_applicationStateMonitor setHandler:[weakThis](NSDictionary *userInfo) {
-            pid_t pid = [userInfo[BKSApplicationStateProcessIDKey] integerValue];
-            if (pid != getpid())
-                return;
-
-            BKSApplicationState newState = (BKSApplicationState)[userInfo[BKSApplicationStateMostElevatedStateForProcessIDKey] unsignedIntValue];
-            bool newInBackground = isBackgroundState(newState);
-
-            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();
-            });
-        }];
     }
-    }
 }
 
 ApplicationStateTracker::~ApplicationStateTracker()
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to