From 51177aac9078da153bcb191864fb368faf105681 Mon Sep 17 00:00:00 2001 From: John Reck Date: Thu, 21 Mar 2013 14:22:33 -0700 Subject: Revert "New loading model" Change-Id: I5d3d4c7a4ca0d11de01278529e1413fc62e6b4ed --- src/com/android/gallery3d/app/AlbumDataLoader.java | 2 +- .../android/gallery3d/app/AlbumSetDataLoader.java | 4 +- .../android/gallery3d/app/PhotoDataAdapter.java | 2 +- src/com/android/gallery3d/app/SlideshowPage.java | 4 +- src/com/android/gallery3d/data/ClusterAlbum.java | 12 ++- .../android/gallery3d/data/ClusterAlbumSet.java | 27 +++-- src/com/android/gallery3d/data/ComboAlbum.java | 24 ++--- src/com/android/gallery3d/data/ComboAlbumSet.java | 24 ++--- .../android/gallery3d/data/FilterDeleteSet.java | 21 ++-- .../gallery3d/data/FilterEmptyPromptSet.java | 9 +- src/com/android/gallery3d/data/FilterTypeSet.java | 20 ++-- src/com/android/gallery3d/data/LocalAlbum.java | 12 +-- src/com/android/gallery3d/data/LocalAlbumSet.java | 113 ++++++++++++++------- .../android/gallery3d/data/LocalMergeAlbum.java | 30 ++---- src/com/android/gallery3d/data/MediaSet.java | 87 +++------------- .../android/gallery3d/data/MediaSetWrapper.java | 47 --------- src/com/android/gallery3d/data/SecureAlbum.java | 13 ++- .../android/gallery3d/data/SingleItemAlbum.java | 9 +- src/com/android/gallery3d/data/SnailAlbum.java | 13 ++- .../android/gallery3d/gadget/MediaSetSource.java | 2 +- src/com/android/photos/shims/MediaItemsLoader.java | 3 +- src/com/android/photos/shims/MediaSetLoader.java | 5 +- .../gallery3d/picasasource/PicasaSource.java | 8 +- .../com/android/gallery3d/data/LocalDataTest.java | 6 +- tests/src/com/android/gallery3d/data/MockSet.java | 9 +- .../com/android/gallery3d/data/RealDataTest.java | 6 +- 26 files changed, 206 insertions(+), 306 deletions(-) delete mode 100644 src/com/android/gallery3d/data/MediaSetWrapper.java diff --git a/src/com/android/gallery3d/app/AlbumDataLoader.java b/src/com/android/gallery3d/app/AlbumDataLoader.java index 77fd0db8a..28a822830 100644 --- a/src/com/android/gallery3d/app/AlbumDataLoader.java +++ b/src/com/android/gallery3d/app/AlbumDataLoader.java @@ -368,7 +368,7 @@ public class AlbumDataLoader { mDirty = false; } updateLoading(true); - long version = mSource.loadIfDirty(); + long version = mSource.reload(); UpdateInfo info = executeAndWait(new GetUpdateInfo(version)); updateComplete = info == null; if (updateComplete) continue; diff --git a/src/com/android/gallery3d/app/AlbumSetDataLoader.java b/src/com/android/gallery3d/app/AlbumSetDataLoader.java index 8c73d4ef5..cf380f812 100644 --- a/src/com/android/gallery3d/app/AlbumSetDataLoader.java +++ b/src/com/android/gallery3d/app/AlbumSetDataLoader.java @@ -343,7 +343,7 @@ public class AlbumSetDataLoader { while (mActive) { synchronized (this) { if (mActive && !mDirty && updateComplete) { - updateLoading(false); + if (!mSource.isLoading()) updateLoading(false); Utils.waitWithoutInterrupt(this); continue; } @@ -351,7 +351,7 @@ public class AlbumSetDataLoader { mDirty = false; updateLoading(true); - long version = mSource.loadIfDirty(); + long version = mSource.reload(); UpdateInfo info = executeAndWait(new GetUpdateInfo(version)); updateComplete = info == null; if (updateComplete) continue; diff --git a/src/com/android/gallery3d/app/PhotoDataAdapter.java b/src/com/android/gallery3d/app/PhotoDataAdapter.java index d409315d1..fd3a7cf73 100644 --- a/src/com/android/gallery3d/app/PhotoDataAdapter.java +++ b/src/com/android/gallery3d/app/PhotoDataAdapter.java @@ -1032,7 +1032,7 @@ public class PhotoDataAdapter implements PhotoPage.Model { mDirty = false; UpdateInfo info = executeAndWait(new GetUpdateInfo()); updateLoading(true); - long version = mSource.loadIfDirty(); + long version = mSource.reload(); if (info.version != version) { info.reloadContent = true; info.size = mSource.getMediaItemCount(); diff --git a/src/com/android/gallery3d/app/SlideshowPage.java b/src/com/android/gallery3d/app/SlideshowPage.java index 51bc70feb..54aae67ab 100644 --- a/src/com/android/gallery3d/app/SlideshowPage.java +++ b/src/com/android/gallery3d/app/SlideshowPage.java @@ -272,7 +272,7 @@ public class SlideshowPage extends ActivityState { @Override public long reload() { - long version = mMediaSet.loadIfDirty(); + long version = mMediaSet.reload(); if (version != mSourceVersion) { mSourceVersion = version; int count = mMediaSet.getTotalMediaItemCount(); @@ -346,7 +346,7 @@ public class SlideshowPage extends ActivityState { @Override public long reload() { - long version = mMediaSet.loadIfDirty(); + long version = mMediaSet.reload(); if (version != mDataVersion) { mDataVersion = version; mData.clear(); diff --git a/src/com/android/gallery3d/data/ClusterAlbum.java b/src/com/android/gallery3d/data/ClusterAlbum.java index 684e6109f..8681952bf 100644 --- a/src/com/android/gallery3d/data/ClusterAlbum.java +++ b/src/com/android/gallery3d/data/ClusterAlbum.java @@ -18,7 +18,7 @@ package com.android.gallery3d.data; import java.util.ArrayList; -public class ClusterAlbum extends MediaSetWrapper implements ContentListener { +public class ClusterAlbum extends MediaSet implements ContentListener { @SuppressWarnings("unused") private static final String TAG = "ClusterAlbum"; private ArrayList mPaths = new ArrayList(); @@ -29,7 +29,7 @@ public class ClusterAlbum extends MediaSetWrapper implements ContentListener { public ClusterAlbum(Path path, DataManager dataManager, MediaSet clusterAlbumSet) { - super(clusterAlbumSet, path, nextVersionNumber()); + super(path, nextVersionNumber()); mDataManager = dataManager; mClusterAlbumSet = clusterAlbumSet; mClusterAlbumSet.addContentListener(this); @@ -105,6 +105,14 @@ public class ClusterAlbum extends MediaSetWrapper implements ContentListener { return mPaths.size(); } + @Override + public long reload() { + if (mClusterAlbumSet.reload() > mDataVersion) { + mDataVersion = nextVersionNumber(); + } + return mDataVersion; + } + @Override public void onContentDirty() { notifyContentChanged(); diff --git a/src/com/android/gallery3d/data/ClusterAlbumSet.java b/src/com/android/gallery3d/data/ClusterAlbumSet.java index a551de2ab..cb212ba36 100644 --- a/src/com/android/gallery3d/data/ClusterAlbumSet.java +++ b/src/com/android/gallery3d/data/ClusterAlbumSet.java @@ -24,7 +24,7 @@ import com.android.gallery3d.app.GalleryApp; import java.util.ArrayList; import java.util.HashSet; -public class ClusterAlbumSet extends MediaSetWrapper implements ContentListener { +public class ClusterAlbumSet extends MediaSet implements ContentListener { @SuppressWarnings("unused") private static final String TAG = "ClusterAlbumSet"; private GalleryApp mApplication; @@ -35,7 +35,7 @@ public class ClusterAlbumSet extends MediaSetWrapper implements ContentListener public ClusterAlbumSet(Path path, GalleryApp application, MediaSet baseSet, int kind) { - super(baseSet, path, INVALID_DATA_VERSION); + super(path, INVALID_DATA_VERSION); mApplication = application; mBaseSet = baseSet; mKind = kind; @@ -58,20 +58,17 @@ public class ClusterAlbumSet extends MediaSetWrapper implements ContentListener } @Override - protected boolean isDirtyLocked() { - return super.isDirtyLocked() - || !mFirstReloadDone; - } - - @Override - public void load() throws InterruptedException { - super.load(); - if (mFirstReloadDone) { - updateClustersContents(); - } else { - updateClusters(); - mFirstReloadDone = true; + public long reload() { + if (mBaseSet.reload() > mDataVersion) { + if (mFirstReloadDone) { + updateClustersContents(); + } else { + updateClusters(); + mFirstReloadDone = true; + } + mDataVersion = nextVersionNumber(); } + return mDataVersion; } @Override diff --git a/src/com/android/gallery3d/data/ComboAlbum.java b/src/com/android/gallery3d/data/ComboAlbum.java index e193afa6d..cadd9f8af 100644 --- a/src/com/android/gallery3d/data/ComboAlbum.java +++ b/src/com/android/gallery3d/data/ComboAlbum.java @@ -27,13 +27,11 @@ public class ComboAlbum extends MediaSet implements ContentListener { @SuppressWarnings("unused") private static final String TAG = "ComboAlbum"; private final MediaSet[] mSets; - private final boolean[] mDirtySets; private String mName; public ComboAlbum(Path path, MediaSet[] mediaSets, String name) { super(path, nextVersionNumber()); mSets = mediaSets; - mDirtySets = new boolean[mSets.length]; for (MediaSet set : mSets) { set.addContentListener(this); } @@ -83,24 +81,14 @@ public class ComboAlbum extends MediaSet implements ContentListener { } @Override - protected boolean isDirtyLocked() { - boolean dirty = false; - for (int i = 0; i < mSets.length; i++) { - mDirtySets[i] = mSets[i].isDirtyLocked(); - dirty |= mDirtySets[i] - || mSets[i].getDataVersion() > getDataVersion(); - } - return dirty; - } - - @Override - protected void load() throws InterruptedException { + public long reload() { + boolean changed = false; for (int i = 0, n = mSets.length; i < n; ++i) { - if (mDirtySets[i]) { - mDirtySets[i] = false; - mSets[i].load(); - } + long version = mSets[i].reload(); + if (version > mDataVersion) changed = true; } + if (changed) mDataVersion = nextVersionNumber(); + return mDataVersion; } @Override diff --git a/src/com/android/gallery3d/data/ComboAlbumSet.java b/src/com/android/gallery3d/data/ComboAlbumSet.java index 528ffcf41..3f3674500 100644 --- a/src/com/android/gallery3d/data/ComboAlbumSet.java +++ b/src/com/android/gallery3d/data/ComboAlbumSet.java @@ -27,13 +27,11 @@ public class ComboAlbumSet extends MediaSet implements ContentListener { @SuppressWarnings("unused") private static final String TAG = "ComboAlbumSet"; private final MediaSet[] mSets; - private final boolean[] mDirtySets; private final String mName; public ComboAlbumSet(Path path, GalleryApp application, MediaSet[] mediaSets) { super(path, nextVersionNumber()); mSets = mediaSets; - mDirtySets = new boolean[mSets.length]; for (MediaSet set : mSets) { set.addContentListener(this); } @@ -68,24 +66,22 @@ public class ComboAlbumSet extends MediaSet implements ContentListener { } @Override - protected boolean isDirtyLocked() { - boolean dirty = false; - for (int i = 0; i < mSets.length; i++) { - mDirtySets[i] = mSets[i].isDirtyLocked(); - dirty |= mDirtySets[i] - || mSets[i].getDataVersion() > getDataVersion(); + public boolean isLoading() { + for (int i = 0, n = mSets.length; i < n; ++i) { + if (mSets[i].isLoading()) return true; } - return dirty; + return false; } @Override - protected void load() throws InterruptedException { + public long reload() { + boolean changed = false; for (int i = 0, n = mSets.length; i < n; ++i) { - if (mDirtySets[i]) { - mDirtySets[i] = false; - mSets[i].load(); - } + long version = mSets[i].reload(); + if (version > mDataVersion) changed = true; } + if (changed) mDataVersion = nextVersionNumber(); + return mDataVersion; } @Override diff --git a/src/com/android/gallery3d/data/FilterDeleteSet.java b/src/com/android/gallery3d/data/FilterDeleteSet.java index 7970d7c4a..c76412ff8 100644 --- a/src/com/android/gallery3d/data/FilterDeleteSet.java +++ b/src/com/android/gallery3d/data/FilterDeleteSet.java @@ -27,7 +27,7 @@ import java.util.ArrayList; // void clearDeletion(); // int getNumberOfDeletions(); // -public class FilterDeleteSet extends MediaSetWrapper implements ContentListener { +public class FilterDeleteSet extends MediaSet implements ContentListener { @SuppressWarnings("unused") private static final String TAG = "FilterDeleteSet"; @@ -65,7 +65,7 @@ public class FilterDeleteSet extends MediaSetWrapper implements ContentListener private ArrayList mCurrent = new ArrayList(); public FilterDeleteSet(Path path, MediaSet baseSet) { - super(baseSet, path, INVALID_DATA_VERSION); + super(path, INVALID_DATA_VERSION); mBaseSet = baseSet; mBaseSet.addContentListener(this); } @@ -141,18 +141,14 @@ public class FilterDeleteSet extends MediaSetWrapper implements ContentListener return base; } - @Override - protected boolean isDirtyLocked() { - synchronized (mRequests) { - return super.isDirtyLocked() || !mRequests.isEmpty(); - } - } - // We apply the pending requests in the mRequests to construct mCurrent in reload(). @Override - protected void load() throws InterruptedException { - super.load(); + public long reload() { + boolean newData = mBaseSet.reload() > mDataVersion; synchronized (mRequests) { + if (!newData && mRequests.isEmpty()) { + return mDataVersion; + } for (int i = 0; i < mRequests.size(); i++) { Request r = mRequests.get(i); switch (r.type) { @@ -222,6 +218,9 @@ public class FilterDeleteSet extends MediaSetWrapper implements ContentListener } mCurrent = result; } + + mDataVersion = nextVersionNumber(); + return mDataVersion; } private void sendRequest(int type, Path path, int indexHint) { diff --git a/src/com/android/gallery3d/data/FilterEmptyPromptSet.java b/src/com/android/gallery3d/data/FilterEmptyPromptSet.java index f2623fb00..b576e06d4 100644 --- a/src/com/android/gallery3d/data/FilterEmptyPromptSet.java +++ b/src/com/android/gallery3d/data/FilterEmptyPromptSet.java @@ -18,7 +18,7 @@ package com.android.gallery3d.data; import java.util.ArrayList; -public class FilterEmptyPromptSet extends MediaSetWrapper implements ContentListener { +public class FilterEmptyPromptSet extends MediaSet implements ContentListener { @SuppressWarnings("unused") private static final String TAG = "FilterEmptyPromptSet"; @@ -26,7 +26,7 @@ public class FilterEmptyPromptSet extends MediaSetWrapper implements ContentList private MediaSet mBaseSet; public FilterEmptyPromptSet(Path path, MediaSet baseSet, MediaItem emptyItem) { - super(baseSet, path, INVALID_DATA_VERSION); + super(path, INVALID_DATA_VERSION); mEmptyItem = new ArrayList(1); mEmptyItem.add(emptyItem); mBaseSet = baseSet; @@ -70,6 +70,11 @@ public class FilterEmptyPromptSet extends MediaSetWrapper implements ContentList return mBaseSet.isCameraRoll(); } + @Override + public long reload() { + return mBaseSet.reload(); + } + @Override public String getName() { return mBaseSet.getName(); diff --git a/src/com/android/gallery3d/data/FilterTypeSet.java b/src/com/android/gallery3d/data/FilterTypeSet.java index d6fbbdb9a..477ef73ad 100644 --- a/src/com/android/gallery3d/data/FilterTypeSet.java +++ b/src/com/android/gallery3d/data/FilterTypeSet.java @@ -25,7 +25,6 @@ public class FilterTypeSet extends MediaSet implements ContentListener { private final DataManager mDataManager; private final MediaSet mBaseSet; - private boolean mBaseSetIsDirty; private final int mMediaType; private final ArrayList mPaths = new ArrayList(); private final ArrayList mAlbums = new ArrayList(); @@ -66,17 +65,12 @@ public class FilterTypeSet extends MediaSet implements ContentListener { } @Override - protected boolean isDirtyLocked() { - mBaseSetIsDirty = mBaseSet.isDirtyLocked(); - return mBaseSetIsDirty || mBaseSet.getDataVersion() > getDataVersion(); - } - - @Override - public void load() throws InterruptedException { - if (mBaseSetIsDirty) { - mBaseSet.load(); + public long reload() { + if (mBaseSet.reload() > mDataVersion) { + updateData(); + mDataVersion = nextVersionNumber(); } - updateData(); + return mDataVersion; } @Override @@ -84,7 +78,7 @@ public class FilterTypeSet extends MediaSet implements ContentListener { notifyContentChanged(); } - private void updateData() throws InterruptedException { + private void updateData() { // Albums mAlbums.clear(); String basePath = "/filter/mediatype/" + mMediaType; @@ -93,7 +87,7 @@ public class FilterTypeSet extends MediaSet implements ContentListener { MediaSet set = mBaseSet.getSubMediaSet(i); String filteredPath = basePath + "/{" + set.getPath().toString() + "}"; MediaSet filteredSet = mDataManager.getMediaSet(filteredPath); - filteredSet.loadIfDirty(); + filteredSet.reload(); if (filteredSet.getMediaItemCount() > 0 || filteredSet.getSubMediaSetCount() > 0) { mAlbums.add(filteredSet); diff --git a/src/com/android/gallery3d/data/LocalAlbum.java b/src/com/android/gallery3d/data/LocalAlbum.java index 8c92d3aa5..7b7015af6 100644 --- a/src/com/android/gallery3d/data/LocalAlbum.java +++ b/src/com/android/gallery3d/data/LocalAlbum.java @@ -252,12 +252,12 @@ public class LocalAlbum extends MediaSet { } @Override - protected boolean isDirtyLocked() { - return mNotifier.isDirty(); - } - @Override - public void load() { - mCachedCount = INVALID_COUNT; + public long reload() { + if (mNotifier.isDirty()) { + mDataVersion = nextVersionNumber(); + mCachedCount = INVALID_COUNT; + } + return mDataVersion; } @Override diff --git a/src/com/android/gallery3d/data/LocalAlbumSet.java b/src/com/android/gallery3d/data/LocalAlbumSet.java index d71c9f700..b2b4b8c5d 100644 --- a/src/com/android/gallery3d/data/LocalAlbumSet.java +++ b/src/com/android/gallery3d/data/LocalAlbumSet.java @@ -17,20 +17,26 @@ package com.android.gallery3d.data; import android.net.Uri; +import android.os.Handler; import android.provider.MediaStore.Images; import android.provider.MediaStore.Video; import com.android.gallery3d.R; import com.android.gallery3d.app.GalleryApp; import com.android.gallery3d.data.BucketHelper.BucketEntry; +import com.android.gallery3d.util.Future; +import com.android.gallery3d.util.FutureListener; import com.android.gallery3d.util.MediaSetUtils; +import com.android.gallery3d.util.ThreadPool; +import com.android.gallery3d.util.ThreadPool.JobContext; import java.util.ArrayList; import java.util.Comparator; // LocalAlbumSet lists all image or video albums in the local storage. // The path should be "/local/image", "local/video" or "/local/all" -public class LocalAlbumSet extends MediaSet { +public class LocalAlbumSet extends MediaSet + implements FutureListener> { @SuppressWarnings("unused") private static final String TAG = "LocalAlbumSet"; @@ -46,10 +52,16 @@ public class LocalAlbumSet extends MediaSet { private ArrayList mAlbums = new ArrayList(); private final ChangeNotifier mNotifier; private final String mName; + private final Handler mHandler; + private boolean mIsLoading; + + private Future> mLoadTask; + private ArrayList mLoadBuffer; public LocalAlbumSet(Path path, GalleryApp application) { super(path, nextVersionNumber()); mApplication = application; + mHandler = new Handler(application.getMainLooper()); mType = getTypeFromPath(path); mNotifier = new ChangeNotifier(this, mWatchUris, application); mName = application.getResources().getString( @@ -86,6 +98,41 @@ public class LocalAlbumSet extends MediaSet { return -1; } + private class AlbumsLoader implements ThreadPool.Job> { + + @Override + @SuppressWarnings("unchecked") + public ArrayList run(JobContext jc) { + // Note: it will be faster if we only select media_type and bucket_id. + // need to test the performance if that is worth + BucketEntry[] entries = BucketHelper.loadBucketEntries( + jc, mApplication.getContentResolver(), mType); + + if (jc.isCancelled()) return null; + + int offset = 0; + // Move camera and download bucket to the front, while keeping the + // order of others. + int index = findBucket(entries, MediaSetUtils.CAMERA_BUCKET_ID); + if (index != -1) { + circularShiftRight(entries, offset++, index); + } + index = findBucket(entries, MediaSetUtils.DOWNLOAD_BUCKET_ID); + if (index != -1) { + circularShiftRight(entries, offset++, index); + } + + ArrayList albums = new ArrayList(); + DataManager dataManager = mApplication.getDataManager(); + for (BucketEntry entry : entries) { + MediaSet album = getLocalAlbum(dataManager, + mType, mPath, entry.bucketId, entry.bucketName); + albums.add(album); + } + return albums; + } + } + private MediaSet getLocalAlbum( DataManager manager, int type, Path parent, int id, String name) { synchronized (DataManager.LOCK) { @@ -108,45 +155,43 @@ public class LocalAlbumSet extends MediaSet { } @Override - protected boolean isDirtyLocked() { - return mNotifier.isDirty(); + public synchronized boolean isLoading() { + return mIsLoading; } @Override - protected void load() throws InterruptedException { - // Note: it will be faster if we only select media_type and bucket_id. - // need to test the performance if that is worth - BucketEntry[] entries = BucketHelper.loadBucketEntries( - createJobContextCompat(), mApplication.getContentResolver(), mType); - - // BucketHelper.loadBucketEntries returns null if it was canceled - if (entries == null || Thread.interrupted()) { - throw new InterruptedException(); - } - - int offset = 0; - // Move camera and download bucket to the front, while keeping the - // order of others. - int index = findBucket(entries, MediaSetUtils.CAMERA_BUCKET_ID); - if (index != -1) { - circularShiftRight(entries, offset++, index); + // synchronized on this function for + // 1. Prevent calling reload() concurrently. + // 2. Prevent calling onFutureDone() and reload() concurrently + public synchronized long reload() { + if (mNotifier.isDirty()) { + if (mLoadTask != null) mLoadTask.cancel(); + mIsLoading = true; + mLoadTask = mApplication.getThreadPool().submit(new AlbumsLoader(), this); } - index = findBucket(entries, MediaSetUtils.DOWNLOAD_BUCKET_ID); - if (index != -1) { - circularShiftRight(entries, offset++, index); - } - - mAlbums.clear(); - DataManager dataManager = mApplication.getDataManager(); - for (BucketEntry entry : entries) { - MediaSet album = getLocalAlbum(dataManager, - mType, mPath, entry.bucketId, entry.bucketName); - mAlbums.add(album); + if (mLoadBuffer != null) { + mAlbums = mLoadBuffer; + mLoadBuffer = null; + for (MediaSet album : mAlbums) { + album.reload(); + } + mDataVersion = nextVersionNumber(); } + return mDataVersion; + } - for (MediaSet album : mAlbums) { - album.loadIfDirty(); - } + @Override + public synchronized void onFutureDone(Future> future) { + if (mLoadTask != future) return; // ignore, wait for the latest task + mLoadBuffer = future.get(); + mIsLoading = false; + if (mLoadBuffer == null) mLoadBuffer = new ArrayList(); + mHandler.post(new Runnable() { + @Override + public void run() { + notifyContentChanged(); + } + }); } // For debug only. Fake there is a ContentObserver.onChange() event. diff --git a/src/com/android/gallery3d/data/LocalMergeAlbum.java b/src/com/android/gallery3d/data/LocalMergeAlbum.java index e07dc5ed8..f0b5e5726 100644 --- a/src/com/android/gallery3d/data/LocalMergeAlbum.java +++ b/src/com/android/gallery3d/data/LocalMergeAlbum.java @@ -24,6 +24,7 @@ import com.android.gallery3d.common.ApiHelper; import java.lang.ref.SoftReference; import java.util.ArrayList; import java.util.Comparator; +import java.util.NoSuchElementException; import java.util.SortedMap; import java.util.TreeMap; @@ -39,7 +40,6 @@ public class LocalMergeAlbum extends MediaSet implements ContentListener { private final Comparator mComparator; private final MediaSet[] mSources; - private final boolean[] mDirtySources; private FetchCache[] mFetcher; private int mSupportedOperation; @@ -53,11 +53,11 @@ public class LocalMergeAlbum extends MediaSet implements ContentListener { super(path, INVALID_DATA_VERSION); mComparator = comparator; mSources = sources; - mDirtySources = new boolean[mSources.length]; mBucketId = bucketId; for (MediaSet set : mSources) { set.addContentListener(this); } + reload(); } @Override @@ -70,6 +70,7 @@ public class LocalMergeAlbum extends MediaSet implements ContentListener { } private void updateData() { + ArrayList matches = new ArrayList(); int supported = mSources.length == 0 ? 0 : MediaItem.SUPPORT_ALL; mFetcher = new FetchCache[mSources.length]; for (int i = 0, n = mSources.length; i < n; ++i) { @@ -172,26 +173,17 @@ public class LocalMergeAlbum extends MediaSet implements ContentListener { } @Override - protected boolean isDirtyLocked() { - boolean dirty = false; + public long reload() { + boolean changed = false; for (int i = 0, n = mSources.length; i < n; ++i) { - mDirtySources[i] = mSources[i].isDirtyLocked(); - dirty |= mDirtySources[i] - || mSources[i].getDataVersion() > getDataVersion(); + if (mSources[i].reload() > mDataVersion) changed = true; } - return dirty; - } - - @Override - public void load() throws InterruptedException { - for (int i = 0, n = mSources.length; i < n; ++i) { - if (mDirtySources[i]) { - mSources[i].load(); - mDirtySources[i] = false; - } + if (changed) { + mDataVersion = nextVersionNumber(); + updateData(); + invalidateCache(); } - updateData(); - invalidateCache(); + return mDataVersion; } @Override diff --git a/src/com/android/gallery3d/data/MediaSet.java b/src/com/android/gallery3d/data/MediaSet.java index d27adb8e9..683aa6b32 100644 --- a/src/com/android/gallery3d/data/MediaSet.java +++ b/src/com/android/gallery3d/data/MediaSet.java @@ -18,8 +18,6 @@ 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; @@ -56,9 +54,6 @@ 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); } @@ -104,6 +99,14 @@ 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++) { @@ -167,76 +170,9 @@ public abstract class MediaSet extends MediaObject { } } - // 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 the MediaSet. Only called if {@link #isDirtyLocked()} - * returned true - * @throws InterruptedException if the load was interrupted - */ - protected abstract void load() throws InterruptedException; + // 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(); @Override public MediaDetails getDetails() { @@ -335,6 +271,7 @@ public abstract class MediaSet extends MediaObject { } private class MultiSetSyncFuture implements Future, SyncListener { + @SuppressWarnings("hiding") private static final String TAG = "Gallery.MultiSetSync"; private final SyncListener mListener; diff --git a/src/com/android/gallery3d/data/MediaSetWrapper.java b/src/com/android/gallery3d/data/MediaSetWrapper.java deleted file mode 100644 index 986c51fa5..000000000 --- a/src/com/android/gallery3d/data/MediaSetWrapper.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2013 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; - -public abstract class MediaSetWrapper extends MediaSet { - - private MediaSet mWrappedSet; - private boolean mWrappedIsDirty; - - public MediaSetWrapper(MediaSet wrappedSet, Path path, long version) { - super(path, version); - mWrappedSet = wrappedSet; - } - - @Override - protected boolean isDirtyLocked() { - mWrappedIsDirty = mWrappedSet.isDirtyLocked(); - return mWrappedIsDirty; - } - - @Override - protected void load() throws InterruptedException { - if (mWrappedIsDirty) { - mWrappedSet.load(); - } - } - - @Override - public long getDataVersion() { - return mWrappedSet.getDataVersion(); - } - -} diff --git a/src/com/android/gallery3d/data/SecureAlbum.java b/src/com/android/gallery3d/data/SecureAlbum.java index 04d51d11c..204f848f8 100644 --- a/src/com/android/gallery3d/data/SecureAlbum.java +++ b/src/com/android/gallery3d/data/SecureAlbum.java @@ -122,13 +122,12 @@ public class SecureAlbum extends MediaSet implements StitchingChangeListener { } @Override - protected boolean isDirtyLocked() { - return mNotifier.isDirty(); - } - - @Override - public void load() { - updateExistingItems(); + public long reload() { + if (mNotifier.isDirty()) { + mDataVersion = nextVersionNumber(); + updateExistingItems(); + } + return mDataVersion; } private ArrayList queryExistingIds(Uri uri, int minId, int maxId) { diff --git a/src/com/android/gallery3d/data/SingleItemAlbum.java b/src/com/android/gallery3d/data/SingleItemAlbum.java index a404fa770..a0093e0c3 100644 --- a/src/com/android/gallery3d/data/SingleItemAlbum.java +++ b/src/com/android/gallery3d/data/SingleItemAlbum.java @@ -62,12 +62,7 @@ public class SingleItemAlbum extends MediaSet { } @Override - protected boolean isDirtyLocked() { - return false; + public long reload() { + return mDataVersion; } - - @Override - protected void load() throws InterruptedException { - } - } diff --git a/src/com/android/gallery3d/data/SnailAlbum.java b/src/com/android/gallery3d/data/SnailAlbum.java index 78f718806..7bce7a695 100644 --- a/src/com/android/gallery3d/data/SnailAlbum.java +++ b/src/com/android/gallery3d/data/SnailAlbum.java @@ -29,13 +29,12 @@ public class SnailAlbum extends SingleItemAlbum { } @Override - protected void load() throws InterruptedException { - ((SnailItem) getItem()).updateVersion(); - } - - @Override - protected boolean isDirtyLocked() { - return mDirty.compareAndSet(true, false); + public long reload() { + if (mDirty.compareAndSet(true, false)) { + ((SnailItem) getItem()).updateVersion(); + mDataVersion = nextVersionNumber(); + } + return mDataVersion; } public void notifyChange() { diff --git a/src/com/android/gallery3d/gadget/MediaSetSource.java b/src/com/android/gallery3d/gadget/MediaSetSource.java index 0e7e6bd57..caeff2a87 100644 --- a/src/com/android/gallery3d/gadget/MediaSetSource.java +++ b/src/com/android/gallery3d/gadget/MediaSetSource.java @@ -83,7 +83,7 @@ public class MediaSetSource implements WidgetSource, ContentListener { @Override public void reload() { - long version = mSource.loadIfDirty(); + long version = mSource.reload(); if (mSourceVersion != version) { mSourceVersion = version; mCacheStart = 0; diff --git a/src/com/android/photos/shims/MediaItemsLoader.java b/src/com/android/photos/shims/MediaItemsLoader.java index d75823404..6142355a9 100644 --- a/src/com/android/photos/shims/MediaItemsLoader.java +++ b/src/com/android/photos/shims/MediaItemsLoader.java @@ -106,7 +106,8 @@ public class MediaItemsLoader extends AsyncTaskLoader implements LoaderC @Override public Cursor loadInBackground() { - mMediaSet.loadIfDirty(); + // TODO: This probably doesn't work + mMediaSet.reload(); final MatrixCursor cursor = new MatrixCursor(PhotoSetLoader.PROJECTION); final Object[] row = new Object[PhotoSetLoader.PROJECTION.length]; final SparseArray mediaItems = new SparseArray(); diff --git a/src/com/android/photos/shims/MediaSetLoader.java b/src/com/android/photos/shims/MediaSetLoader.java index d200807f9..9093bc139 100644 --- a/src/com/android/photos/shims/MediaSetLoader.java +++ b/src/com/android/photos/shims/MediaSetLoader.java @@ -104,14 +104,15 @@ public class MediaSetLoader extends AsyncTaskLoader implements LoaderCom @Override public Cursor loadInBackground() { - mMediaSet.loadIfDirty(); + // TODO: This probably doesn't work + mMediaSet.reload(); final MatrixCursor cursor = new MatrixCursor(AlbumSetLoader.PROJECTION); final Object[] row = new Object[AlbumSetLoader.PROJECTION.length]; int count = mMediaSet.getSubMediaSetCount(); ArrayList coverItems = new ArrayList(count); for (int i = 0; i < count; i++) { MediaSet m = mMediaSet.getSubMediaSet(i); - m.loadIfDirty(); + m.reload(); row[AlbumSetLoader.INDEX_ID] = i; row[AlbumSetLoader.INDEX_TITLE] = m.getName(); row[AlbumSetLoader.INDEX_COUNT] = m.getMediaItemCount(); diff --git a/src_pd/com/android/gallery3d/picasasource/PicasaSource.java b/src_pd/com/android/gallery3d/picasasource/PicasaSource.java index de457bf99..5e800e23b 100644 --- a/src_pd/com/android/gallery3d/picasasource/PicasaSource.java +++ b/src_pd/com/android/gallery3d/picasasource/PicasaSource.java @@ -66,12 +66,8 @@ public class PicasaSource extends MediaSource { } @Override - protected boolean isDirtyLocked() { - return false; - } - - @Override - protected void load() { + public long reload() { + return mDataVersion; } } diff --git a/tests/src/com/android/gallery3d/data/LocalDataTest.java b/tests/src/com/android/gallery3d/data/LocalDataTest.java index 67fc97ac3..8f6a46b8e 100644 --- a/tests/src/com/android/gallery3d/data/LocalDataTest.java +++ b/tests/src/com/android/gallery3d/data/LocalDataTest.java @@ -66,7 +66,7 @@ public class LocalDataTest extends AndroidTestCase { Path path = Path.fromString( mIsImage ? "/local/image" : "/local/video"); mAlbumSet = new LocalAlbumSet(path, mApp); - mAlbumSet.loadIfDirty(); + mAlbumSet.reload(); verifyResult(); } @@ -200,7 +200,7 @@ public class LocalDataTest extends AndroidTestCase { sub.delete(); mAlbumSet.fakeChange(); latch.isOnContentDirtyBeCalled(DEFAULT_TIMEOUT); - mAlbumSet.loadIfDirty(); + mAlbumSet.reload(); assertEquals(1, mAlbumSet.getSubMediaSetCount()); } } @@ -220,7 +220,7 @@ public class LocalDataTest extends AndroidTestCase { assertEquals(1, sub.getMediaItemCount()); assertTrue((sub.getSupportedOperations() & MediaSet.SUPPORT_DELETE) != 0); sub.delete(); - sub.loadIfDirty(); + sub.reload(); assertEquals(0, sub.getMediaItemCount()); } } diff --git a/tests/src/com/android/gallery3d/data/MockSet.java b/tests/src/com/android/gallery3d/data/MockSet.java index 42f874bdc..fa83c796f 100644 --- a/tests/src/com/android/gallery3d/data/MockSet.java +++ b/tests/src/com/android/gallery3d/data/MockSet.java @@ -82,12 +82,7 @@ public class MockSet extends MediaSet { } @Override - protected boolean isDirtyLocked() { - return false; + public long reload() { + return 0; } - - @Override - protected void load() throws InterruptedException { - } - } diff --git a/tests/src/com/android/gallery3d/data/RealDataTest.java b/tests/src/com/android/gallery3d/data/RealDataTest.java index 7a984ef93..526cfe357 100644 --- a/tests/src/com/android/gallery3d/data/RealDataTest.java +++ b/tests/src/com/android/gallery3d/data/RealDataTest.java @@ -53,7 +53,7 @@ public class RealDataTest extends AndroidTestCase { class TestLocalImage { public void run() { MediaSet set = mDataManager.getMediaSet("/local/image"); - set.loadIfDirty(); + set.reload(); Log.v(TAG, "LocalAlbumSet (Image)"); dumpMediaSet(set, ""); } @@ -62,7 +62,7 @@ public class RealDataTest extends AndroidTestCase { class TestLocalVideo { public void run() { MediaSet set = mDataManager.getMediaSet("/local/video"); - set.loadIfDirty(); + set.reload(); Log.v(TAG, "LocalAlbumSet (Video)"); dumpMediaSet(set, ""); } @@ -71,7 +71,7 @@ public class RealDataTest extends AndroidTestCase { class TestPicasa implements Runnable { public void run() { MediaSet set = mDataManager.getMediaSet("/picasa"); - set.loadIfDirty(); + set.reload(); Log.v(TAG, "PicasaAlbumSet"); dumpMediaSet(set, ""); } -- cgit v1.2.3