WebKit Bugzilla
New
Browse
Log In
×
Sign in with GitHub
or
Remember my login
Create Account
·
Forgot Password
Forgotten password account recovery
NEW
211956
WKWebView: Enable userMedia by using Private API
https://bugs.webkit.org/show_bug.cgi?id=211956
Summary
WKWebView: Enable userMedia by using Private API
Mickael
Reported
2020-05-15 07:43:33 PDT
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
Attachments
Add attachment
proposed patch, testcase, etc.
Radar WebKit Bug Importer
Comment 1
2020-05-15 12:22:58 PDT
<
rdar://problem/63284343
>
Mickael
Comment 2
2020-05-16 10:32:10 PDT
The link not work (In reply to Radar WebKit Bug Importer from
comment #1
)
> <
rdar://problem/63284343
>
Note
You need to
log in
before you can comment on or make changes to this bug.
Top of Page
Format For Printing
XML
Clone This Bug