summaryrefslogtreecommitdiffstats
path: root/src/com/android/gallery3d/data
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/gallery3d/data')
-rw-r--r--src/com/android/gallery3d/data/DataManager.java6
-rw-r--r--src/com/android/gallery3d/data/LocalImage.java89
-rw-r--r--src/com/android/gallery3d/data/MediaItem.java8
-rw-r--r--src/com/android/gallery3d/data/MediaObject.java33
-rw-r--r--src/com/android/gallery3d/data/PanoramaMetadataJob.java40
-rw-r--r--src/com/android/gallery3d/data/UriImage.java89
6 files changed, 192 insertions, 73 deletions
diff --git a/src/com/android/gallery3d/data/DataManager.java b/src/com/android/gallery3d/data/DataManager.java
index 95954e59a..3d2c0c2f0 100644
--- a/src/com/android/gallery3d/data/DataManager.java
+++ b/src/com/android/gallery3d/data/DataManager.java
@@ -250,6 +250,12 @@ public class DataManager {
return getMediaObject(path).getSupportedOperations();
}
+ // getAll will cause this call to wait if any of the operations
+ // are expensive to compute. Do not call in UI thread.
+ public int getSupportedOperations(Path path, boolean getAll) {
+ return getMediaObject(path).getSupportedOperations(getAll);
+ }
+
public void delete(Path path) {
getMediaObject(path).delete();
}
diff --git a/src/com/android/gallery3d/data/LocalImage.java b/src/com/android/gallery3d/data/LocalImage.java
index 5d6d39dcf..dba6b68eb 100644
--- a/src/com/android/gallery3d/data/LocalImage.java
+++ b/src/com/android/gallery3d/data/LocalImage.java
@@ -36,8 +36,11 @@ import com.android.gallery3d.app.GalleryApp;
import com.android.gallery3d.app.StitchingProgressManager;
import com.android.gallery3d.common.ApiHelper;
import com.android.gallery3d.common.BitmapUtils;
+import com.android.gallery3d.util.Future;
+import com.android.gallery3d.util.FutureListener;
import com.android.gallery3d.util.GalleryUtils;
import com.android.gallery3d.util.LightCycleHelper;
+import com.android.gallery3d.util.LightCycleHelper.PanoramaMetadata;
import com.android.gallery3d.util.ThreadPool.Job;
import com.android.gallery3d.util.ThreadPool.JobContext;
import com.android.gallery3d.util.UpdateHelper;
@@ -101,11 +104,11 @@ public class LocalImage extends LocalMediaItem {
public int rotation;
- private boolean mUsePanoramaViewer;
- private boolean mUsePanoramaViewerInitialized;
-
- private boolean mIsPanorama360;
- private boolean mIsPanorama360Initialized;
+ private Object mLock = new Object();
+ private Future<PanoramaMetadata> mGetPanoMetadataTask;
+ private boolean mPanoramaMetadataInitialized;
+ private PanoramaMetadata mPanoramaMetadata;
+ private SupportedOperationsListener mListener;
public LocalImage(Path path, GalleryApp application, Cursor cursor) {
super(path, nextVersionNumber());
@@ -255,9 +258,9 @@ public class LocalImage extends LocalMediaItem {
operation |= SUPPORT_SHOW_ON_MAP;
}
- if (usePanoramaViewer()) {
+ if (mPanoramaMetadata != null && mPanoramaMetadata.mUsePanoramaViewer) {
operation |= SUPPORT_PANORAMA;
- if (isPanorama360()) {
+ if (mPanoramaMetadata.mIsPanorama360) {
operation |= SUPPORT_PANORAMA360;
// disable destructive rotate and crop for 360 degree panorama
operation &= ~(SUPPORT_ROTATE | SUPPORT_CROP);
@@ -267,6 +270,55 @@ public class LocalImage extends LocalMediaItem {
}
@Override
+ public int getSupportedOperations(boolean getAll) {
+ synchronized (mLock) {
+ if (getAll && !mPanoramaMetadataInitialized) {
+ if (mGetPanoMetadataTask == null) {
+ mGetPanoMetadataTask = getThreadPool().submit(
+ new PanoramaMetadataJob(mApplication.getAndroidContext(),
+ getContentUri()));
+ }
+ mPanoramaMetadata = mGetPanoMetadataTask.get();
+ mPanoramaMetadataInitialized = true;
+ }
+ }
+ return getSupportedOperations();
+ }
+
+ @Override
+ public void setSupportedOperationsListener(SupportedOperationsListener l) {
+ synchronized (mLock) {
+ if (mPanoramaMetadataInitialized) return; // no more updates
+
+ if (l == null) {
+ if (mGetPanoMetadataTask != null) {
+ mGetPanoMetadataTask.cancel();
+ mGetPanoMetadataTask = null;
+ }
+ } else {
+ if (mGetPanoMetadataTask == null) {
+ mGetPanoMetadataTask = getThreadPool().submit(
+ new PanoramaMetadataJob(mApplication.getAndroidContext(),
+ getContentUri()),
+ new FutureListener<PanoramaMetadata>() {
+ @Override
+ public void onFutureDone(Future<PanoramaMetadata> future) {
+ mGetPanoMetadataTask = null;
+ if (future.isCancelled()) return;
+ mPanoramaMetadata = future.get();
+ mPanoramaMetadataInitialized = true;
+ if (mListener != null) {
+ mListener.onChange(getSupportedOperations());
+ }
+ }
+ });
+ }
+ }
+ mListener = l;
+ }
+ }
+
+ @Override
public void delete() {
GalleryUtils.assertNotInRenderThread();
Uri baseUri = Images.Media.EXTERNAL_CONTENT_URI;
@@ -360,27 +412,4 @@ public class LocalImage extends LocalMediaItem {
public String getFilePath() {
return filePath;
}
-
- @Override
- public boolean usePanoramaViewer() {
- if (!mUsePanoramaViewerInitialized) {
- Context context = mApplication.getAndroidContext();
- mUsePanoramaViewer = LightCycleHelper.hasLightCycleView(context)
- && LightCycleHelper.isPanorama(mApplication.getContentResolver(),
- getContentUri());
- mUsePanoramaViewerInitialized = true;
- }
- return mUsePanoramaViewer;
- }
-
- @Override
- public boolean isPanorama360() {
- // cache flag for faster access
- if (!mIsPanorama360Initialized) {
- mIsPanorama360 = LightCycleHelper.isPanorama360(
- mApplication.getAndroidContext(), getContentUri());
- mIsPanorama360Initialized = true;
- }
- return mIsPanorama360;
- }
}
diff --git a/src/com/android/gallery3d/data/MediaItem.java b/src/com/android/gallery3d/data/MediaItem.java
index da59abeef..19084d41e 100644
--- a/src/com/android/gallery3d/data/MediaItem.java
+++ b/src/com/android/gallery3d/data/MediaItem.java
@@ -103,14 +103,6 @@ public abstract class MediaItem extends MediaObject {
return "";
}
- public boolean usePanoramaViewer() {
- return false;
- }
-
- public boolean isPanorama360() {
- return false;
- }
-
// Returns width and height of the media item.
// Returns 0, 0 if the information is not available.
public abstract int getWidth();
diff --git a/src/com/android/gallery3d/data/MediaObject.java b/src/com/android/gallery3d/data/MediaObject.java
index a16b9666d..382a5c792 100644
--- a/src/com/android/gallery3d/data/MediaObject.java
+++ b/src/com/android/gallery3d/data/MediaObject.java
@@ -18,6 +18,8 @@ package com.android.gallery3d.data;
import android.net.Uri;
+import com.android.gallery3d.util.ThreadPool;
+
public abstract class MediaObject {
@SuppressWarnings("unused")
private static final String TAG = "MediaObject";
@@ -37,14 +39,20 @@ public abstract class MediaObject {
public static final int SUPPORT_INFO = 1 << 10;
public static final int SUPPORT_IMPORT = 1 << 11;
public static final int SUPPORT_TRIM = 1 << 12;
- public static final int SUPPORT_PANORAMA = 1 << 13;
- public static final int SUPPORT_PANORAMA360 = 1 << 14;
- public static final int SUPPORT_UNLOCK = 1 << 15;
- public static final int SUPPORT_BACK = 1 << 16;
- public static final int SUPPORT_ACTION = 1 << 17;
- public static final int SUPPORT_CAMERA_SHORTCUT = 1 << 18;
+ public static final int SUPPORT_UNLOCK = 1 << 13;
+ public static final int SUPPORT_BACK = 1 << 14;
+ public static final int SUPPORT_ACTION = 1 << 15;
+ public static final int SUPPORT_CAMERA_SHORTCUT = 1 << 16;
+ // The panorama specific bits are expensive to compute.
+ // Use SupportedOperationsListener to request them.
+ public static final int SUPPORT_PANORAMA = 1 << 30;
+ public static final int SUPPORT_PANORAMA360 = 1 << 31;
public static final int SUPPORT_ALL = 0xffffffff;
+ public static interface SupportedOperationsListener {
+ public void onChange(int operations);
+ }
+
// These are the bits returned from getMediaType():
public static final int MEDIA_TYPE_UNKNOWN = 1;
public static final int MEDIA_TYPE_IMAGE = 2;
@@ -72,6 +80,11 @@ public abstract class MediaObject {
protected final Path mPath;
+ private static ThreadPool sThreadPool = new ThreadPool(1, 1);
+ public static ThreadPool getThreadPool() {
+ return sThreadPool;
+ }
+
public MediaObject(Path path, long version) {
path.setObject(this);
mPath = path;
@@ -86,6 +99,14 @@ public abstract class MediaObject {
return 0;
}
+ public int getSupportedOperations(boolean getAll) {
+ return 0;
+ }
+
+ public void setSupportedOperationsListener(SupportedOperationsListener l) {
+ // nothing to do
+ }
+
public void delete() {
throw new UnsupportedOperationException();
}
diff --git a/src/com/android/gallery3d/data/PanoramaMetadataJob.java b/src/com/android/gallery3d/data/PanoramaMetadataJob.java
new file mode 100644
index 000000000..e0a69c41f
--- /dev/null
+++ b/src/com/android/gallery3d/data/PanoramaMetadataJob.java
@@ -0,0 +1,40 @@
+/*
+ * 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.data;
+
+import android.content.Context;
+import android.net.Uri;
+
+import com.android.gallery3d.util.LightCycleHelper;
+import com.android.gallery3d.util.LightCycleHelper.PanoramaMetadata;
+import com.android.gallery3d.util.ThreadPool.Job;
+import com.android.gallery3d.util.ThreadPool.JobContext;
+
+class PanoramaMetadataJob implements Job<PanoramaMetadata> {
+ Context mContext;
+ Uri mUri;
+
+ public PanoramaMetadataJob(Context context, Uri uri) {
+ mContext = context;
+ mUri = uri;
+ }
+
+ @Override
+ public PanoramaMetadata run(JobContext jc) {
+ return LightCycleHelper.getPanoramaMetadata(mContext, mUri);
+ }
+}
diff --git a/src/com/android/gallery3d/data/UriImage.java b/src/com/android/gallery3d/data/UriImage.java
index b2cbc7d68..5fab667b8 100644
--- a/src/com/android/gallery3d/data/UriImage.java
+++ b/src/com/android/gallery3d/data/UriImage.java
@@ -28,7 +28,10 @@ import android.os.ParcelFileDescriptor;
import com.android.gallery3d.app.GalleryApp;
import com.android.gallery3d.common.BitmapUtils;
import com.android.gallery3d.common.Utils;
+import com.android.gallery3d.util.Future;
+import com.android.gallery3d.util.FutureListener;
import com.android.gallery3d.util.LightCycleHelper;
+import com.android.gallery3d.util.LightCycleHelper.PanoramaMetadata;
import com.android.gallery3d.util.ThreadPool.CancelListener;
import com.android.gallery3d.util.ThreadPool.Job;
import com.android.gallery3d.util.ThreadPool.JobContext;
@@ -56,10 +59,12 @@ public class UriImage extends MediaItem {
private int mWidth;
private int mHeight;
private int mRotation;
- private boolean mUsePanoramaViewer;
- private boolean mUsePanoramaViewerInitialized;
- private boolean mIsPanorama360;
- private boolean mIsPanorama360Initialized;
+
+ private Object mLock = new Object();
+ private Future<PanoramaMetadata> mGetPanoMetadataTask;
+ private boolean mPanoramaMetadataInitialized;
+ private PanoramaMetadata mPanoramaMetadata;
+ private SupportedOperationsListener mListener;
private GalleryApp mApplication;
@@ -220,9 +225,9 @@ public class UriImage extends MediaItem {
if (BitmapUtils.isSupportedByRegionDecoder(mContentType)) {
supported |= SUPPORT_FULL_IMAGE;
}
- if (usePanoramaViewer()) {
+ if (mPanoramaMetadata != null && mPanoramaMetadata.mUsePanoramaViewer) {
supported |= SUPPORT_PANORAMA;
- if (isPanorama360()) {
+ if (mPanoramaMetadata.mIsPanorama360) {
supported |= SUPPORT_PANORAMA360;
// disable destructive crop for 360 degree panorama
supported &= ~SUPPORT_CROP;
@@ -231,6 +236,55 @@ public class UriImage extends MediaItem {
return supported;
}
+ @Override
+ public int getSupportedOperations(boolean getAll) {
+ synchronized (mLock) {
+ if (getAll && !mPanoramaMetadataInitialized) {
+ if (mGetPanoMetadataTask == null) {
+ mGetPanoMetadataTask = getThreadPool().submit(
+ new PanoramaMetadataJob(mApplication.getAndroidContext(),
+ getContentUri()));
+ }
+ mPanoramaMetadata = mGetPanoMetadataTask.get();
+ mPanoramaMetadataInitialized = true;
+ }
+ }
+ return getSupportedOperations();
+ }
+
+ @Override
+ public void setSupportedOperationsListener(SupportedOperationsListener l) {
+ synchronized (mLock) {
+ if (mPanoramaMetadataInitialized) return; // no more updates
+
+ if (l != null) {
+ if (mGetPanoMetadataTask != null) {
+ mGetPanoMetadataTask.cancel();
+ mGetPanoMetadataTask = null;
+ }
+ } else {
+ if (mGetPanoMetadataTask == null) {
+ mGetPanoMetadataTask = getThreadPool().submit(
+ new PanoramaMetadataJob(mApplication.getAndroidContext(),
+ getContentUri()),
+ new FutureListener<PanoramaMetadata>() {
+ @Override
+ public void onFutureDone(Future<PanoramaMetadata> future) {
+ mGetPanoMetadataTask = null;
+ if (future.isCancelled()) return;
+ mPanoramaMetadata = future.get();
+ mPanoramaMetadataInitialized = true;
+ if (mListener != null) {
+ mListener.onChange(getSupportedOperations());
+ }
+ }
+ });
+ }
+ }
+ mListener = l;
+ }
+ }
+
private boolean isSharable() {
// We cannot grant read permission to the receiver since we put
// the data URI in EXTRA_STREAM instead of the data part of an intent
@@ -297,27 +351,4 @@ public class UriImage extends MediaItem {
public int getRotation() {
return mRotation;
}
-
- @Override
- public boolean usePanoramaViewer() {
- if (!mUsePanoramaViewerInitialized) {
- Context context = mApplication.getAndroidContext();
- mUsePanoramaViewer = LightCycleHelper.hasLightCycleView(context)
- && LightCycleHelper.isPanorama(mApplication.getContentResolver(),
- getContentUri());
- mUsePanoramaViewerInitialized = true;
- }
- return mUsePanoramaViewer;
- }
-
- @Override
- public boolean isPanorama360() {
- // cache flag for faster access
- if (!mIsPanorama360Initialized) {
- mIsPanorama360 = LightCycleHelper.isPanorama360(
- mApplication.getAndroidContext(), getContentUri());
- mIsPanorama360Initialized = true;
- }
- return mIsPanorama360;
- }
}