diff options
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) { |