⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 267698 in webkit


Ignore:
Timestamp:
Sep 28, 2020, 7:34:46 AM (6 years ago)
Author:
youenn@apple.com
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):

Location:
trunk/Source/WebKit
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit/ChangeLog

    r267691 r267698  
     12020-09-28  Youenn Fablet  <youenn@apple.com>
     2
     3        Make sure our calls to AVCaptureDevice requestAccessForMediaType do processing on the main thread
     4        https://bugs.webkit.org/show_bug.cgi?id=216974
     5
     6        Reviewed by Darin Adler.
     7
     8        The completion handler to [AVCaptureDeviceClass requestAccessForMediaType:] may sometimes be called in a background thread on iOS.
     9        Make sure to hop to the main thread if that is the case.
     10        Also make sure to ref/weakref lambda captured variables.
     11
     12        * UIProcess/Cocoa/UIDelegate.h:
     13        * UIProcess/Cocoa/UIDelegate.mm:
     14        (WebKit::requestAccessForMediaType):
     15        (WebKit::UIDelegate::UIClient::decidePolicyForUserMediaPermissionRequest):
     16
    1172020-09-27  Lauro Moura  <lmoura@igalia.com>
    218
  • trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.h

    r267414 r267698  
    7777#endif
    7878
    79     class UIClient : public API::UIClient {
     79    class UIClient : public API::UIClient, public CanMakeWeakPtr<UIClient> {
    8080    public:
    8181        explicit UIClient(UIDelegate&);
  • trunk/Source/WebKit/UIProcess/Cocoa/UIDelegate.mm

    r267568 r267698  
    940940    [delegate _webView:&webView requestUserMediaAuthorizationForDevices:devices url:requestFrameURL mainFrameURL:mainFrameURL decisionHandler:decisionHandler.get()];
    941941}
     942
     943static void requestAccessForMediaType(CompletionHandler<void(BOOL authorized)>&& completionHandler, AVMediaType type)
     944{
     945    auto decisionHandler = makeBlockPtr([completionHandler = WTFMove(completionHandler)](BOOL authorized) mutable {
     946        if (!isMainThread()) {
     947            callOnMainThread([completionHandler = WTFMove(completionHandler), authorized]() mutable {
     948                completionHandler(authorized);
     949            });
     950            return;
     951        }
     952        completionHandler(authorized);
     953    });
     954    [PAL::getAVCaptureDeviceClass() requestAccessForMediaType:type completionHandler:decisionHandler.get()];
     955}
    942956#endif
    943957
     
    960974
    961975    bool usingMockCaptureDevices = page.preferences().mockCaptureDevicesEnabled();
    962     auto requestCameraAuthorization = makeBlockPtr([this, &frame, protectedRequest = makeRef(request), webView = RetainPtr<WKWebView>(m_uiDelegate.m_webView), topLevelOrigin = makeRef(topLevelOrigin), usingMockCaptureDevices]() mutable {
    963 
     976    auto requestCameraAuthorization = [weakThis = makeWeakPtr(this), frame = makeRef(frame), protectedRequest = makeRef(request), webView = RetainPtr<WKWebView>(m_uiDelegate.m_webView), topLevelOrigin = makeRef(topLevelOrigin), usingMockCaptureDevices]() mutable {
     977        if (!weakThis) {
     978            protectedRequest->deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied);
     979            return;
     980        }
    964981        if (!protectedRequest->requiresVideoCapture()) {
    965             requestUserMediaAuthorizationForFrame(frame, topLevelOrigin, protectedRequest, (id <WKUIDelegatePrivate>)m_uiDelegate.m_delegate.get(), *webView.get());
     982            requestUserMediaAuthorizationForFrame(frame, topLevelOrigin, protectedRequest, (id <WKUIDelegatePrivate>)weakThis->m_uiDelegate.m_delegate.get(), *webView.get());
    966983            return;
    967984        }
     
    969986        switch (cameraAuthorizationStatus) {
    970987        case AVAuthorizationStatusAuthorized:
    971             requestUserMediaAuthorizationForFrame(frame, topLevelOrigin, protectedRequest, (id <WKUIDelegatePrivate>)m_uiDelegate.m_delegate.get(), *webView.get());
     988            requestUserMediaAuthorizationForFrame(frame, topLevelOrigin, protectedRequest, (id <WKUIDelegatePrivate>)weakThis->m_uiDelegate.m_delegate.get(), *webView.get());
    972989            break;
    973990        case AVAuthorizationStatusDenied:
     
    976993            return;
    977994        case AVAuthorizationStatusNotDetermined:
    978             auto decisionHandler = makeBlockPtr([this, &frame, protectedRequest = makeRef(protectedRequest.get()), webView = RetainPtr<WKWebView>(m_uiDelegate.m_webView), topLevelOrigin = WTFMove(topLevelOrigin)](BOOL authorized) {
    979                 if (!authorized) {
     995            auto completionHandler = [weakThis = WTFMove(weakThis), frame = WTFMove(frame), protectedRequest = WTFMove(protectedRequest), webView = WTFMove(webView), topLevelOrigin = WTFMove(topLevelOrigin)](BOOL authorized) {
     996                if (!authorized || !weakThis) {
    980997                    protectedRequest->deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied);
    981998                    return;
    982999                }
    983                 requestUserMediaAuthorizationForFrame(frame, topLevelOrigin, protectedRequest, (id <WKUIDelegatePrivate>)m_uiDelegate.m_delegate.get(), *webView.get());
    984             });
    985 
    986             [PAL::getAVCaptureDeviceClass() requestAccessForMediaType:AVMediaTypeVideo completionHandler:decisionHandler.get()];
     1000                requestUserMediaAuthorizationForFrame(frame, topLevelOrigin, protectedRequest, (id <WKUIDelegatePrivate>)weakThis->m_uiDelegate.m_delegate.get(), *webView.get());
     1001            };
     1002            requestAccessForMediaType(WTFMove(completionHandler), AVMediaTypeVideo);
    9871003            break;
    9881004        }
    989     });
     1005    };
    9901006
    9911007    if (requiresAudioCapture) {
     
    10001016            return;
    10011017        case AVAuthorizationStatusNotDetermined:
    1002             auto decisionHandler = makeBlockPtr([protectedRequest = makeRef(request), requestCameraAuthorization](BOOL authorized) {
     1018            auto completionHandler = [protectedRequest = makeRef(request), requestCameraAuthorization = WTFMove(requestCameraAuthorization)](BOOL authorized) mutable {
    10031019                if (!authorized) {
    10041020                    protectedRequest->deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::PermissionDenied);
     
    10061022                }
    10071023                requestCameraAuthorization();
    1008             });
    1009 
    1010             [PAL::getAVCaptureDeviceClass() requestAccessForMediaType:AVMediaTypeAudio completionHandler:decisionHandler.get()];
     1024            };
     1025            requestAccessForMediaType(WTFMove(completionHandler), AVMediaTypeVideo);
    10111026            break;
    10121027        }
    1013     } else
    1014         requestCameraAuthorization();
     1028        return;
     1029    }
     1030    requestCameraAuthorization();
    10151031#endif
    10161032}
Note: See TracChangeset for help on using the changeset viewer.