Title: [267698] trunk/Source/WebKit
Revision
267698
Author
[email protected]
Date
2020-09-28 07:34:46 -0700 (Mon, 28 Sep 2020)

Log Message

Make sure our calls to AVCaptureDevice requestAccessForMediaType do processing on the main thread
https://bugs.webkit.org/show_bug.cgi?id=216974

Reviewed by Darin Adler.

The completion handler to [AVCaptureDeviceClass requestAccessForMediaType:] may sometimes be called in a background thread on iOS.
Make sure to hop to the main thread if that is the case.
Also make sure to ref/weakref lambda captured variables.

* UIProcess/Cocoa/UIDelegate.h:
* UIProcess/Cocoa/UIDelegate.mm:
(WebKit::requestAccessForMediaType):
(WebKit::UIDelegate::UIClient::decidePolicyForUserMediaPermissionRequest):

Modified Paths

Diff

Modified: trunk/Source/WebKit/ChangeLog (267697 => 267698)


--- trunk/Source/WebKit/ChangeLog	2020-09-28 13:42:33 UTC (rev 267697)
+++ trunk/Source/WebKit/ChangeLog	2020-09-28 14:34:46 UTC (rev 267698)
@@ -1,3 +1,19 @@
+2020-09-28  Youenn Fablet  <[email protected]>
+
+        Make sure our calls to AVCaptureDevice requestAccessForMediaType do processing on the main thread
+        https://bugs.webkit.org/show_bug.cgi?id=216974
+
+        Reviewed by Darin Adler.
+
+        The completion handler to [AVCaptureDeviceClass requestAccessForMediaType:] may sometimes be called in a background thread on iOS.
+        Make sure to hop to the main thread if that is the case.
+        Also make sure to ref/weakref lambda captured variables.
+
+        * UIProcess/Cocoa/UIDelegate.h:
+        * UIProcess/Cocoa/UIDelegate.mm:
+        (WebKit::requestAccessForMediaType):
+        (WebKit::UIDelegate::UIClient::decidePolicyForUserMediaPermissionRequest):
+
 2020-09-27  Lauro Moura  <[email protected]>
 
         REGRESSION(r267688) [GTK] Many compositing timeouts

Modified: trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.h (267697 => 267698)


--- trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.h	2020-09-28 13:42:33 UTC (rev 267697)
+++ trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.h	2020-09-28 14:34:46 UTC (rev 267698)
@@ -76,7 +76,7 @@
     };
 #endif
 
-    class UIClient : public API::UIClient {
+    class UIClient : public API::UIClient, public CanMakeWeakPtr<UIClient> {
     public:
         explicit UIClient(UIDelegate&);
         ~UIClient();

Modified: trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm (267697 => 267698)


--- trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm	2020-09-28 13:42:33 UTC (rev 267697)
+++ trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm	2020-09-28 14:34:46 UTC (rev 267698)
@@ -939,6 +939,20 @@
 
     [delegate _webView:&webView requestUserMediaAuthorizationForDevices:devices url:requestFrameURL mainFrameURL:mainFrameURL decisionHandler:decisionHandler.get()];
 }
+
+static void requestAccessForMediaType(CompletionHandler<void(BOOL authorized)>&& completionHandler, AVMediaType type)
+{
+    auto decisionHandler = makeBlockPtr([completionHandler = WTFMove(completionHandler)](BOOL authorized) mutable {
+        if (!isMainThread()) {
+            callOnMainThread([completionHandler = WTFMove(completionHandler), authorized]() mutable {
+                completionHandler(authorized);
+            });
+            return;
+        }
+        completionHandler(authorized);
+    });
+    [PAL::getAVCaptureDeviceClass() requestAccessForMediaType:type completionHandler:decisionHandler.get()];
+}
 #endif
 
 void UIDelegate::UIClient::decidePolicyForUserMediaPermissionRequest(WebPageProxy& page, WebFrameProxy& frame, API::SecurityOrigin& userMediaOrigin, API::SecurityOrigin& topLevelOrigin, UserMediaPermissionRequestProxy& request)
@@ -959,16 +973,19 @@
     }
 
     bool usingMockCaptureDevices = page.preferences().mockCaptureDevicesEnabled();
-    auto requestCameraAuthorization = makeBlockPtr([this, &frame, protectedRequest = makeRef(request), webView = RetainPtr<WKWebView>(m_uiDelegate.m_webView), topLevelOrigin = makeRef(topLevelOrigin), usingMockCaptureDevices]() mutable {
-
+    auto requestCameraAuthorization = [weakThis = makeWeakPtr(this), frame = makeRef(frame), protectedRequest = makeRef(request), webView = RetainPtr<WKWebView>(m_uiDelegate.m_webView), topLevelOrigin = makeRef(topLevelOrigin), usingMockCaptureDevices]() mutable {
+        if (!weakThis) {
+            protectedRequest->deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied);
+            return;
+        }
         if (!protectedRequest->requiresVideoCapture()) {
-            requestUserMediaAuthorizationForFrame(frame, topLevelOrigin, protectedRequest, (id <WKUIDelegatePrivate>)m_uiDelegate.m_delegate.get(), *webView.get());
+            requestUserMediaAuthorizationForFrame(frame, topLevelOrigin, protectedRequest, (id <WKUIDelegatePrivate>)weakThis->m_uiDelegate.m_delegate.get(), *webView.get());
             return;
         }
         AVAuthorizationStatus cameraAuthorizationStatus = usingMockCaptureDevices ? AVAuthorizationStatusAuthorized : [PAL::getAVCaptureDeviceClass() authorizationStatusForMediaType:AVMediaTypeVideo];
         switch (cameraAuthorizationStatus) {
         case AVAuthorizationStatusAuthorized:
-            requestUserMediaAuthorizationForFrame(frame, topLevelOrigin, protectedRequest, (id <WKUIDelegatePrivate>)m_uiDelegate.m_delegate.get(), *webView.get());
+            requestUserMediaAuthorizationForFrame(frame, topLevelOrigin, protectedRequest, (id <WKUIDelegatePrivate>)weakThis->m_uiDelegate.m_delegate.get(), *webView.get());
             break;
         case AVAuthorizationStatusDenied:
         case AVAuthorizationStatusRestricted:
@@ -975,18 +992,17 @@
             protectedRequest->deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied);
             return;
         case AVAuthorizationStatusNotDetermined:
-            auto decisionHandler = makeBlockPtr([this, &frame, protectedRequest = makeRef(protectedRequest.get()), webView = RetainPtr<WKWebView>(m_uiDelegate.m_webView), topLevelOrigin = WTFMove(topLevelOrigin)](BOOL authorized) {
-                if (!authorized) {
+            auto completionHandler = [weakThis = WTFMove(weakThis), frame = WTFMove(frame), protectedRequest = WTFMove(protectedRequest), webView = WTFMove(webView), topLevelOrigin = WTFMove(topLevelOrigin)](BOOL authorized) {
+                if (!authorized || !weakThis) {
                     protectedRequest->deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied);
                     return;
                 }
-                requestUserMediaAuthorizationForFrame(frame, topLevelOrigin, protectedRequest, (id <WKUIDelegatePrivate>)m_uiDelegate.m_delegate.get(), *webView.get());
-            });
-
-            [PAL::getAVCaptureDeviceClass() requestAccessForMediaType:AVMediaTypeVideo completionHandler:decisionHandler.get()];
+                requestUserMediaAuthorizationForFrame(frame, topLevelOrigin, protectedRequest, (id <WKUIDelegatePrivate>)weakThis->m_uiDelegate.m_delegate.get(), *webView.get());
+            };
+            requestAccessForMediaType(WTFMove(completionHandler), AVMediaTypeVideo);
             break;
         }
-    });
+    };
 
     if (requiresAudioCapture) {
         AVAuthorizationStatus microphoneAuthorizationStatus = usingMockCaptureDevices ? AVAuthorizationStatusAuthorized : [PAL::getAVCaptureDeviceClass() authorizationStatusForMediaType:AVMediaTypeAudio];
@@ -999,19 +1015,19 @@
             request.deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied);
             return;
         case AVAuthorizationStatusNotDetermined:
-            auto decisionHandler = makeBlockPtr([protectedRequest = makeRef(request), requestCameraAuthorization](BOOL authorized) {
+            auto completionHandler = [protectedRequest = makeRef(request), requestCameraAuthorization = WTFMove(requestCameraAuthorization)](BOOL authorized) mutable {
                 if (!authorized) {
                     protectedRequest->deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied);
                     return;
                 }
                 requestCameraAuthorization();
-            });
-
-            [PAL::getAVCaptureDeviceClass() requestAccessForMediaType:AVMediaTypeAudio completionHandler:decisionHandler.get()];
+            };
+            requestAccessForMediaType(WTFMove(completionHandler), AVMediaTypeVideo);
             break;
         }
-    } else
-        requestCameraAuthorization();
+        return;
+    }
+    requestCameraAuthorization();
 #endif
 }
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to