diff options
author | Danesh M <daneshm90@gmail.com> | 2015-09-09 17:51:27 -0700 |
---|---|---|
committer | Gerrit Code Review <gerrit@cyanogenmod.org> | 2015-09-14 10:47:17 -0700 |
commit | a5aa75d6ac958822e145b61e7c475bd1dc1b5260 (patch) | |
tree | 2bdad1ca02b17e4fef67d0fa30bc323ebd9cfb5e | |
parent | 78aee6b67dd0e9483a4994bef8b7cb4c1a9fdb78 (diff) | |
download | android_packages_apps_Gallery2-a5aa75d6ac958822e145b61e7c475bd1dc1b5260.tar.gz android_packages_apps_Gallery2-a5aa75d6ac958822e145b61e7c475bd1dc1b5260.tar.bz2 android_packages_apps_Gallery2-a5aa75d6ac958822e145b61e7c475bd1dc1b5260.zip |
Gallery3d : Fix CROP_ACTION for third party apps
Certain apps such as google photos, don't respect
return-data true, since the bitmap could be very large.
Switch to a file provider to pass the external apps a uri
to write cropped results to.
Change-Id: I9ec8b8defaffa3d9fa0c2cdfd68422eeff5aef84
-rw-r--r-- | AndroidManifest.xml | 9 | ||||
-rw-r--r-- | res/xml/file_paths.xml | 18 | ||||
-rw-r--r-- | slim_manifest/AndroidManifest.xml | 10 | ||||
-rw-r--r-- | src/com/android/gallery3d/filtershow/cache/ImageLoader.java | 2 | ||||
-rw-r--r-- | src/com/android/gallery3d/gadget/WidgetConfigure.java | 176 |
5 files changed, 179 insertions, 36 deletions
diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 88a218ca8..216996017 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -436,5 +436,14 @@ android:label="@string/movie_view_label" android:configChanges="orientation|keyboardHidden|screenSize|mnc|mcc"> </activity> + <provider + android:name="android.support.v4.content.FileProvider" + android:authorities="com.android.gallery3d.fileprovider" + android:exported="false" + android:grantUriPermissions="true"> + <meta-data + android:name="android.support.FILE_PROVIDER_PATHS" + android:resource="@xml/file_paths" /> + </provider> </application> </manifest> diff --git a/res/xml/file_paths.xml b/res/xml/file_paths.xml new file mode 100644 index 000000000..28d186477 --- /dev/null +++ b/res/xml/file_paths.xml @@ -0,0 +1,18 @@ +<!-- + Copyright (C) 2012-2015 The CyanogenMod Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<paths xmlns:android="http://schemas.android.com/apk/res/android"> + <cache-path name="cropped_image"/> +</paths> diff --git a/slim_manifest/AndroidManifest.xml b/slim_manifest/AndroidManifest.xml index e515319e9..aae3467bc 100644 --- a/slim_manifest/AndroidManifest.xml +++ b/slim_manifest/AndroidManifest.xml @@ -233,6 +233,14 @@ </intent-filter> </activity> <service android:name="com.android.gallery3d.app.BatchService" /> - + <provider + android:name="android.support.v4.content.FileProvider" + android:authorities="com.android.gallery3d.fileprovider" + android:exported="false" + android:grantUriPermissions="true"> + <meta-data + android:name="android.support.FILE_PROVIDER_PATHS" + android:resource="@xml/file_paths" /> + </provider> </application> </manifest> diff --git a/src/com/android/gallery3d/filtershow/cache/ImageLoader.java b/src/com/android/gallery3d/filtershow/cache/ImageLoader.java index ea559e569..30d535d77 100644 --- a/src/com/android/gallery3d/filtershow/cache/ImageLoader.java +++ b/src/com/android/gallery3d/filtershow/cache/ImageLoader.java @@ -108,7 +108,7 @@ public final class ImageLoader { new String[] { MediaStore.Images.ImageColumns.ORIENTATION }, null, null, null); if (cursor != null && cursor.moveToNext()) { - int ori = cursor.getInt(0); + int ori = cursor.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.ORIENTATION); switch (ori) { case 90: return ORI_ROTATE_90; diff --git a/src/com/android/gallery3d/gadget/WidgetConfigure.java b/src/com/android/gallery3d/gadget/WidgetConfigure.java index 2a4c6cfe4..b9a3fec23 100644 --- a/src/com/android/gallery3d/gadget/WidgetConfigure.java +++ b/src/com/android/gallery3d/gadget/WidgetConfigure.java @@ -18,11 +18,16 @@ package com.android.gallery3d.gadget; import android.app.Activity; import android.appwidget.AppWidgetManager; +import android.content.ClipData; import android.content.Intent; import android.content.res.Resources; import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.net.Uri; +import android.os.AsyncTask; import android.os.Bundle; +import android.provider.MediaStore; +import android.support.v4.content.FileProvider; import android.util.Log; import android.widget.RemoteViews; @@ -38,6 +43,14 @@ import com.android.gallery3d.data.Path; import com.android.gallery3d.filtershow.crop.CropActivity; import com.android.gallery3d.filtershow.crop.CropExtras; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + public class WidgetConfigure extends Activity { @SuppressWarnings("unused") private static final String TAG = "WidgetConfigure"; @@ -61,6 +74,7 @@ public class WidgetConfigure extends Activity { private int mAppWidgetId = -1; private Uri mPickedItem; + private Uri mCropSrc, mCropDst; @Override protected void onCreate(Bundle savedState) { @@ -116,48 +130,142 @@ public class WidgetConfigure extends Activity { } else if (requestCode == REQUEST_GET_PHOTO) { setChoosenPhoto(data); } else if (requestCode == REQUEST_CROP_IMAGE) { - setPhotoWidget(data); + setPhotoWidget(); } else { throw new AssertionError("unknown request: " + requestCode); } } - private void setPhotoWidget(Intent data) { - // Store the cropped photo in our database - Bitmap bitmap = (Bitmap) data.getParcelableExtra("data"); - WidgetDatabaseHelper helper = new WidgetDatabaseHelper(this); + private void setPhotoWidget() { + AsyncTask.execute(new Runnable() { + @Override + public void run() { + Bitmap bitmap = null; + InputStream stream = null; + try { + stream = WidgetConfigure.this.getContentResolver() + .openInputStream(mCropDst); + if (stream != null) { + bitmap = BitmapFactory.decodeStream(stream); + } + } catch (FileNotFoundException e) { + e.printStackTrace(); + } finally { + if (stream != null) { + try { + stream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + getContentResolver().delete(mCropSrc, null, null); + getContentResolver().delete(mCropDst, null, null); + } + if (bitmap == null) { + setResult(Activity.RESULT_CANCELED); + finish(); + return; + } + WidgetDatabaseHelper helper = new WidgetDatabaseHelper(WidgetConfigure.this); + try { + helper.setPhoto(mAppWidgetId, mPickedItem, bitmap); + updateWidgetAndFinish(helper.getEntry(mAppWidgetId)); + } finally { + helper.close(); + } + } + }); + } + + private void setChoosenPhoto(final Intent data) { + AsyncTask.execute(new Runnable() { + @Override + public void run() { + Resources res = getResources(); + + float width = res.getDimension(R.dimen.appwidget_width); + float height = res.getDimension(R.dimen.appwidget_height); + + // We try to crop a larger image (by scale factor), but there is still + // a bound on the binder limit. + float scale = Math.min(WIDGET_SCALE_FACTOR, + MAX_WIDGET_SIDE / Math.max(width, height)); + + int widgetWidth = Math.round(width * scale); + int widgetHeight = Math.round(height * scale); + + File cropSrc = new File(getCacheDir(), "crop_source.png"); + File cropDst = new File(getCacheDir(), "crop_dest.png"); + mPickedItem = data.getData(); + if (!copyUriToFile(mPickedItem, cropSrc)) { + setResult(Activity.RESULT_CANCELED); + finish(); + return; + } + + mCropSrc = FileProvider.getUriForFile(WidgetConfigure.this, + "com.android.gallery3d.fileprovider", + new File(cropSrc.getAbsolutePath())); + mCropDst = FileProvider.getUriForFile(WidgetConfigure.this, + "com.android.gallery3d.fileprovider", + new File(cropDst.getAbsolutePath())); + + Intent request = new Intent(CropActivity.CROP_ACTION) + .putExtra(CropExtras.KEY_OUTPUT_X, widgetWidth) + .putExtra(CropExtras.KEY_OUTPUT_Y, widgetHeight) + .putExtra(CropExtras.KEY_ASPECT_X, widgetWidth) + .putExtra(CropExtras.KEY_ASPECT_Y, widgetHeight) + .putExtra(CropExtras.KEY_SCALE_UP_IF_NEEDED, true) + .putExtra(CropExtras.KEY_SCALE, true) + .putExtra(CropExtras.KEY_RETURN_DATA, false) + .setDataAndType(mCropSrc, "image/*") + .addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION | + Intent.FLAG_GRANT_READ_URI_PERMISSION); + request.putExtra(MediaStore.EXTRA_OUTPUT, mCropDst); + request.setClipData(ClipData.newRawUri(MediaStore.EXTRA_OUTPUT, mCropDst)); + startActivityForResult(request, REQUEST_CROP_IMAGE); + } + }); + } + + public boolean copyUriToFile(Uri inUri, File dst) { + boolean isSuccessful = false; + InputStream in = null; + OutputStream out = null; try { - helper.setPhoto(mAppWidgetId, mPickedItem, bitmap); - updateWidgetAndFinish(helper.getEntry(mAppWidgetId)); + in = getContentResolver().openInputStream(inUri); + out = new FileOutputStream(dst); + + byte[] buf = new byte[1024]; + + try { + for (int len; (len = in.read(buf)) > 0; ) { + out.write(buf, 0, len); + } + isSuccessful = true; + } catch (IOException e) { + // ignore + } + + } catch (FileNotFoundException fnf) { + // ignore } finally { - helper.close(); + if (in != null) { + try { + in.close(); + } catch (IOException e) { + // ignore + } + } + if (out != null) { + try { + out.close(); + } catch (IOException e) { + // ignore + } + } } - } - - private void setChoosenPhoto(Intent data) { - Resources res = getResources(); - - float width = res.getDimension(R.dimen.appwidget_width); - float height = res.getDimension(R.dimen.appwidget_height); - - // We try to crop a larger image (by scale factor), but there is still - // a bound on the binder limit. - float scale = Math.min(WIDGET_SCALE_FACTOR, - MAX_WIDGET_SIDE / Math.max(width, height)); - - int widgetWidth = Math.round(width * scale); - int widgetHeight = Math.round(height * scale); - - mPickedItem = data.getData(); - Intent request = new Intent(CropActivity.CROP_ACTION, mPickedItem) - .putExtra(CropExtras.KEY_OUTPUT_X, widgetWidth) - .putExtra(CropExtras.KEY_OUTPUT_Y, widgetHeight) - .putExtra(CropExtras.KEY_ASPECT_X, widgetWidth) - .putExtra(CropExtras.KEY_ASPECT_Y, widgetHeight) - .putExtra(CropExtras.KEY_SCALE_UP_IF_NEEDED, true) - .putExtra(CropExtras.KEY_SCALE, true) - .putExtra(CropExtras.KEY_RETURN_DATA, true); - startActivityForResult(request, REQUEST_CROP_IMAGE); + return isSuccessful; } private void setChoosenAlbum(Intent data) { |