diff --git a/README.md b/README.md index 3e71ebe7..509a5166 100644 --- a/README.md +++ b/README.md @@ -468,6 +468,16 @@ The `retryPredicate` is part of `HCaptchaConfig` that may get persist during app So pay attention to this aspect and make sure that `retryPredicate` is serializable to avoid `android.os.BadParcelableException` in run-time. +### Camera Permission + +Challenges that use the camera require the host app to declare and request the `CAMERA` permission at runtime (Android 6.0+): + +```xml + +``` + +Requires Android 5.0+ (API 21). + ### User Journeys (Enterprise) You can optionally enable user journeys to send recent interaction events alongside your verification request. diff --git a/example-app/src/main/AndroidManifest.xml b/example-app/src/main/AndroidManifest.xml index eb1f08ab..63dc7cba 100644 --- a/example-app/src/main/AndroidManifest.xml +++ b/example-app/src/main/AndroidManifest.xml @@ -1,6 +1,11 @@ + + + + + + = Build.VERSION_CODES.JELLY_BEAN_MR1) { + // Allow media playback to start without a user gesture. + settings.setMediaPlaybackRequiresUserGesture(false); + } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { webView.setWebViewClient(new HCaptchaWebClient(handler)); } @@ -260,5 +265,29 @@ public boolean onConsoleMessage(ConsoleMessage consoleMessage) { public void onProgressChanged(WebView view, int newProgress) { HCaptchaLog.d("[webview] onProgressChanged %d%%", newProgress); } + + @Override + @RequiresApi(Build.VERSION_CODES.LOLLIPOP) + public void onPermissionRequest(final PermissionRequest request) { + // Grant only the requested capture resource; audio is never requested, which + // avoids forcing host apps to declare RECORD_AUDIO. + boolean wantsCapture = false; + for (final String resource : request.getResources()) { + if (PermissionRequest.RESOURCE_VIDEO_CAPTURE.equals(resource)) { + wantsCapture = true; + break; + } + } + if (wantsCapture) { + // The requested surface only composites on a hardware layer; the default + // software layer (disableHardwareAcceleration) would render it blank. + webView.setLayerType(View.LAYER_TYPE_HARDWARE, null); + request.grant(new String[]{PermissionRequest.RESOURCE_VIDEO_CAPTURE}); + HCaptchaLog.d("[webview] onPermissionRequest granted"); + } else { + request.deny(); + HCaptchaLog.d("[webview] onPermissionRequest denied"); + } + } } }