[image_picker] Removed redundant request for camera permission (#4001)
* Removed all permissions and updated unit tests
* Updated pubspec version and changelog.
Updated pubspec version and changelog.
* Update version
diff --git a/packages/image_picker/image_picker/CHANGELOG.md b/packages/image_picker/image_picker/CHANGELOG.md
index 515845e..703b00b 100644
--- a/packages/image_picker/image_picker/CHANGELOG.md
+++ b/packages/image_picker/image_picker/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.8.0+1
+
+* Removed redundant request for camera permissions.
+
## 0.8.0
* BREAKING CHANGE: Changed storage location for captured images and videos to internal cache on Android,
diff --git a/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerDelegate.java b/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerDelegate.java
index c934b54..41df851 100644
--- a/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerDelegate.java
+++ b/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerDelegate.java
@@ -4,7 +4,6 @@
package io.flutter.plugins.imagepicker;
-import android.Manifest;
import android.app.Activity;
import android.content.Intent;
import android.content.pm.PackageManager;
@@ -15,7 +14,6 @@
import android.os.Build;
import android.provider.MediaStore;
import androidx.annotation.VisibleForTesting;
-import androidx.core.app.ActivityCompat;
import androidx.core.content.FileProvider;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
@@ -42,19 +40,7 @@
* means that the chooseImageFromGallery() or takeImageWithCamera() method was called at least
* twice. In this case, stop executing and finish with an error.
*
- * <p>2. Check that a required runtime permission has been granted. The takeImageWithCamera() method
- * checks that {@link Manifest.permission#CAMERA} has been granted.
- *
- * <p>The permission check can end up in two different outcomes:
- *
- * <p>A) If the permission has already been granted, continue with picking the image from gallery or
- * camera.
- *
- * <p>B) If the permission hasn't already been granted, ask for the permission from the user. If the
- * user grants the permission, proceed with step #3. If the user denies the permission, stop doing
- * anything else and finish with a null result.
- *
- * <p>3. Launch the gallery or camera for picking the image, depending on whether
+ * <p>2. Launch the gallery or camera for picking the image, depending on whether
* chooseImageFromGallery() or takeImageWithCamera() was called.
*
* <p>This can end up in three different outcomes:
@@ -69,15 +55,11 @@
*
* <p>C) User cancels picking an image. Finish with null result.
*/
-public class ImagePickerDelegate
- implements PluginRegistry.ActivityResultListener,
- PluginRegistry.RequestPermissionsResultListener {
+public class ImagePickerDelegate implements PluginRegistry.ActivityResultListener {
@VisibleForTesting static final int REQUEST_CODE_CHOOSE_IMAGE_FROM_GALLERY = 2342;
@VisibleForTesting static final int REQUEST_CODE_TAKE_IMAGE_WITH_CAMERA = 2343;
- @VisibleForTesting static final int REQUEST_CAMERA_IMAGE_PERMISSION = 2345;
@VisibleForTesting static final int REQUEST_CODE_CHOOSE_VIDEO_FROM_GALLERY = 2352;
@VisibleForTesting static final int REQUEST_CODE_TAKE_VIDEO_WITH_CAMERA = 2353;
- @VisibleForTesting static final int REQUEST_CAMERA_VIDEO_PERMISSION = 2355;
@VisibleForTesting final String fileProviderName;
@@ -85,20 +67,11 @@
@VisibleForTesting final File externalFilesDirectory;
private final ImageResizer imageResizer;
private final ImagePickerCache cache;
- private final PermissionManager permissionManager;
private final IntentResolver intentResolver;
private final FileUriResolver fileUriResolver;
private final FileUtils fileUtils;
private CameraDevice cameraDevice;
- interface PermissionManager {
- boolean isPermissionGranted(String permissionName);
-
- void askForPermission(String permissionName, int requestCode);
-
- boolean needRequestCameraPermission();
- }
-
interface IntentResolver {
boolean resolveActivity(Intent intent);
}
@@ -129,23 +102,6 @@
null,
null,
cache,
- new PermissionManager() {
- @Override
- public boolean isPermissionGranted(String permissionName) {
- return ActivityCompat.checkSelfPermission(activity, permissionName)
- == PackageManager.PERMISSION_GRANTED;
- }
-
- @Override
- public void askForPermission(String permissionName, int requestCode) {
- ActivityCompat.requestPermissions(activity, new String[] {permissionName}, requestCode);
- }
-
- @Override
- public boolean needRequestCameraPermission() {
- return ImagePickerUtils.needRequestCameraPermission(activity);
- }
- },
new IntentResolver() {
@Override
public boolean resolveActivity(Intent intent) {
@@ -187,7 +143,6 @@
final MethodChannel.Result result,
final MethodCall methodCall,
final ImagePickerCache cache,
- final PermissionManager permissionManager,
final IntentResolver intentResolver,
final FileUriResolver fileUriResolver,
final FileUtils fileUtils) {
@@ -197,7 +152,6 @@
this.fileProviderName = activity.getPackageName() + ".flutter.image_provider";
this.pendingResult = result;
this.methodCall = methodCall;
- this.permissionManager = permissionManager;
this.intentResolver = intentResolver;
this.fileUriResolver = fileUriResolver;
this.fileUtils = fileUtils;
@@ -269,13 +223,6 @@
return;
}
- if (needRequestCameraPermission()
- && !permissionManager.isPermissionGranted(Manifest.permission.CAMERA)) {
- permissionManager.askForPermission(
- Manifest.permission.CAMERA, REQUEST_CAMERA_VIDEO_PERMISSION);
- return;
- }
-
launchTakeVideoWithCameraIntent();
}
@@ -328,22 +275,9 @@
return;
}
- if (needRequestCameraPermission()
- && !permissionManager.isPermissionGranted(Manifest.permission.CAMERA)) {
- permissionManager.askForPermission(
- Manifest.permission.CAMERA, REQUEST_CAMERA_IMAGE_PERMISSION);
- return;
- }
launchTakeImageWithCameraIntent();
}
- private boolean needRequestCameraPermission() {
- if (permissionManager == null) {
- return false;
- }
- return permissionManager.needRequestCameraPermission();
- }
-
private void launchTakeImageWithCameraIntent() {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (cameraDevice == CameraDevice.FRONT) {
@@ -402,39 +336,6 @@
}
@Override
- public boolean onRequestPermissionsResult(
- int requestCode, String[] permissions, int[] grantResults) {
- boolean permissionGranted =
- grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED;
-
- switch (requestCode) {
- case REQUEST_CAMERA_IMAGE_PERMISSION:
- if (permissionGranted) {
- launchTakeImageWithCameraIntent();
- }
- break;
- case REQUEST_CAMERA_VIDEO_PERMISSION:
- if (permissionGranted) {
- launchTakeVideoWithCameraIntent();
- }
- break;
- default:
- return false;
- }
-
- if (!permissionGranted) {
- switch (requestCode) {
- case REQUEST_CAMERA_IMAGE_PERMISSION:
- case REQUEST_CAMERA_VIDEO_PERMISSION:
- finishWithError("camera_access_denied", "The user did not allow camera access.");
- break;
- }
- }
-
- return true;
- }
-
- @Override
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CODE_CHOOSE_IMAGE_FROM_GALLERY:
diff --git a/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java b/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java
index bffc903..b4e7e8a 100644
--- a/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java
+++ b/packages/image_picker/image_picker/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerPlugin.java
@@ -192,11 +192,9 @@
// V1 embedding setup for activity listeners.
application.registerActivityLifecycleCallbacks(observer);
registrar.addActivityResultListener(delegate);
- registrar.addRequestPermissionsResultListener(delegate);
} else {
// V2 embedding setup for activity listeners.
activityBinding.addActivityResultListener(delegate);
- activityBinding.addRequestPermissionsResultListener(delegate);
lifecycle = FlutterLifecycleAdapter.getActivityLifecycle(activityBinding);
lifecycle.addObserver(observer);
}
@@ -204,7 +202,6 @@
private void tearDown() {
activityBinding.removeActivityResultListener(delegate);
- activityBinding.removeRequestPermissionsResultListener(delegate);
activityBinding = null;
lifecycle.removeObserver(observer);
lifecycle = null;
diff --git a/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerDelegateTest.java b/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerDelegateTest.java
index da53b10..5b66814 100644
--- a/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerDelegateTest.java
+++ b/packages/image_picker/image_picker/example/android/app/src/test/java/io/flutter/plugins/imagepicker/ImagePickerDelegateTest.java
@@ -14,7 +14,6 @@
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
-import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
@@ -40,7 +39,6 @@
@Mock ImageResizer mockImageResizer;
@Mock MethodCall mockMethodCall;
@Mock MethodChannel.Result mockResult;
- @Mock ImagePickerDelegate.PermissionManager mockPermissionManager;
@Mock ImagePickerDelegate.IntentResolver mockIntentResolver;
@Mock FileUtils mockFileUtils;
@Mock Intent mockIntent;
@@ -104,11 +102,7 @@
}
@Test
- public void
- chooseImageFromGallery_WhenHasExternalStoragePermission_LaunchesChooseFromGalleryIntent() {
- when(mockPermissionManager.isPermissionGranted(Manifest.permission.READ_EXTERNAL_STORAGE))
- .thenReturn(true);
-
+ public void chooseImageFromGallery_LaunchesChooseFromGalleryIntent() {
ImagePickerDelegate delegate = createDelegate();
delegate.chooseImageFromGallery(mockMethodCall, mockResult);
@@ -128,49 +122,30 @@
}
@Test
- public void takeImageWithCamera_WhenHasNoCameraPermission_RequestsForPermission() {
- when(mockPermissionManager.isPermissionGranted(Manifest.permission.CAMERA)).thenReturn(false);
- when(mockPermissionManager.needRequestCameraPermission()).thenReturn(true);
-
- ImagePickerDelegate delegate = createDelegate();
- delegate.takeImageWithCamera(mockMethodCall, mockResult);
-
- verify(mockPermissionManager)
- .askForPermission(
- Manifest.permission.CAMERA, ImagePickerDelegate.REQUEST_CAMERA_IMAGE_PERMISSION);
- }
-
- @Test
- public void takeImageWithCamera_WhenCameraPermissionNotPresent_RequestsForPermission() {
- when(mockPermissionManager.needRequestCameraPermission()).thenReturn(false);
+ public void
+ takeImageWithCamera_WhenAnActivityCanHandleCameraIntent_LaunchesTakeWithCameraIntent() {
when(mockIntentResolver.resolveActivity(any(Intent.class))).thenReturn(true);
- ImagePickerDelegate delegate = createDelegate();
- delegate.takeImageWithCamera(mockMethodCall, mockResult);
+ MockedStatic<File> mockStaticFile = Mockito.mockStatic(File.class);
+ mockStaticFile
+ .when(() -> File.createTempFile(any(), any(), any()))
+ .thenReturn(new File("/tmpfile"));
- verify(mockActivity)
- .startActivityForResult(
- any(Intent.class), eq(ImagePickerDelegate.REQUEST_CODE_TAKE_IMAGE_WITH_CAMERA));
+ try {
+ ImagePickerDelegate delegate = createDelegate();
+ delegate.takeImageWithCamera(mockMethodCall, mockResult);
+
+ verify(mockActivity)
+ .startActivityForResult(
+ any(Intent.class), eq(ImagePickerDelegate.REQUEST_CODE_TAKE_IMAGE_WITH_CAMERA));
+ } finally {
+ mockStaticFile.close();
+ }
}
@Test
public void
- takeImageWithCamera_WhenHasCameraPermission_AndAnActivityCanHandleCameraIntent_LaunchesTakeWithCameraIntent() {
- when(mockPermissionManager.isPermissionGranted(Manifest.permission.CAMERA)).thenReturn(true);
- when(mockIntentResolver.resolveActivity(any(Intent.class))).thenReturn(true);
-
- ImagePickerDelegate delegate = createDelegate();
- delegate.takeImageWithCamera(mockMethodCall, mockResult);
-
- verify(mockActivity)
- .startActivityForResult(
- any(Intent.class), eq(ImagePickerDelegate.REQUEST_CODE_TAKE_IMAGE_WITH_CAMERA));
- }
-
- @Test
- public void
- takeImageWithCamera_WhenHasCameraPermission_AndNoActivityToHandleCameraIntent_FinishesWithNoCamerasAvailableError() {
- when(mockPermissionManager.isPermissionGranted(Manifest.permission.CAMERA)).thenReturn(true);
+ takeImageWithCamera_WhenNoActivityToHandleCameraIntent_FinishesWithNoCamerasAvailableError() {
when(mockIntentResolver.resolveActivity(any(Intent.class))).thenReturn(false);
ImagePickerDelegate delegate = createDelegate();
@@ -183,7 +158,6 @@
@Test
public void takeImageWithCamera_WritesImageToCacheDirectory() {
- when(mockPermissionManager.isPermissionGranted(Manifest.permission.CAMERA)).thenReturn(true);
when(mockIntentResolver.resolveActivity(any(Intent.class))).thenReturn(true);
MockedStatic<File> mockStaticFile = Mockito.mockStatic(File.class);
@@ -191,57 +165,16 @@
.when(() -> File.createTempFile(any(), any(), any()))
.thenReturn(new File("/tmpfile"));
- ImagePickerDelegate delegate = createDelegate();
- delegate.takeImageWithCamera(mockMethodCall, mockResult);
+ try {
+ ImagePickerDelegate delegate = createDelegate();
+ delegate.takeImageWithCamera(mockMethodCall, mockResult);
- mockStaticFile.verify(
- () -> File.createTempFile(any(), eq(".jpg"), eq(new File("/image_picker_cache"))),
- times(1));
- }
-
- @Test
- public void onRequestPermissionsResult_WhenCameraPermissionDenied_FinishesWithError() {
- ImagePickerDelegate delegate = createDelegateWithPendingResultAndMethodCall();
-
- delegate.onRequestPermissionsResult(
- ImagePickerDelegate.REQUEST_CAMERA_IMAGE_PERMISSION,
- new String[] {Manifest.permission.CAMERA},
- new int[] {PackageManager.PERMISSION_DENIED});
-
- verify(mockResult).error("camera_access_denied", "The user did not allow camera access.", null);
- verifyNoMoreInteractions(mockResult);
- }
-
- @Test
- public void
- onRequestTakeVideoPermissionsResult_WhenCameraPermissionGranted_LaunchesTakeVideoWithCameraIntent() {
- when(mockIntentResolver.resolveActivity(any(Intent.class))).thenReturn(true);
-
- ImagePickerDelegate delegate = createDelegateWithPendingResultAndMethodCall();
- delegate.onRequestPermissionsResult(
- ImagePickerDelegate.REQUEST_CAMERA_VIDEO_PERMISSION,
- new String[] {Manifest.permission.CAMERA},
- new int[] {PackageManager.PERMISSION_GRANTED});
-
- verify(mockActivity)
- .startActivityForResult(
- any(Intent.class), eq(ImagePickerDelegate.REQUEST_CODE_TAKE_VIDEO_WITH_CAMERA));
- }
-
- @Test
- public void
- onRequestTakeImagePermissionsResult_WhenCameraPermissionGranted_LaunchesTakeWithCameraIntent() {
- when(mockIntentResolver.resolveActivity(any(Intent.class))).thenReturn(true);
-
- ImagePickerDelegate delegate = createDelegateWithPendingResultAndMethodCall();
- delegate.onRequestPermissionsResult(
- ImagePickerDelegate.REQUEST_CAMERA_IMAGE_PERMISSION,
- new String[] {Manifest.permission.CAMERA},
- new int[] {PackageManager.PERMISSION_GRANTED});
-
- verify(mockActivity)
- .startActivityForResult(
- any(Intent.class), eq(ImagePickerDelegate.REQUEST_CODE_TAKE_IMAGE_WITH_CAMERA));
+ mockStaticFile.verify(
+ () -> File.createTempFile(any(), eq(".jpg"), eq(new File("/image_picker_cache"))),
+ times(1));
+ } finally {
+ mockStaticFile.close();
+ }
}
@Test
@@ -362,7 +295,6 @@
null,
null,
cache,
- mockPermissionManager,
mockIntentResolver,
mockFileUriResolver,
mockFileUtils);
@@ -371,12 +303,11 @@
private ImagePickerDelegate createDelegateWithPendingResultAndMethodCall() {
return new ImagePickerDelegate(
mockActivity,
- null,
+ new File("/image_picker_cache"),
mockImageResizer,
mockResult,
mockMethodCall,
cache,
- mockPermissionManager,
mockIntentResolver,
mockFileUriResolver,
mockFileUtils);
diff --git a/packages/image_picker/image_picker/pubspec.yaml b/packages/image_picker/image_picker/pubspec.yaml
index 95ea808..c24fdd0 100755
--- a/packages/image_picker/image_picker/pubspec.yaml
+++ b/packages/image_picker/image_picker/pubspec.yaml
@@ -3,7 +3,7 @@
library, and taking new pictures with the camera.
repository: https://github.com/flutter/plugins/tree/master/packages/image_picker/image_picker
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+image_picker%22
-version: 0.8.0
+version: 0.8.0+1
environment:
sdk: ">=2.12.0 <3.0.0"