diff options
author | qinmin <qinmin@chromium.org> | 2015-12-11 16:19:53 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-12-12 00:20:43 +0000 |
commit | ad157151d2ed880ff783b6b68a7663b6aa49ba07 (patch) | |
tree | 689b24e9631560af381a2acfbcb9bf14524a033d | |
parent | 42b13e3af4be21f043908bccca0a8b40bce22b54 (diff) | |
download | chromium_src-ad157151d2ed880ff783b6b68a7663b6aa49ba07.zip chromium_src-ad157151d2ed880ff783b6b68a7663b6aa49ba07.tar.gz chromium_src-ad157151d2ed880ff783b6b68a7663b6aa49ba07.tar.bz2 |
Fix strict mode violation in SelectFileDialog.java
This change introduces an async task to launch the select file intent.
BUG=562173
Review URL: https://codereview.chromium.org/1507153002
Cr-Commit-Position: refs/heads/master@{#364844}
-rw-r--r-- | base/android/java/src/org/chromium/base/ContentUriUtils.java | 14 | ||||
-rw-r--r-- | ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java | 87 |
2 files changed, 60 insertions, 41 deletions
diff --git a/base/android/java/src/org/chromium/base/ContentUriUtils.java b/base/android/java/src/org/chromium/base/ContentUriUtils.java index 528af8f..5448aa0 100644 --- a/base/android/java/src/org/chromium/base/ContentUriUtils.java +++ b/base/android/java/src/org/chromium/base/ContentUriUtils.java @@ -23,6 +23,9 @@ public abstract class ContentUriUtils { private static final String TAG = "ContentUriUtils"; private static FileProviderUtil sFileProviderUtil; + // Guards access to sFileProviderUtil. + private static final Object sLock = new Object(); + /** * Provides functionality to translate a file into a content URI for use * with a content provider. @@ -40,13 +43,16 @@ public abstract class ContentUriUtils { private ContentUriUtils() {} public static void setFileProviderUtil(FileProviderUtil util) { - sFileProviderUtil = util; + synchronized (sLock) { + sFileProviderUtil = util; + } } public static Uri getContentUriFromFile(Context context, File file) { - ThreadUtils.assertOnUiThread(); - if (sFileProviderUtil != null) { - return sFileProviderUtil.getContentUriFromFile(context, file); + synchronized (sLock) { + if (sFileProviderUtil != null) { + return sFileProviderUtil.getContentUriFromFile(context, file); + } } return null; } diff --git a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java index 0e177f6..6113e63 100644 --- a/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java +++ b/ui/android/java/src/org/chromium/ui/base/SelectFileDialog.java @@ -15,12 +15,12 @@ import android.content.pm.PackageManager; import android.net.Uri; import android.os.AsyncTask; import android.os.Build; -import android.os.StrictMode; import android.provider.MediaStore; import android.text.TextUtils; import android.util.Log; import org.chromium.base.ContentUriUtils; +import org.chromium.base.ThreadUtils; import org.chromium.base.VisibleForTesting; import org.chromium.base.annotations.CalledByNative; import org.chromium.base.annotations.JNINamespace; @@ -122,28 +122,34 @@ public class SelectFileDialog } } + /** + * Called to launch an intent to allow user to select files. + */ private void launchSelectFileIntent() { boolean hasCameraPermission = mWindowAndroid.hasPermission(Manifest.permission.CAMERA); - boolean hasAudioPermission = - mWindowAndroid.hasPermission(Manifest.permission.RECORD_AUDIO); - - Intent camera = null; if (mSupportsImageCapture && hasCameraPermission) { - camera = getCameraIntent(mWindowAndroid.getApplicationContext()); - // The camera intent can be null if we are unable to generate the output URI. If this - // occurs while we are in camera capture mode, early exit as there is nothing we can - // do at this point. - if (camera == null && captureCamera()) { - onFileNotSelected(); - return; - } + // GetCameraIntentTask will call LaunchSelectFileWithCameraIntent later. + new GetCameraIntentTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR); + } else { + launchSelectFileWithCameraIntent(hasCameraPermission, null); } + } + /** + * Called to launch an intent to allow user to select files. If |camera| is null, + * the select file dialog shouldn't include any files from the camera. Otherwise, user + * is allowed to choose files from the camera. + * @param hasCameraPermission Whether accessing camera is allowed. + * @param camera Intent for selecting files from camera. + */ + private void launchSelectFileWithCameraIntent(boolean hasCameraPermission, Intent camera) { Intent camcorder = null; if (mSupportsVideoCapture && hasCameraPermission) { camcorder = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); } + boolean hasAudioPermission = + mWindowAndroid.hasPermission(Manifest.permission.RECORD_AUDIO); Intent soundRecorder = null; if (mSupportsAudioCapture && hasAudioPermission) { soundRecorder = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION); @@ -204,25 +210,37 @@ public class SelectFileDialog } } - private Intent getCameraIntent(Context context) { - Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); - camera.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION - | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); - try { - mCameraOutputUri = - UiUtils.getUriForImageCaptureFile(context, getFileForImageCapture(context)); - } catch (IOException e) { - Log.e(TAG, "Cannot retrieve content uri from file", e); + private class GetCameraIntentTask extends AsyncTask<Void, Void, Uri> { + @Override + public Uri doInBackground(Void...voids) { + try { + Context context = mWindowAndroid.getApplicationContext(); + return UiUtils.getUriForImageCaptureFile(context, getFileForImageCapture(context)); + } catch (IOException e) { + Log.e(TAG, "Cannot retrieve content uri from file", e); + return null; + } } - if (mCameraOutputUri == null) return null; + @Override + protected void onPostExecute(Uri result) { + mCameraOutputUri = result; + if (mCameraOutputUri == null && captureCamera()) { + onFileNotSelected(); + return; + } - camera.putExtra(MediaStore.EXTRA_OUTPUT, mCameraOutputUri); - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { - camera.setClipData(ClipData.newUri( - context.getContentResolver(), UiUtils.IMAGE_FILE_PATH, mCameraOutputUri)); + Intent camera = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); + camera.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION + | Intent.FLAG_GRANT_WRITE_URI_PERMISSION); + camera.putExtra(MediaStore.EXTRA_OUTPUT, mCameraOutputUri); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { + camera.setClipData(ClipData.newUri( + mWindowAndroid.getApplicationContext().getContentResolver(), + UiUtils.IMAGE_FILE_PATH, mCameraOutputUri)); + } + launchSelectFileWithCameraIntent(true, camera); } - return camera; } /** @@ -234,15 +252,10 @@ public class SelectFileDialog * @return file path for the captured image to be stored. */ private File getFileForImageCapture(Context context) throws IOException { - // Temporarily allowing disk access while fixing. TODO: http://crbug.com/562173 - StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); - try { - File photoFile = File.createTempFile(String.valueOf(System.currentTimeMillis()), ".jpg", - UiUtils.getDirectoryForImageCapture(context)); - return photoFile; - } finally { - StrictMode.setThreadPolicy(oldPolicy); - } + assert !ThreadUtils.runningOnUiThread(); + File photoFile = File.createTempFile(String.valueOf(System.currentTimeMillis()), ".jpg", + UiUtils.getDirectoryForImageCapture(context)); + return photoFile; } /** |