Skip to content

Commit

Permalink
Merge pull request #2484 from dimagi/attachment-fix
Browse files Browse the repository at this point in the history
[SAAS-12272] Show error if selected image is not supported by commcare
  • Loading branch information
ShivamPokhriyal committed May 27, 2021
2 parents e055b3d + 6edc8f7 commit 75f87d7
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 42 deletions.
2 changes: 1 addition & 1 deletion app/src/org/commcare/activities/FormEntryActivity.java
Expand Up @@ -403,7 +403,7 @@ private void processChooserResponse(Intent intent) {
Toast.makeText(FormEntryActivity.this,
Localization.get("form.attachment.notfound"),
Toast.LENGTH_LONG).show();
} else if (!FileUtil.isSupportedMultiMediaFile(media)) {
} else if (!FileUtil.isSupportedMultiMediaFile(this, media)) {
// don't let the user select a file that won't be included in the
// upload to the server
uiController.questionsView.clearAnswer();
Expand Down
Expand Up @@ -132,6 +132,12 @@ public static void processImageChooserResponse(FormEntryActivity activity,
showInvalidImageMessage(activity);
return;
}
if (!FileUtil.isSupportedMultiMediaFile(activity, selectedImage)) {
Toast.makeText(activity,
Localization.get("form.attachment.invalid"),
Toast.LENGTH_LONG).show();
return;
}
processImageGivenFileUri(activity, instanceFolder, selectedImage);
}

Expand Down
89 changes: 49 additions & 40 deletions app/src/org/commcare/utils/FileUtil.java
Expand Up @@ -25,7 +25,6 @@
import org.commcare.resources.model.Resource;
import org.commcare.util.LogTypes;
import org.javarosa.core.io.StreamsUtil;
import org.javarosa.core.model.data.StringData;
import org.javarosa.core.reference.InvalidReferenceException;
import org.javarosa.core.reference.Reference;
import org.javarosa.core.reference.ReferenceManager;
Expand Down Expand Up @@ -135,8 +134,7 @@ public static String SanitizeFileName(String input) {
* The app needs to already have permissions granted for the external file content.
*
* @param contentUri A valid uri to a contentprovider backed external file
* @param destDir The destination directory for the file to be copied into.
*
* @param destDir The destination directory for the file to be copied into.
* @return The destination copy of the file
*/
public static File copyContentFileToLocalDir(Uri contentUri, File destDir, Context context) throws IOException {
Expand All @@ -156,14 +154,14 @@ public static File copyContentFileToLocalDir(Uri contentUri, File destDir, Conte
dst.transferFrom(srcFc, 0, fileLength);
} finally {
try {
if(srcFc != null) {
if (srcFc != null) {
srcFc.close();
}
} catch (IOException e) {
e.printStackTrace();
}
try {
if(dst != null) {
if (dst != null) {
dst.close();
}
} catch (IOException e) {
Expand Down Expand Up @@ -338,7 +336,9 @@ public static ArrayList<String> getExternalMounts() {
* https://developer.android.com/reference/android/content/ContentUris
*/
public static boolean isContentUri(String input) {
if (input == null) { return false; }
if (input == null) {
return false;
}

return "content".equals(Uri.parse(input).getScheme());
}
Expand Down Expand Up @@ -517,37 +517,39 @@ public static String getMd5Hash(File file) {
}

public static String getExtension(String filePath) {
if (filePath.contains(".")) {
if (filePath != null && filePath.contains(".")) {
return last(filePath.split("\\."));
}
return "";
}

/**
* Retrieve a file's name using contentUri.
* https://developer.android.com/training/secure-file-sharing/retrieve-info.html#RetrieveFileInfo
* Retrieve a file's name from content URI using below process:
* - Get fileName using {@link UriToFilePath#getPathFromUri(Context, Uri)}.
* - If the fileName doesn't have an extension, then retrieve fileName using file provider. @see https://developer.android.com/training/secure-file-sharing/retrieve-info.html#RetrieveFileInfo
* - If the fileName still doesn't have extension, use {@link #getFileExtensionUsingMimeType(Context, Uri, String)}
*
* @throws FileExtensionNotFoundException
* @return FileName with extension
*/
public static String getFileName(Context context, Uri uri) throws FileExtensionNotFoundException {
String fileName;
try (Cursor cursor = context.getContentResolver().query(
uri, new String[] { OpenableColumns.DISPLAY_NAME }, null, null, null)) {
if (cursor == null || cursor.getCount() <= 0) {
try {
fileName = getFileName(UriToFilePath.getPathFromUri(context, uri));
} catch (UriToFilePath.NoDataColumnForUriException e) {
fileName = uri.getLastPathSegment();
try {
fileName = getFileName(UriToFilePath.getPathFromUri(context, uri));
} catch (UriToFilePath.NoDataColumnForUriException e) {
fileName = uri.getLastPathSegment();
}
if (TextUtils.isEmpty(getExtension(fileName))) {
try (Cursor cursor = context.getContentResolver().query(
uri, new String[]{OpenableColumns.DISPLAY_NAME}, null, null, null)) {
if (cursor != null && cursor.moveToFirst()) {
fileName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
}
} else {
int nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
cursor.moveToFirst();
fileName = cursor.getString(nameIndex);
cursor.close();
} catch (Exception e) {
e.printStackTrace();
}
}
if (TextUtils.isEmpty(getExtension(fileName))) {
String ext = getFileExtension(context, uri, fileName);
String ext = getFileExtensionUsingMimeType(context, uri, fileName);
fileName = fileName + "." + ext;
}
return fileName;
Expand All @@ -557,25 +559,33 @@ public static String getFileName(Context context, Uri uri) throws FileExtensionN
* @return file extension by getting the mimeType from the URI.
* @throws FileExtensionNotFoundException if we can't find mimeType from the URI.
*/
private static String getFileExtension(Context context, Uri uri, String fileName) throws FileExtensionNotFoundException {
private static String getFileExtensionUsingMimeType(Context context, Uri uri, String fileName) throws FileExtensionNotFoundException {
String mimeType = getMimeTypeFromUri(context, uri);
String ext = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType);
if (TextUtils.isEmpty(ext)) {
throw new FileExtensionNotFoundException(
"Can't find extension for URI :: " + uri
+ " and mimeType :: " + mimeType
+ " and fileName :: " + fileName
);
}
return ext;
}

/**
* @return mimeType for the file denoted by URI
*/
private static String getMimeTypeFromUri(Context context, Uri uri) {
String mimeType = context.getContentResolver().getType(uri);
if (TextUtils.isEmpty(mimeType)) {
try (Cursor cursor = context.getContentResolver().query(
uri, new String[] { MediaStore.MediaColumns.MIME_TYPE }, null, null, null)) {
uri, new String[]{MediaStore.MediaColumns.MIME_TYPE}, null, null, null)) {
if (cursor != null && cursor.moveToFirst()) {
mimeType = cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.MIME_TYPE));
}
}
}
String ext = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType);
if (TextUtils.isEmpty(ext)) {
throw new FileExtensionNotFoundException(
"Can't find extension for URI :: " + uri
+ " and mimeType :: " + mimeType
+ " and fileName :: " + fileName
);
}
return ext;
return mimeType;
}

public static String getFileName(String filePath) {
Expand Down Expand Up @@ -724,13 +734,12 @@ public static void copyFile(InputStream inputStream, File dstFile) throws IOExce
outputStream.close();
}

public static boolean isSupportedMultiMediaFile(Uri media) {
public static boolean isSupportedMultiMediaFile(Context context, Uri media) {
try {
String binaryPath = UriToFilePath.getPathFromUri(CommCareApplication.instance(), media);
return FormUploadUtil.isSupportedMultimediaFile(binaryPath);
} catch (UriToFilePath.NoDataColumnForUriException e) {
// No file path available, work with the media uri instead
return FormUploadUtil.isSupportedMultimediaFile(media.getPath());
String fileName = getFileName(context, media);
return FormUploadUtil.isSupportedMultimediaFile(fileName);
} catch (FileExtensionNotFoundException e) {
return false;
}
}

Expand Down
3 changes: 2 additions & 1 deletion app/src/org/commcare/utils/FormUploadUtil.java
Expand Up @@ -32,6 +32,7 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;

import javax.annotation.Nullable;
import javax.crypto.Cipher;
Expand Down Expand Up @@ -409,7 +410,7 @@ public static MultipartBody.Part createEncryptedFilePart(String partName, File f
*/
public static boolean isSupportedMultimediaFile(String filename) {
for (String ext : SUPPORTED_FILE_EXTS) {
if (filename.endsWith(ext)) {
if (filename.toLowerCase(Locale.US).endsWith(ext)) {
return true;
}
}
Expand Down

0 comments on commit 75f87d7

Please sign in to comment.