Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(android): prevent app crash caused by NPE on intent data or mediaFile #232

Merged
merged 3 commits into from
Aug 3, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 55 additions & 49 deletions src/android/Capture.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,31 +20,27 @@ Licensed to the Apache Software Foundation (ASF) under one

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;

import android.content.ActivityNotFoundException;
import android.os.Build;
import android.os.Bundle;

import org.apache.cordova.file.FileUtils;
import org.apache.cordova.file.LocalFilesystemURL;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.LOG;
import org.apache.cordova.PermissionHelper;
import org.apache.cordova.PluginManager;
import org.apache.cordova.file.FileUtils;
import org.apache.cordova.file.LocalFilesystemURL;
import org.apache.cordova.mediacapture.PendingRequests.Request;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.Manifest;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Intent;
Expand All @@ -54,6 +50,8 @@ Licensed to the Apache Software Foundation (ASF) under one
import android.graphics.BitmapFactory;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;

Expand Down Expand Up @@ -285,17 +283,6 @@ private void captureAudio(Request req) {
}
}

private String getTempDirectoryPath() {
File cache = null;

// Use internal storage
cache = cordova.getActivity().getCacheDir();

// Create the cache directory if it doesn't exist
cache.mkdirs();
return cache.getAbsolutePath();
}

/**
* Sets up an intent to capture images. Result handled by onActivityResult()
*/
Expand All @@ -318,11 +305,6 @@ private void captureImage(Request req) {
this.cordova.startActivityForResult((CordovaPlugin) this, intent, req.requestCode);
}

private static void createWritableFile(File file) throws IOException {
file.createNewFile();
file.setWritable(true, false);
}

/**
* Sets up an intent to capture video. Result handled by onActivityResult()
*/
Expand Down Expand Up @@ -399,8 +381,19 @@ else if (resultCode == Activity.RESULT_CANCELED) {
public void onAudioActivityResult(Request req, Intent intent) {
// Get the uri of the audio clip
Uri data = intent.getData();
// create a file object from the uri
req.results.put(createMediaFile(data));
if (data == null) {
pendingRequests.resolveWithFailure(req, createErrorObject(CAPTURE_NO_MEDIA_FILES, "Error: data is null"));
return;
}

// Create a file object from the uri
JSONObject mediaFile = createMediaFile(data);
if (mediaFile == null) {
pendingRequests.resolveWithFailure(req, createErrorObject(CAPTURE_INTERNAL_ERR, "Error: no mediaFile created from " + data));
return;
}

req.results.put(mediaFile);

if (req.results.length() >= req.limit) {
// Send Uri back to JavaScript for listening to audio
Expand All @@ -412,8 +405,21 @@ public void onAudioActivityResult(Request req, Intent intent) {
}

public void onImageActivityResult(Request req) {
// Add image to results
req.results.put(createMediaFile(imageUri));
// Get the uri of the image
Uri data = imageUri;
if (data == null) {
pendingRequests.resolveWithFailure(req, createErrorObject(CAPTURE_NO_MEDIA_FILES, "Error: data is null"));
return;
}

// Create a file object from the uri
JSONObject mediaFile = createMediaFile(data);
if (mediaFile == null) {
pendingRequests.resolveWithFailure(req, createErrorObject(CAPTURE_INTERNAL_ERR, "Error: no mediaFile created from " + data));
return;
}

req.results.put(mediaFile);

checkForDuplicateImage();

Expand All @@ -427,32 +433,28 @@ public void onImageActivityResult(Request req) {
}

public void onVideoActivityResult(Request req, Intent intent) {
Uri data = null;

if (intent != null){
// Get the uri of the video clip
data = intent.getData();
// Get the uri of the video clip
Uri data = intent.getData();
if (data == null) {
pendingRequests.resolveWithFailure(req, createErrorObject(CAPTURE_NO_MEDIA_FILES, "Error: data is null"));
return;
}

if( data == null){
File movie = new File(getTempDirectoryPath(), "Capture.avi");
data = Uri.fromFile(movie);
// Create a file object from the uri
JSONObject mediaFile = createMediaFile(data);
if (mediaFile == null) {
pendingRequests.resolveWithFailure(req, createErrorObject(CAPTURE_INTERNAL_ERR, "Error: no mediaFile created from " + data));
return;
}

// create a file object from the uri
if(data == null) {
pendingRequests.resolveWithFailure(req, createErrorObject(CAPTURE_NO_MEDIA_FILES, "Error: data is null"));
}
else {
req.results.put(createMediaFile(data));
req.results.put(mediaFile);

if (req.results.length() >= req.limit) {
// Send Uri back to JavaScript for viewing video
pendingRequests.resolveWithSuccess(req);
} else {
// still need to capture more video clips
captureVideo(req);
}
if (req.results.length() >= req.limit) {
// Send Uri back to JavaScript for viewing video
pendingRequests.resolveWithSuccess(req);
} else {
// still need to capture more video clips
captureVideo(req);
}
}

Expand All @@ -465,6 +467,10 @@ public void onVideoActivityResult(Request req, Intent intent) {
*/
private JSONObject createMediaFile(Uri data) {
File fp = webView.getResourceApi().mapUriToFile(data);
if (fp == null) {
return null;
}

JSONObject obj = new JSONObject();

Class webViewClass = webView.getClass();
Expand Down