Skip to content
This repository has been archived by the owner on Jan 10, 2024. It is now read-only.

How to implement onPermissionRequest() ? #78

Open
TemaSM opened this issue May 21, 2020 · 4 comments
Open

How to implement onPermissionRequest() ? #78

TemaSM opened this issue May 21, 2020 · 4 comments

Comments

@TemaSM
Copy link

TemaSM commented May 21, 2020

Hi, thanks for your NS plugin, it's awesome! 👏

I'm trying to implement:
WebChromeClient#onPermissionRequest(android.webkit.PermissionRequest) (link to android docs)
to simply grant access to microphone and camera into WebView, but with no success 😢

Here's my code snippet (WebViewExt's loadStarted event handler):

let webview = null

// loadStarted event handler
webviewLoadStarted(args) {
  if (!webview) webview = args.object

  // Variant #1
  // extend original WebChromeClient by settings custom `onPermissionRequest()`
  let CustomWebChromeClient = new global.android.webkit.WebChromeClient.extend({
    onPermissionRequest: function (request) {
      // console.log('onPermissionRequest()')
      request.grant(request.getResources())
    }
  })
  webview.nativeViewProtected.setWebChromeClient(new CustomWebChromeClient())
  
  // Variant #2
  // directly modify `chromeClient's `onPermissionRequest()` function to handle `grant()`
  webview.nativeViewProtected.chromeClient.onPermissionRequest = function (request) {
    // console.log('onPermissionRequest()')
    request.grant(request.getResources())
  }
}

As you can see, I tried with two different variants, but no one works.
Important notice - I've already added required permissions to my AndroidManifest.xml and check & request these permissions during app runtime (before WebView loaded):

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MICROPHONE" />

<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature android:name="android.hardware.camera2.full" />
<uses-feature android:name="android.hardware.camera2.autofocus" />
<uses-feature android:name="android.hardware.audio.low_latency" />
<uses-feature android:name="android.hardware.audio.pro" />
<uses-feature android:name="android.hardware.microphone"/>

JS script loaded on page in WebView, still cannot enumerate devices by calling navigator.mediaDevices.getUserMedia(), but prototyped native Android app can get access to these devices.
Where am I wrong?

Hope for your quick reply and thanks in advance 😃

@m-abs
Copy link
Contributor

m-abs commented May 22, 2020

Varient 1 will probably break some of the minor features in the plugin. fullscreen, alerts, console etc.

I don't Variant 2 can work, unless the function is already defined in the JavaScript layer. The android runtime creates a Java wrapper at compile time.

I haven't tried to setup permissions like that in the webview, but I'll see what I can do.

@m-abs
Copy link
Contributor

m-abs commented May 23, 2020

I think, I've solved it on Android, but I need you to test it and if the test is successful, I need a teammate to review the code. This might take a while since, we're working on a new project.

Install @nota/[email protected]

You also need to install nativescript-permissions for this to work and add an requestPermissionsEvent.
We don't want to depend on the nativescript-permissions, as it is a limited use-case.

    webview.on(WebViewExt.requestPermissionsEvent, (args: RequestPermissionsEventData) => {
        const wantedPerssions = args.permissions
            .map((p) => {
                if (p === "RECORD_AUDIO") {
                    return android.Manifest.permission.RECORD_AUDIO;
                }

                if (p === "CAMERA") {
                    return android.Manifest.permission.CAMERA;
                }

                return p;
            })
            .filter((p) => !!p);

        permissions
            .requestPermissions(wantedPerssions)
            .then(() => args.callback(true))
            .catch(() => args.callback(false));
     });

@m-abs
Copy link
Contributor

m-abs commented May 23, 2020

According to https://bugs.webkit.org/show_bug.cgi?id=188360 we cannot add support on iOS because WKWebView doesn't support it.

@farfromrefug
Copy link

@m-abs could you add it in 8.0.0 ? i have the need for it on android

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants