summaryrefslogtreecommitdiffstats
path: root/src/com/android/gallery3d/data/MediaSet.java
diff options
context:
space:
mode:
authorJohn Reck <jreck@google.com>2013-01-16 14:10:30 -0800
committerJohn Reck <jreck@google.com>2013-01-16 18:05:07 -0800
commit9686d9d07e344fae2f2310ca544e5401b5e11d30 (patch)
tree7bc66a807f33e3aa016d0e9c977f85cfffbe62f1 /src/com/android/gallery3d/data/MediaSet.java
parent9003bd581c00a31db4c8291c99a30d5e74fe2dde (diff)
downloadandroid_packages_apps_Snap-9686d9d07e344fae2f2310ca544e5401b5e11d30.tar.gz
android_packages_apps_Snap-9686d9d07e344fae2f2310ca544e5401b5e11d30.tar.bz2
android_packages_apps_Snap-9686d9d07e344fae2f2310ca544e5401b5e11d30.zip
New loading model
Rename reload() to loadIfDirty() loadIfDirty is implemented by MediaSet and is final loadIfDirty is now blocking instead of async Subclasses must implement two protected methods, isDirtyLocked() and load() The change from async reload() to sync loadIfDirty() should be fine since all users of reload() were doing so from a background thread already, and the longest load() is PicasaAlbumSet which is still a fairly brisk 40ms or so Change-Id: If5cc596a1c13e52e5f4efff1a144bd086d37cfb7
Diffstat (limited to 'src/com/android/gallery3d/data/MediaSet.java')
-rw-r--r--src/com/android/gallery3d/data/MediaSet.java87
1 files changed, 72 insertions, 15 deletions
diff --git a/src/com/android/gallery3d/data/MediaSet.java b/src/com/android/gallery3d/data/MediaSet.java
index 9bc148f89..cc8a4a71a 100644
--- a/src/com/android/gallery3d/data/MediaSet.java
+++ b/src/com/android/gallery3d/data/MediaSet.java
@@ -18,6 +18,8 @@ package com.android.gallery3d.data;
import com.android.gallery3d.common.Utils;
import com.android.gallery3d.util.Future;
+import com.android.gallery3d.util.ThreadPool.CancelListener;
+import com.android.gallery3d.util.ThreadPool.JobContext;
import java.util.ArrayList;
import java.util.WeakHashMap;
@@ -54,6 +56,9 @@ public abstract class MediaSet extends MediaObject {
void onSyncDone(MediaSet mediaSet, int resultCode);
}
+ private Object mLoadLock = new Object();
+ private boolean mIsLoading;
+
public MediaSet(Path path, long version) {
super(path, version);
}
@@ -99,14 +104,6 @@ public abstract class MediaSet extends MediaObject {
return false;
}
- /**
- * Method {@link #reload()} may process the loading task in background, this method tells
- * its client whether the loading is still in process or not.
- */
- public boolean isLoading() {
- return false;
- }
-
public int getTotalMediaItemCount() {
int total = getMediaItemCount();
for (int i = 0, n = getSubMediaSetCount(); i < n; i++) {
@@ -176,15 +173,76 @@ public abstract class MediaSet extends MediaObject {
}
}
- // Reload the content. Return the current data version. reload() should be called
- // in the same thread as getMediaItem(int, int) and getSubMediaSet(int).
- public abstract long reload();
+ // TODO: Remove this once createJobContextCompat is no longer needed
+ // Note that canceling a load is not strictly supported as it can leave
+ // MediaSets with bad internal state. Fortunately they are never canceled
+ // anywhere, so the isCancelled() exists purely for completeness sake
+ private static class LoadJobContextCompat implements JobContext {
+
+ @Override
+ public boolean isCancelled() {
+ return Thread.interrupted();
+ }
+
+ @Override
+ public void setCancelListener(CancelListener listener) {
+ }
+
+ @Override
+ public boolean setMode(int mode) {
+ return false;
+ }
+ }
+
+ @Deprecated
+ protected final JobContext createJobContextCompat() {
+ return new LoadJobContextCompat();
+ }
+
+ /**
+ * Synchronously load if the MediaSet is dirty. Note that this must be called
+ * on the same thread as getMediaItem(int, int) and getSubMediaSet(int)
+ * @return DataVersion
+ */
+ public final long loadIfDirty() {
+ try {
+ boolean doLoad = false;
+ synchronized (mLoadLock) {
+ if (mIsLoading) {
+ mLoadLock.wait();
+ }
+ doLoad = isDirtyLocked();
+ if (doLoad) {
+ mIsLoading = true;
+ }
+ }
+ if (doLoad) {
+ load();
+ synchronized (mLoadLock) {
+ mDataVersion = nextVersionNumber();
+ mIsLoading = false;
+ mLoadLock.notifyAll();
+ }
+ }
+ } catch (InterruptedException ex) {
+ }
+ return getDataVersion();
+ }
+
+ /**
+ * Called inside of synchronized(mLoadLock). It is guaranteed this will only
+ * be called once before a call to load() if this returns true. It is
+ * acceptable to clear any internal dirty flags in this function as a result.
+ * @return true if the set wants a load() call, false otherwise
+ */
+ protected abstract boolean isDirtyLocked();
/**
- * Synchronously load if the MediaSet is dirty
- * @return True if new data was loaded, false otherwise
+ * Synchronously load the MediaSet. Only called if {@link #isDirtyLocked()}
+ * returned true
+ * @throws InterruptedException if the load was interrupted
*/
- public boolean loadIfDirty() { throw new IllegalStateException("not implemented"); }
+ protected abstract void load() throws InterruptedException;
@Override
public MediaDetails getDetails() {
@@ -283,7 +341,6 @@ public abstract class MediaSet extends MediaObject {
}
private class MultiSetSyncFuture implements Future<Integer>, SyncListener {
- @SuppressWarnings("hiding")
private static final String TAG = "Gallery.MultiSetSync";
private final SyncListener mListener;