Skip to content

Commit

Permalink
fix(android): openPhotoGallery() crashes when canceled (#12165)
Browse files Browse the repository at this point in the history
- Regression introduced in 9.1.0

Fixes TIMOB-28178

Co-authored-by: ssekhri <ssekhri@axway.com>
  • Loading branch information
jquick-axway and ssekhri authored Oct 8, 2020
1 parent 5ba35d3 commit 0e284e5
Showing 1 changed file with 83 additions and 87 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -933,9 +933,7 @@ public void openPhotoGallery(KrollDict options)
}
if (isSelectingPhoto && isSelectingVideo) {
galleryIntent.getIntent().setType("*/*");
if (Build.VERSION.SDK_INT >= 19) {
galleryIntent.getIntent().putExtra(Intent.EXTRA_MIME_TYPES, new String[] { "image/*", "video/*" });
}
galleryIntent.getIntent().putExtra(Intent.EXTRA_MIME_TYPES, new String[] { "image/*", "video/*" });
MediaModule.mediaType = MEDIA_TYPE_PHOTO;
} else if (isSelectingVideo) {
galleryIntent.getIntent().setType("video/*");
Expand All @@ -952,7 +950,7 @@ public void openPhotoGallery(KrollDict options)
final int PICK_IMAGE_MULTIPLE = activitySupport.getUniqueResultCode();
boolean allowMultiple = false;

if (options.containsKey(TiC.PROPERTY_ALLOW_MULTIPLE) && Build.VERSION.SDK_INT >= 18) {
if (options.containsKey(TiC.PROPERTY_ALLOW_MULTIPLE)) {
allowMultiple = TiConvert.toBoolean(options.get(TiC.PROPERTY_ALLOW_MULTIPLE));
galleryIntent.getIntent().putExtra(Intent.EXTRA_ALLOW_MULTIPLE, allowMultiple);
}
Expand All @@ -966,115 +964,113 @@ public void onResult(Activity activity, int requestCode, int resultCode, Intent
if (requestCode != code) {
return;
}

// Do not continue if no selection was made.
Log.d(TAG, "OnResult called: " + resultCode, Log.DEBUG_MODE);
Uri uri = data.getData();
String path = null;
if (data != null) {
path = uri.toString();
}
//Starting with Android-L, backing out of the gallery no longer returns cancel code, but with
//an ok code and a null data.
if (resultCode == Activity.RESULT_CANCELED || (Build.VERSION.SDK_INT >= 20 && data == null)) {
if ((resultCode == Activity.RESULT_CANCELED) || (data == null)) {
if (fCancelCallback != null) {
KrollDict response = new KrollDict();
response.putCodeAndMessage(NO_ERROR, null);
fCancelCallback.callAsync(getKrollObject(), response);
}
return;
}

} else {
// Handle multiple file selection, if enabled.
if (requestCode == PICK_IMAGE_MULTIPLE && Build.VERSION.SDK_INT >= 18) {
// Wrap all selected file(s) in Titanium "CameraMediaItemType" dictionaries.
ArrayList<KrollDict> selectedFiles = new ArrayList<>();
ClipData clipData = data.getClipData();
if (clipData != null) {
// Fetch file(s) from clip data.
int count = clipData.getItemCount();
for (int index = 0; index < count; index++) {
ClipData.Item item = clipData.getItemAt(index);
if ((item == null) || (item.getUri() == null)) {
continue;
}
KrollDict dictionary = createDictForImage(item.getUri().toString());
if (dictionary == null) {
continue;
}
selectedFiles.add(dictionary);
// Fetch a URI to file selected. (Only applicable to single file selection.)
Uri uri = data.getData();
String path = uri.toString();

// Handle multiple file selection, if enabled.
if (requestCode == PICK_IMAGE_MULTIPLE) {
// Wrap all selected file(s) in Titanium "CameraMediaItemType" dictionaries.
ArrayList<KrollDict> selectedFiles = new ArrayList<>();
ClipData clipData = data.getClipData();
if (clipData != null) {
// Fetch file(s) from clip data.
int count = clipData.getItemCount();
for (int index = 0; index < count; index++) {
ClipData.Item item = clipData.getItemAt(index);
if ((item == null) || (item.getUri() == null)) {
continue;
}
} else if (path != null) {
// Only a single file was found.
KrollDict dictionary = createDictForImage(path);
if (dictionary != null) {
selectedFiles.add(dictionary);
KrollDict dictionary = createDictForImage(item.getUri().toString());
if (dictionary == null) {
continue;
}
selectedFiles.add(dictionary);
}

// Copy each selected file to either an "images" or "videos" collection.
ArrayList<KrollDict> selectedImages = new ArrayList<>();
ArrayList<KrollDict> selectedVideos = new ArrayList<>();
for (KrollDict dictionary : selectedFiles) {
String mediaType = dictionary.getString("mediaType");
if (mediaType != null) {
if (mediaType.equals(MEDIA_TYPE_PHOTO)) {
selectedImages.add(dictionary);
} else if (mediaType.equals(MEDIA_TYPE_VIDEO)) {
selectedVideos.add(dictionary);
}
}
} else if (path != null) {
// Only a single file was found.
KrollDict dictionary = createDictForImage(path);
if (dictionary != null) {
selectedFiles.add(dictionary);
}
}

// Invoke a callback with the selection result.
if (selectedImages.isEmpty() && selectedVideos.isEmpty()) {
if (selectedFiles.isEmpty()) {
// Invoke the "cancel" callback if no files were selected.
if (fCancelCallback != null) {
KrollDict response = new KrollDict();
response.putCodeAndMessage(NO_ERROR, null);
fCancelCallback.callAsync(getKrollObject(), response);
}
} else {
// Invoke the "error" callback if non-image/video files were selected.
String message = "Invalid file types were selected";
Log.e(TAG, message);
if (fErrorCallback != null) {
fErrorCallback.callAsync(getKrollObject(),
createErrorResponse(UNKNOWN_ERROR, message));
}
}
} else {
// Invoke the "success" callback with the selected file(s).
if (fSuccessCallback != null) {
KrollDict d = new KrollDict();
d.putCodeAndMessage(NO_ERROR, null);
d.put("images", selectedImages.toArray(new KrollDict[0]));
d.put("videos", selectedVideos.toArray(new KrollDict[0]));
fSuccessCallback.callAsync(getKrollObject(), d);
// Copy each selected file to either an "images" or "videos" collection.
ArrayList<KrollDict> selectedImages = new ArrayList<>();
ArrayList<KrollDict> selectedVideos = new ArrayList<>();
for (KrollDict dictionary : selectedFiles) {
String mediaType = dictionary.getString("mediaType");
if (mediaType != null) {
if (mediaType.equals(MEDIA_TYPE_PHOTO)) {
selectedImages.add(dictionary);
} else if (mediaType.equals(MEDIA_TYPE_VIDEO)) {
selectedVideos.add(dictionary);
}
}
return;
}

// Handle single file selection.
try {
//Check for invalid path
if (path == null) {
String msg = "File path is invalid";
Log.e(TAG, msg);
// Invoke a callback with the selection result.
if (selectedImages.isEmpty() && selectedVideos.isEmpty()) {
if (selectedFiles.isEmpty()) {
// Invoke the "cancel" callback if no files were selected.
if (fCancelCallback != null) {
KrollDict response = new KrollDict();
response.putCodeAndMessage(NO_ERROR, null);
fCancelCallback.callAsync(getKrollObject(), response);
}
} else {
// Invoke the "error" callback if non-image/video files were selected.
String message = "Invalid file types were selected";
Log.e(TAG, message);
if (fErrorCallback != null) {
fErrorCallback.callAsync(getKrollObject(), createErrorResponse(UNKNOWN_ERROR, msg));
fErrorCallback.callAsync(getKrollObject(),
createErrorResponse(UNKNOWN_ERROR, message));
}
return;
}
} else {
// Invoke the "success" callback with the selected file(s).
if (fSuccessCallback != null) {
fSuccessCallback.callAsync(getKrollObject(), createDictForImage(path));
KrollDict d = new KrollDict();
d.putCodeAndMessage(NO_ERROR, null);
d.put("images", selectedImages.toArray(new KrollDict[0]));
d.put("videos", selectedVideos.toArray(new KrollDict[0]));
fSuccessCallback.callAsync(getKrollObject(), d);
}
}
return;
}

} catch (OutOfMemoryError e) {
String msg = "Not enough memory to get image: " + e.getMessage();
// Handle single file selection.
try {
//Check for invalid path
if (path == null) {
String msg = "File path is invalid";
Log.e(TAG, msg);
if (fErrorCallback != null) {
fErrorCallback.callAsync(getKrollObject(), createErrorResponse(UNKNOWN_ERROR, msg));
}
return;
}
if (fSuccessCallback != null) {
fSuccessCallback.callAsync(getKrollObject(), createDictForImage(path));
}
} catch (OutOfMemoryError e) {
String msg = "Not enough memory to get image: " + e.getMessage();
Log.e(TAG, msg);
if (fErrorCallback != null) {
fErrorCallback.callAsync(getKrollObject(), createErrorResponse(UNKNOWN_ERROR, msg));
}
}
}
Expand Down

0 comments on commit 0e284e5

Please sign in to comment.