summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDanesh M <daneshm90@gmail.com>2015-09-09 17:51:27 -0700
committerGerrit Code Review <gerrit@cyanogenmod.org>2015-09-14 10:47:17 -0700
commita5aa75d6ac958822e145b61e7c475bd1dc1b5260 (patch)
tree2bdad1ca02b17e4fef67d0fa30bc323ebd9cfb5e
parent78aee6b67dd0e9483a4994bef8b7cb4c1a9fdb78 (diff)
downloadandroid_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.xml9
-rw-r--r--res/xml/file_paths.xml18
-rw-r--r--slim_manifest/AndroidManifest.xml10
-rw-r--r--src/com/android/gallery3d/filtershow/cache/ImageLoader.java2
-rw-r--r--src/com/android/gallery3d/gadget/WidgetConfigure.java176
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) {