diff options
author | John Reck <jreck@google.com> | 2013-01-16 14:10:30 -0800 |
---|---|---|
committer | John Reck <jreck@google.com> | 2013-01-16 18:05:07 -0800 |
commit | 9686d9d07e344fae2f2310ca544e5401b5e11d30 (patch) | |
tree | 7bc66a807f33e3aa016d0e9c977f85cfffbe62f1 /src/com/android/gallery3d/data/MediaSet.java | |
parent | 9003bd581c00a31db4c8291c99a30d5e74fe2dde (diff) | |
download | android_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.java | 87 |
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; |