From 126b5b3a771fbcf1a4acd1700c8cfa22975f22df Mon Sep 17 00:00:00 2001 From: Tao Bai Date: Wed, 3 Sep 2014 14:00:38 -0700 Subject: Adapt AOSP browser to use the revised createIntent() API BUG:17253647,16624450 Change-Id: I0b58d945564923c4ed0fc9377a3f6267d8080c2f --- src/com/android/browser/UploadHandler.java | 117 +++++++++++++++++++++++++++-- 1 file changed, 110 insertions(+), 7 deletions(-) (limited to 'src/com/android/browser') diff --git a/src/com/android/browser/UploadHandler.java b/src/com/android/browser/UploadHandler.java index beaaf5f..c20fbf6 100644 --- a/src/com/android/browser/UploadHandler.java +++ b/src/com/android/browser/UploadHandler.java @@ -20,29 +20,31 @@ import android.app.Activity; import android.content.ActivityNotFoundException; import android.content.Intent; import android.net.Uri; -import android.os.Environment; import android.provider.MediaStore; +import android.support.v4.content.FileProvider; import android.webkit.WebChromeClient.FileChooserParams; -import android.webkit.WebChromeClient.UploadHelper; import android.webkit.ValueCallback; import android.widget.Toast; import java.io.File; -import java.util.Vector; /** * Handle the file upload. This does not support selecting multiple files yet. */ public class UploadHandler { + private final static String IMAGE_MIME_TYPE = "image/*"; + private final static String VIDEO_MIME_TYPE = "video/*"; + private final static String AUDIO_MIME_TYPE = "audio/*"; /* * The Object used to inform the WebView of the file to upload. */ private ValueCallback mUploadMessage; - private UploadHelper mUploadHelper; private boolean mHandled; private Controller mController; + private FileChooserParams mParams; + private Uri mCapturedMedia; public UploadHandler(Controller controller) { mController = controller; @@ -53,7 +55,11 @@ public class UploadHandler { } void onResult(int resultCode, Intent intent) { - mUploadMessage.onReceiveValue(mUploadHelper.parseResult(resultCode, intent)); + Uri[] uris; + // As the media capture is always supported, we can't use + // FileChooserParams.parseResult(). + uris = parseResult(resultCode, intent); + mUploadMessage.onReceiveValue(uris); mHandled = true; } @@ -65,8 +71,46 @@ public class UploadHandler { } mUploadMessage = callback; - mUploadHelper = fileChooserParams.getUploadHelper(); - startActivity(mUploadHelper.buildIntent()); + mParams = fileChooserParams; + Intent[] captureIntents = createCaptureIntent(); + assert(captureIntents != null && captureIntents.length > 0); + Intent intent = null; + // Go to the media capture directly if capture is specified, this is the + // preferred way. + if (fileChooserParams.isCaptureEnabled() && captureIntents.length == 1) { + intent = captureIntents[0]; + } else { + intent = new Intent(Intent.ACTION_CHOOSER); + intent.putExtra(Intent.EXTRA_INITIAL_INTENTS, captureIntents); + intent.putExtra(Intent.EXTRA_INTENT, fileChooserParams.createIntent()); + } + startActivity(intent); + } + + private Uri[] parseResult(int resultCode, Intent intent) { + if (resultCode == Activity.RESULT_CANCELED) { + return null; + } + Uri result = intent == null || resultCode != Activity.RESULT_OK ? null + : intent.getData(); + + // As we ask the camera to save the result of the user taking + // a picture, the camera application does not return anything other + // than RESULT_OK. So we need to check whether the file we expected + // was written to disk in the in the case that we + // did not get an intent returned but did get a RESULT_OK. If it was, + // we assume that this result has came back from the camera. + if (result == null && intent == null && resultCode == Activity.RESULT_OK + && mCapturedMedia != null) { + result = mCapturedMedia; + } + + Uri[] uris = null; + if (result != null) { + uris = new Uri[1]; + uris[0] = result; + } + return uris; } private void startActivity(Intent intent) { @@ -79,4 +123,63 @@ public class UploadHandler { Toast.LENGTH_LONG).show(); } } + + private Intent[] createCaptureIntent() { + try { + File mediaPath = new File(mController.getActivity().getFilesDir(), "captured_media"); + if (!mediaPath.exists() && !mediaPath.mkdir()) { + throw new RuntimeException("Folder cannot be created."); + } + File mediaFile = File.createTempFile( + String.valueOf(System.currentTimeMillis()), null, mediaPath); + mCapturedMedia = FileProvider.getUriForFile(mController.getActivity(), + "com.android.browser-classic.file", mediaFile); + } catch (java.io.IOException e) { + throw new RuntimeException(e); + } + String mimeType = "*/*"; + String[] acceptTypes = mParams.getAcceptTypes(); + if ( acceptTypes != null && acceptTypes.length > 0) { + mimeType = acceptTypes[0]; + } + Intent[] intents; + if (mimeType.equals(IMAGE_MIME_TYPE)) { + intents = new Intent[1]; + intents[0] = createCameraIntent(); + } else if (mimeType.equals(VIDEO_MIME_TYPE)) { + intents = new Intent[1]; + intents[0] = createCamcorderIntent(); + } else if (mimeType.equals(AUDIO_MIME_TYPE)) { + intents = new Intent[1]; + intents[0] = createSoundRecorderIntent(); + } else { + intents = new Intent[3]; + intents[0] = createCameraIntent(); + intents[1] = createCamcorderIntent(); + intents[2] = createSoundRecorderIntent(); + } + return intents; + } + + private Intent createCameraIntent() { + if (mCapturedMedia == null) throw new IllegalArgumentException(); + Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | + Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + intent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedMedia); + return intent; + } + + private Intent createCamcorderIntent() { + if (mCapturedMedia == null) throw new IllegalArgumentException(); + Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); + intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | + Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + intent.putExtra(MediaStore.EXTRA_OUTPUT, mCapturedMedia); + return intent; + } + + private Intent createSoundRecorderIntent() { + return new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION); + } } -- cgit v1.1