[Webkit-unassigned] [Bug 211956] New: WKWebView: Enable userMedia by using Private API

bugzilla-daemon at webkit.org bugzilla-daemon at webkit.org
Fri May 15 07:43:33 PDT 2020


https://bugs.webkit.org/show_bug.cgi?id=211956

            Bug ID: 211956
           Summary: WKWebView: Enable userMedia by using Private API
           Product: WebKit
           Version: WebKit Local Build
          Hardware: Macintosh
                OS: macOS 10.15
            Status: NEW
          Severity: Normal
          Priority: P2
         Component: WebKit API
          Assignee: webkit-unassigned at lists.webkit.org
          Reporter: emoonadev at gmail.com

I have a WKWebView in my macOS app and I am trying to enable the userMedia. To do this I have to use private API.

I have successfully enabled userMedia in the webview by creating a category in Objective-C:

```
@interface WKPreferences (MyPreferences)
- (void)_setMediaDevicesEnabled:(BOOL)enabled;
- (void)_setMediaStreamEnabled:(BOOL)enabled;
- (void)_setWebRTCLegacyAPIEnabled:(BOOL)enabled;
- (void)_setAVFoundationEnabled:(BOOL)enabled;
- (void)_setMediaSourceEnabled:(BOOL)enabled;

- (void)setMediaDevicesEnabled:(BOOL)enabled;
@end
```
And:
```
@implementation WKPreferences (MyPreferences)

- (void)setMediaDevicesEnabled:(BOOL)enabled {
    [self _setAVFoundationEnabled:enabled];
    [self _setMediaStreamEnabled:enabled];
    [self _setMediaSourceEnabled:enabled];
    [self _setWebRTCLegacyAPIEnabled:enabled];
    [self _setMediaDevicesEnabled:enabled];
}

@end
```
Using in Swift code:

```
webView.configuration.preferences.setMediaDevicesEnabled(true)
```

This code makes webviews appear their icons to record the voice or launch video. In reality just it was enough to enable `(void) _setMediaDevicesEnabled: (BOOL)enabled` but since it does not work entirely so I have to add all the others.

The problem is that when I click in the webview on the record button or start the video, I get this error:

```
[plugin] AddInstanceForFactory: No factory registered for id <CFUUID 0x6000003b14c0> F8BB1C28-BAE8-11D1-9C31-00032314CD45 HALC_ShellDriverPlugIn::Open: Can't get a pointer to the Open routine [] CMIO_DAL_PlugInManagement.cpp:191:Initialize Missing device-camera entitlement
```

I guess I need to implement delegates to be able to request permission and launch the camera or microphone. I found delegates who could be the right ones in the `WKUIDelegatePrivate`

```

- (void)_webView:(WKWebView *)webView requestUserMediaAuthorizationForDevices:(_WKCaptureDevices)devices url:(NSURL *)url mainFrameURL:(NSURL *)mainFrameURL decisionHandler:(void (^)(BOOL authorized))decisionHandler;
- (void)_webView:(WKWebView *)webView checkUserMediaPermissionForURL:(NSURL *)url mainFrameURL:(NSURL *)mainFrameURL frameIdentifier:(NSUInteger)frameIdentifier decisionHandler:(void (^)(NSString *salt, BOOL authorized))decisionHandler;
- (void)_webView:(WKWebView *)webView mediaCaptureStateDidChange:(_WKMediaCaptureState)state;
- (void)_webView:(WKWebView *)arg1 requestMediaCaptureAuthorization:(unsigned long long)arg2 decisionHandler:(void (^)(BOOL))arg3;
```

So I tried to implement them but the delegates are NEVER CALLED. This is my problem: how can I initialize WKUIDelegatePrivate?

The code I tried:

```
@protocol WKUIDelegatePrivate <WKUIDelegate>

- (void)_webView:(WKWebView *)webView requestUserMediaAuthorizationForDevices:(_WKCaptureDevices)devices url:(NSURL *)url mainFrameURL:(NSURL *)mainFrameURL decisionHandler:(void (^)(BOOL authorized))decisionHandler;
- (void)_webView:(WKWebView *)webView checkUserMediaPermissionForURL:(NSURL *)url mainFrameURL:(NSURL *)mainFrameURL frameIdentifier:(NSUInteger)frameIdentifier decisionHandler:(void (^)(NSString *salt, BOOL authorized))decisionHandler;
- (void)_webView:(WKWebView *)webView mediaCaptureStateDidChange:(_WKMediaCaptureState)state;
- (void)_webView:(WKWebView *)arg1 requestMediaCaptureAuthorization:(unsigned long long)arg2 decisionHandler:(void (^)(BOOL))arg3;

- (void)registerDelegate:(WKWebView *)webView;
@end


@interface UserMediaProvider : NSObject <WKUIDelegatePrivate>
@end
```

And:
```
@implementation UserMediaProvider

- (id)init {
    self = [super init];
    if (self) {
    }

    return self;
}

- (void)_webView:(WKWebView *)webView requestUserMediaAuthorizationForDevices:(_WKCaptureDevices)devices url:(NSURL *)url mainFrameURL:(NSURL *)mainFrameURL decisionHandler:(void (^)(BOOL authorized))decisionHandler {
    NSLog(@"AAAAAAAAA");
}

- (void)_webView:(WKWebView *)webView checkUserMediaPermissionForURL:(NSURL *)url mainFrameURL:(NSURL *)mainFrameURL frameIdentifier:(NSUInteger)frameIdentifier decisionHandler:(void (^)(NSString *salt, BOOL authorized))decisionHandler {
    NSLog(@"BBBBBB");
}

- (void)_webView:(WKWebView *)webView mediaCaptureStateDidChange:(_WKMediaCaptureState)state {
    NSLog(@"CCCCCC");
}

- (void)_webView:(WKWebView *)arg1 requestMediaCaptureAuthorization:(unsigned long long)arg2 decisionHandler:(void (^)(BOOL))arg3{
    NSLog(@"PPPPPPP");
}


- (void)registerDelegate:(WKWebView *)webView {
    webView.UIDelegate = self;
}

@end
```

Using from Swift code:

```
webview.registerDelegate(self)
```

I see WKWebView.mm for example that uiDelegatePrivate is cast to UIDelegate when used:

```
id<WKUIDelegatePrivate> uiDelegatePrivate = static_cast<id <WKUIDelegatePrivate>>([self UIDelegate]);
```

Also I can see in UIDelegate.mm That the delegate is called via uidelegate
```

{
    auto delegate = m_uiDelegate.m_delegate.get();
    if (!delegate || !m_uiDelegate.m_delegateMethods.webViewRequestUserMediaAuthorizationForDevicesURLMainFrameURLDecisionHandler) {
        request.deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::UserMediaDisabled); // THIS
        return true;
    }

    bool requiresAudio = request.requiresAudio();
    bool requiresVideo = request.requiresVideo();
    if (!requiresAudio && !requiresVideo) {
        request.deny(UserMediaPermissionRequestProxy::UserMediaAccessDenialReason::NoConstraints);
        return true;
    }
...
```

How can I enable these delegate methods to be called?

I specify that it is for internal application of my company so I do not want the upload to the store

-- 
You are receiving this mail because:
You are the assignee for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.webkit.org/pipermail/webkit-unassigned/attachments/20200515/e76910a5/attachment.htm>


More information about the webkit-unassigned mailing list