diff options
author | Hung-ying Tyan <tyanh@google.com> | 2011-09-30 14:42:50 +0800 |
---|---|---|
committer | Hung-ying Tyan <tyanh@google.com> | 2011-10-07 18:57:06 +0800 |
commit | 9d62da7986aef9d89356f6b169fafecd8936d9f6 (patch) | |
tree | 4c3ab57d55fe238b5503a0afc92fe8e0f3533836 /src/com/android/gallery3d/data/MediaSet.java | |
parent | 78eac46afd4c5b33c8c32f976974ebff6870c0a4 (diff) | |
download | android_packages_apps_Snap-9d62da7986aef9d89356f6b169fafecd8936d9f6.tar.gz android_packages_apps_Snap-9d62da7986aef9d89356f6b169fafecd8936d9f6.tar.bz2 android_packages_apps_Snap-9d62da7986aef9d89356f6b169fafecd8936d9f6.zip |
Request sync when there's no mediaItem in a mediaSet.
This is to fix the problem where media items haven't been sync'ed when the album
set or album is viewed for the first time.
+ Add MediaSet.SyncListener.
+ Make AlbumPage and AlbumSetPage implement SyncListener.
+ Implement requestSync() for ComboAlbum and ComboAlbumSet.
+ add ActivityState.isDestroyed(). This also fixes the problem where
StateManager.finishState() may be called twice.
Bug: 5337899
Change-Id: I25364c3ac25721a2650701c5d7931bfb6daa9303
Diffstat (limited to 'src/com/android/gallery3d/data/MediaSet.java')
-rw-r--r-- | src/com/android/gallery3d/data/MediaSet.java | 126 |
1 files changed, 122 insertions, 4 deletions
diff --git a/src/com/android/gallery3d/data/MediaSet.java b/src/com/android/gallery3d/data/MediaSet.java index 99f00a0dd..a54067efc 100644 --- a/src/com/android/gallery3d/data/MediaSet.java +++ b/src/com/android/gallery3d/data/MediaSet.java @@ -16,9 +16,11 @@ package com.android.gallery3d.data; +import com.android.gallery3d.common.Utils; import com.android.gallery3d.util.Future; import java.util.ArrayList; +import java.util.HashMap; import java.util.WeakHashMap; // MediaSet is a directory-like data structure. @@ -34,6 +36,22 @@ public abstract class MediaSet extends MediaObject { public static final int MEDIAITEM_BATCH_FETCH_COUNT = 500; public static final int INDEX_NOT_FOUND = -1; + public static final int SYNC_RESULT_SUCCESS = 0; + public static final int SYNC_RESULT_CANCELLED = 1; + public static final int SYNC_RESULT_ERROR = 2; + + /** Listener to be used with requestSync(SyncListener). */ + public static interface SyncListener { + /** + * Called when the sync task completed. Completion may be due to normal termination, + * an exception, or cancellation. + * + * @param mediaSet the MediaSet that's done with sync + * @param resultCode one of the SYNC_RESULT_* constants + */ + void onSyncDone(MediaSet mediaSet, int resultCode); + } + public MediaSet(Path path, long version) { super(path, version); } @@ -190,11 +208,21 @@ public abstract class MediaSet extends MediaObject { return start; } - public Future<Void> requestSync() { + /** + * Requests sync on this MediaSet. It returns a Future object that can be used by the caller + * to query the status of the sync. The sync result code is one of the SYNC_RESULT_* constants + * defined in this class and can be obtained by Future.get(). + * + * Subclasses should perform sync on a different thread. + * + * The default implementation here returns a Future stub that does nothing and returns + * SYNC_RESULT_SUCCESS by get(). + */ + public Future<Integer> requestSync(SyncListener listener) { return FUTURE_STUB; } - private static final Future<Void> FUTURE_STUB = new Future<Void>() { + private static final Future<Integer> FUTURE_STUB = new Future<Integer>() { @Override public void cancel() {} @@ -209,11 +237,101 @@ public abstract class MediaSet extends MediaObject { } @Override - public Void get() { - return null; + public Integer get() { + return SYNC_RESULT_SUCCESS; } @Override public void waitDone() {} }; + + protected Future<Integer> requestSyncOnEmptySets(MediaSet[] sets, SyncListener listener) { + MultiSetSyncFuture future = new MultiSetSyncFuture(listener); + future.requestSyncOnEmptySets(sets); + return future; + } + + private class MultiSetSyncFuture implements Future<Integer>, SyncListener { + private static final String TAG = "Gallery.MultiSetSync"; + + private final HashMap<MediaSet, Future<Integer>> mMediaSetMap = + new HashMap<MediaSet, Future<Integer>>(); + private final SyncListener mListener; + + private boolean mIsCancelled = false; + private int mResult = -1; + + MultiSetSyncFuture(SyncListener listener) { + mListener = listener; + } + + synchronized void requestSyncOnEmptySets(MediaSet[] sets) { + for (MediaSet set : sets) { + if ((set.getMediaItemCount() == 0) && !mMediaSetMap.containsKey(set)) { + // Sync results are handled in this.onSyncDone(). + Future<Integer> future = set.requestSync(this); + if (!future.isDone()) { + mMediaSetMap.put(set, future); + Log.d(TAG, " request sync: " + Utils.maskDebugInfo(set.getName())); + } + } + } + Log.d(TAG, "requestSyncOnEmptySets actual=" + mMediaSetMap.size()); + } + + @Override + public synchronized void cancel() { + if (mIsCancelled) return; + mIsCancelled = true; + for (Future<Integer> future : mMediaSetMap.values()) future.cancel(); + mMediaSetMap.clear(); + if (mResult < 0) mResult = SYNC_RESULT_CANCELLED; + } + + @Override + public synchronized boolean isCancelled() { + return mIsCancelled; + } + + @Override + public synchronized boolean isDone() { + return mMediaSetMap.isEmpty(); + } + + @Override + public synchronized Integer get() { + waitDone(); + return mResult; + } + + @Override + public synchronized void waitDone() { + try { + while (!isDone()) wait(); + } catch (InterruptedException e) { + Log.d(TAG, "waitDone() interrupted"); + } + } + + // SyncListener callback + @Override + public void onSyncDone(MediaSet mediaSet, int resultCode) { + SyncListener listener = null; + synchronized (this) { + if (mMediaSetMap.remove(mediaSet) != null) { + Log.d(TAG, "onSyncDone: " + Utils.maskDebugInfo(mediaSet.getName()) + + " #pending=" + mMediaSetMap.size()); + if (resultCode == SYNC_RESULT_ERROR) { + mResult = SYNC_RESULT_ERROR; + } + if (mMediaSetMap.isEmpty()) { + if (mResult < 0) mResult = SYNC_RESULT_SUCCESS; + notifyAll(); + listener = mListener; + } + } + } + if (listener != null) listener.onSyncDone(MediaSet.this, mResult); + } + } } |