From b46ef5eede2754acffa5598328b9f56757ab2ee0 Mon Sep 17 00:00:00 2001 From: Stuart Morgan Date: Mon, 7 Nov 2022 12:26:17 -0500 Subject: [PATCH] [image_picker] Don't store null paths in lost cache If the user cancels image selection on Android, store nothing in the lost image cache rather than storing an array with a null path. While we could potentially keep this behavior and instead handle it differently on the Dart side, returning some new "cancelled" `LostDataResponse`, that would be semi-breaking; e.g., the current example's lost data handling would actually throw as written if we had a new non-`isEmpty`, non-exception, null-`file` response. Since nobody has requested the ability to specifically detect a "lost cancel" as being different from not having started the process of picking anything, this doesn't make that potentially-client-breaking change. If it turns out there's a use case for that in the future, we can revisit that (but should not do it by storing a null entry in a file array anyway). Fixes https://github.com/flutter/flutter/issues/114551 --- .../image_picker_android/CHANGELOG.md | 4 ++++ .../imagepicker/ImagePickerDelegate.java | 16 +++++++++---- .../imagepicker/ImagePickerDelegateTest.java | 23 +++++++++++++++++++ .../image_picker_android/pubspec.yaml | 2 +- 4 files changed, 40 insertions(+), 5 deletions(-) diff --git a/packages/image_picker/image_picker_android/CHANGELOG.md b/packages/image_picker/image_picker_android/CHANGELOG.md index 3075f5b1d976..b041761181d0 100644 --- a/packages/image_picker/image_picker_android/CHANGELOG.md +++ b/packages/image_picker/image_picker_android/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.8.5+4 + +* Fixes null cast exception when restoring a cancelled selection. + ## 0.8.5+3 * Updates minimum Flutter version to 2.10. diff --git a/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerDelegate.java b/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerDelegate.java index dddf67e6a382..cb4beacf9df4 100644 --- a/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerDelegate.java +++ b/packages/image_picker/image_picker_android/android/src/main/java/io/flutter/plugins/imagepicker/ImagePickerDelegate.java @@ -15,6 +15,7 @@ import android.net.Uri; import android.os.Build; import android.provider.MediaStore; +import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.core.app.ActivityCompat; import androidx.core.content.FileProvider; @@ -621,11 +622,18 @@ private boolean setPendingMethodCallAndResult( return true; } - private void finishWithSuccess(String imagePath) { + // Handles completion of selection with a single result. + // + // A null imagePath indicates that the image picker was cancelled without + // selection. + private void finishWithSuccess(@Nullable String imagePath) { if (pendingResult == null) { - ArrayList pathList = new ArrayList<>(); - pathList.add(imagePath); - cache.saveResult(pathList, null, null); + // Only save data for later retrieval if something was actually selected. + if (imagePath != null) { + ArrayList pathList = new ArrayList<>(); + pathList.add(imagePath); + cache.saveResult(pathList, null, null); + } return; } pendingResult.success(imagePath); diff --git a/packages/image_picker/image_picker_android/android/src/test/java/io/flutter/plugins/imagepicker/ImagePickerDelegateTest.java b/packages/image_picker/image_picker_android/android/src/test/java/io/flutter/plugins/imagepicker/ImagePickerDelegateTest.java index d2ee7b0b7d61..6d1e73c49eb9 100644 --- a/packages/image_picker/image_picker_android/android/src/test/java/io/flutter/plugins/imagepicker/ImagePickerDelegateTest.java +++ b/packages/image_picker/image_picker_android/android/src/test/java/io/flutter/plugins/imagepicker/ImagePickerDelegateTest.java @@ -13,6 +13,7 @@ import static org.mockito.Mockito.doNothing; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; @@ -275,6 +276,16 @@ public void onActivityResult_WhenPickFromGalleryCanceled_FinishesWithNull() { verifyNoMoreInteractions(mockResult); } + @Test + public void onActivityResult_WhenPickFromGalleryCanceled_StoresNothingInCache() { + ImagePickerDelegate delegate = createDelegate(); + + delegate.onActivityResult( + ImagePickerDelegate.REQUEST_CODE_CHOOSE_IMAGE_FROM_GALLERY, Activity.RESULT_CANCELED, null); + + verify(cache, never()).saveResult(any(), any(), any()); + } + @Test public void onActivityResult_WhenImagePickedFromGallery_AndNoResizeNeeded_FinishesWithImagePath() { @@ -287,6 +298,18 @@ public void onActivityResult_WhenPickFromGalleryCanceled_FinishesWithNull() { verifyNoMoreInteractions(mockResult); } + @Test + public void onActivityResult_WhenImagePickedFromGallery_AndNoResizeNeeded_StoresImageInCache() { + ImagePickerDelegate delegate = createDelegate(); + + delegate.onActivityResult( + ImagePickerDelegate.REQUEST_CODE_CHOOSE_IMAGE_FROM_GALLERY, Activity.RESULT_OK, mockIntent); + + ArgumentCaptor> pathListCapture = ArgumentCaptor.forClass(ArrayList.class); + verify(cache, times(1)).saveResult(pathListCapture.capture(), any(), any()); + assertEquals("pathFromUri", pathListCapture.getValue().get(0)); + } + @Test public void onActivityResult_WhenImagePickedFromGallery_AndResizeNeeded_FinishesWithScaledImagePath() { diff --git a/packages/image_picker/image_picker_android/pubspec.yaml b/packages/image_picker/image_picker_android/pubspec.yaml index c0092493b715..4c32e345007c 100755 --- a/packages/image_picker/image_picker_android/pubspec.yaml +++ b/packages/image_picker/image_picker_android/pubspec.yaml @@ -2,7 +2,7 @@ name: image_picker_android description: Android implementation of the image_picker plugin. repository: https://github.com/flutter/plugins/tree/main/packages/image_picker/image_picker_android issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+image_picker%22 -version: 0.8.5+3 +version: 0.8.5+4 environment: sdk: ">=2.14.0 <3.0.0"