blob: 7d60e0fffa5c91847f94ef34dd7e2e60a3a2494f [file] [log] [blame]
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package io.flutter.plugins.camera;
import android.Manifest;
import android.Manifest.permission;
import android.app.Activity;
import android.content.pm.PackageManager;
import androidx.annotation.VisibleForTesting;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
final class CameraPermissions {
interface PermissionsRegistry {
@SuppressWarnings("deprecation")
void addListener(
io.flutter.plugin.common.PluginRegistry.RequestPermissionsResultListener handler);
}
interface ResultCallback {
void onResult(String errorCode, String errorDescription);
}
private static final int CAMERA_REQUEST_ID = 9796;
private boolean ongoing = false;
void requestPermissions(
Activity activity,
PermissionsRegistry permissionsRegistry,
boolean enableAudio,
ResultCallback callback) {
if (ongoing) {
callback.onResult("cameraPermission", "Camera permission request ongoing");
}
if (!hasCameraPermission(activity) || (enableAudio && !hasAudioPermission(activity))) {
permissionsRegistry.addListener(
new CameraRequestPermissionsListener(
(String errorCode, String errorDescription) -> {
ongoing = false;
callback.onResult(errorCode, errorDescription);
}));
ongoing = true;
ActivityCompat.requestPermissions(
activity,
enableAudio
? new String[] {Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO}
: new String[] {Manifest.permission.CAMERA},
CAMERA_REQUEST_ID);
} else {
// Permissions already exist. Call the callback with success.
callback.onResult(null, null);
}
}
private boolean hasCameraPermission(Activity activity) {
return ContextCompat.checkSelfPermission(activity, permission.CAMERA)
== PackageManager.PERMISSION_GRANTED;
}
private boolean hasAudioPermission(Activity activity) {
return ContextCompat.checkSelfPermission(activity, permission.RECORD_AUDIO)
== PackageManager.PERMISSION_GRANTED;
}
@VisibleForTesting
@SuppressWarnings("deprecation")
static final class CameraRequestPermissionsListener
implements io.flutter.plugin.common.PluginRegistry.RequestPermissionsResultListener {
// There's no way to unregister permission listeners in the v1 embedding, so we'll be called
// duplicate times in cases where the user denies and then grants a permission. Keep track of if
// we've responded before and bail out of handling the callback manually if this is a repeat
// call.
boolean alreadyCalled = false;
final ResultCallback callback;
@VisibleForTesting
CameraRequestPermissionsListener(ResultCallback callback) {
this.callback = callback;
}
@Override
public boolean onRequestPermissionsResult(int id, String[] permissions, int[] grantResults) {
if (alreadyCalled || id != CAMERA_REQUEST_ID) {
return false;
}
alreadyCalled = true;
if (grantResults[0] != PackageManager.PERMISSION_GRANTED) {
callback.onResult("cameraPermission", "MediaRecorderCamera permission not granted");
} else if (grantResults.length > 1 && grantResults[1] != PackageManager.PERMISSION_GRANTED) {
callback.onResult("cameraPermission", "MediaRecorderAudio permission not granted");
} else {
callback.onResult(null, null);
}
return true;
}
}
}