summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--gallerycommon/src/com/android/gallery3d/common/AsyncTaskUtil.java66
-rw-r--r--src/com/android/gallery3d/provider/GalleryProvider.java38
-rw-r--r--src/com/android/gallery3d/ui/TileImageViewAdapter.java2
3 files changed, 101 insertions, 5 deletions
diff --git a/gallerycommon/src/com/android/gallery3d/common/AsyncTaskUtil.java b/gallerycommon/src/com/android/gallery3d/common/AsyncTaskUtil.java
new file mode 100644
index 000000000..b70c4d365
--- /dev/null
+++ b/gallerycommon/src/com/android/gallery3d/common/AsyncTaskUtil.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2012 The Android Open Source 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.
+ */
+
+package com.android.gallery3d.common;
+
+import android.os.AsyncTask;
+import android.os.Build;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.concurrent.Executor;
+
+/**
+ * Helper class to execute an AsyncTask in parallel if SDK version is 11 or newer.
+ */
+public class AsyncTaskUtil {
+ private static Method sMethodExecuteOnExecutor;
+ private static Executor sExecutor;
+ static {
+ if (Build.VERSION.SDK_INT >= 11) {
+ try {
+ sExecutor = (Executor) AsyncTask.class.getField("THREAD_POOL_EXECUTOR")
+ .get(null);
+ sMethodExecuteOnExecutor = AsyncTask.class.getMethod(
+ "executeOnExecutor", Executor.class, Object[].class);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ } catch (NoSuchFieldException e) {
+ throw new RuntimeException(e);
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ public static <Param> void executeInParallel(AsyncTask<Param, ?, ?> task, Param... params) {
+ if (Build.VERSION.SDK_INT < 11) {
+ task.execute(params);
+ } else {
+ try {
+ sMethodExecuteOnExecutor.invoke(task, sExecutor, params);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ } catch (InvocationTargetException e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+
+ private AsyncTaskUtil() {
+ }
+}
+
diff --git a/src/com/android/gallery3d/provider/GalleryProvider.java b/src/com/android/gallery3d/provider/GalleryProvider.java
index 79ec66be8..45f47a42c 100644
--- a/src/com/android/gallery3d/provider/GalleryProvider.java
+++ b/src/com/android/gallery3d/provider/GalleryProvider.java
@@ -22,13 +22,14 @@ import android.content.Context;
import android.database.Cursor;
import android.database.MatrixCursor;
import android.net.Uri;
+import android.os.AsyncTask;
import android.os.Binder;
-import android.os.Bundle;
import android.os.ParcelFileDescriptor;
import android.provider.MediaStore.Images.ImageColumns;
import android.util.Log;
import com.android.gallery3d.app.GalleryApp;
+import com.android.gallery3d.common.AsyncTaskUtil;
import com.android.gallery3d.common.Utils;
import com.android.gallery3d.data.DataManager;
import com.android.gallery3d.data.MediaItem;
@@ -211,7 +212,7 @@ public class GalleryProvider extends ContentProvider {
if (PicasaSource.isPicasaImage(object)) {
return PicasaSource.openFile(getContext(), object, mode);
} else if (object instanceof MtpImage) {
- return openPipeHelper(uri, null, null, null,
+ return openPipeHelper(null,
new MtpPipeDataWriter((MtpImage) object));
} else {
throw new FileNotFoundException("unspported type: " + object);
@@ -226,6 +227,34 @@ public class GalleryProvider extends ContentProvider {
throw new UnsupportedOperationException();
}
+ private static interface PipeDataWriter<T> {
+ void writeDataToPipe(ParcelFileDescriptor output, T args);
+ }
+
+ // Modified from ContentProvider.openPipeHelper. We are target at API LEVEL 10.
+ // But openPipeHelper is available in API LEVEL 11.
+ private static <T> ParcelFileDescriptor openPipeHelper(
+ final T args, final PipeDataWriter<T> func) throws FileNotFoundException {
+ try {
+ final ParcelFileDescriptor[] pipe = ParcelFileDescriptor.createPipe();
+ AsyncTask<Object, Object, Object> task = new AsyncTask<Object, Object, Object>() {
+ @Override
+ protected Object doInBackground(Object... params) {
+ try {
+ func.writeDataToPipe(pipe[1], args);
+ return null;
+ } finally {
+ Utils.closeSilently(pipe[1]);
+ }
+ }
+ };
+ AsyncTaskUtil.executeInParallel(task, (Object[]) null);
+ return pipe[0];
+ } catch (IOException e) {
+ throw new FileNotFoundException("failure making pipe");
+ }
+ }
+
private final class MtpPipeDataWriter implements PipeDataWriter<Object> {
private final MtpImage mImage;
@@ -234,14 +263,13 @@ public class GalleryProvider extends ContentProvider {
}
@Override
- public void writeDataToPipe(ParcelFileDescriptor output,
- Uri uri, String mimeType, Bundle opts, Object args) {
+ public void writeDataToPipe(ParcelFileDescriptor output, Object args) {
OutputStream os = null;
try {
os = new ParcelFileDescriptor.AutoCloseOutputStream(output);
os.write(mImage.getImageData());
} catch (IOException e) {
- Log.w(TAG, "fail to download: " + uri, e);
+ Log.w(TAG, "fail to download: " + mImage.toString(), e);
} finally {
Utils.closeSilently(os);
}
diff --git a/src/com/android/gallery3d/ui/TileImageViewAdapter.java b/src/com/android/gallery3d/ui/TileImageViewAdapter.java
index 4865e5c67..a14df754a 100644
--- a/src/com/android/gallery3d/ui/TileImageViewAdapter.java
+++ b/src/com/android/gallery3d/ui/TileImageViewAdapter.java
@@ -16,6 +16,7 @@
package com.android.gallery3d.ui;
+import android.annotation.TargetApi;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
@@ -107,6 +108,7 @@ public class TileImageViewAdapter implements TileImageView.Model {
//
// As a result, we should decode region (50-6, 50-6, 250+6, 250+6) or
// (44, 44, 256, 256) from the original photo and down sample it to 106.
+ @TargetApi(ApiHelper.VERSION_CODES.HONEYCOMB)
@Override
public Bitmap getTile(int level, int x, int y, int tileSize,
int borderSize, BitmapPool pool) {