summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/com/android/gallery3d/app/AlbumDataLoader.java2
-rw-r--r--src/com/android/gallery3d/app/AlbumSetDataLoader.java4
-rw-r--r--src/com/android/gallery3d/app/PhotoDataAdapter.java2
-rw-r--r--src/com/android/gallery3d/app/SlideshowPage.java4
-rw-r--r--src/com/android/gallery3d/data/ClusterAlbum.java12
-rw-r--r--src/com/android/gallery3d/data/ClusterAlbumSet.java27
-rw-r--r--src/com/android/gallery3d/data/ComboAlbum.java24
-rw-r--r--src/com/android/gallery3d/data/ComboAlbumSet.java24
-rw-r--r--src/com/android/gallery3d/data/FilterDeleteSet.java21
-rw-r--r--src/com/android/gallery3d/data/FilterEmptyPromptSet.java9
-rw-r--r--src/com/android/gallery3d/data/FilterTypeSet.java20
-rw-r--r--src/com/android/gallery3d/data/LocalAlbum.java12
-rw-r--r--src/com/android/gallery3d/data/LocalAlbumSet.java113
-rw-r--r--src/com/android/gallery3d/data/LocalMergeAlbum.java30
-rw-r--r--src/com/android/gallery3d/data/MediaSet.java87
-rw-r--r--src/com/android/gallery3d/data/MediaSetWrapper.java47
-rw-r--r--src/com/android/gallery3d/data/SecureAlbum.java13
-rw-r--r--src/com/android/gallery3d/data/SingleItemAlbum.java9
-rw-r--r--src/com/android/gallery3d/data/SnailAlbum.java13
-rw-r--r--src/com/android/gallery3d/gadget/MediaSetSource.java2
-rw-r--r--src/com/android/photos/shims/MediaItemsLoader.java3
-rw-r--r--src/com/android/photos/shims/MediaSetLoader.java5
-rw-r--r--src_pd/com/android/gallery3d/picasasource/PicasaSource.java8
-rw-r--r--tests/src/com/android/gallery3d/data/LocalDataTest.java6
-rw-r--r--tests/src/com/android/gallery3d/data/MockSet.java9
-rw-r--r--tests/src/com/android/gallery3d/data/RealDataTest.java6
26 files changed, 206 insertions, 306 deletions
diff --git a/src/com/android/gallery3d/app/AlbumDataLoader.java b/src/com/android/gallery3d/app/AlbumDataLoader.java
index 77fd0db..28a8228 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 8c73d4e..cf380f8 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 d409315..fd3a7cf7 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 51bc70f..54aae67 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 684e610..8681952 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<Path> mPaths = new ArrayList<Path>();
@@ -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);
@@ -106,6 +106,14 @@ public class ClusterAlbum extends MediaSetWrapper implements ContentListener {
}
@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 a551de2..cb212ba 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 e193afa..cadd9f8 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 528ffcf..3f36745 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 7970d7c..c76412f 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<Deletion> mCurrent = new ArrayList<Deletion>();
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 f2623fb..b576e06 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<MediaItem>(1);
mEmptyItem.add(emptyItem);
mBaseSet = baseSet;
@@ -71,6 +71,11 @@ public class FilterEmptyPromptSet extends MediaSetWrapper implements ContentList
}
@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 d6fbbdb..477ef73 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<Path> mPaths = new ArrayList<Path>();
private final ArrayList<MediaSet> mAlbums = new ArrayList<MediaSet>();
@@ -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 8c92d3a..7b7015a 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 d71c9f7..b2b4b8c 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<ArrayList<MediaSet>> {
@SuppressWarnings("unused")
private static final String TAG = "LocalAlbumSet";
@@ -46,10 +52,16 @@ public class LocalAlbumSet extends MediaSet {
private ArrayList<MediaSet> mAlbums = new ArrayList<MediaSet>();
private final ChangeNotifier mNotifier;
private final String mName;
+ private final Handler mHandler;
+ private boolean mIsLoading;
+
+ private Future<ArrayList<MediaSet>> mLoadTask;
+ private ArrayList<MediaSet> 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<ArrayList<MediaSet>> {
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public ArrayList<MediaSet> 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<MediaSet> albums = new ArrayList<MediaSet>();
+ 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<ArrayList<MediaSet>> future) {
+ if (mLoadTask != future) return; // ignore, wait for the latest task
+ mLoadBuffer = future.get();
+ mIsLoading = false;
+ if (mLoadBuffer == null) mLoadBuffer = new ArrayList<MediaSet>();
+ 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 e07dc5e..f0b5e57 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<MediaItem> 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<MediaSet> matches = new ArrayList<MediaSet>();
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 d27adb8..683aa6b 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<Integer>, 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 986c51f..0000000
--- 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 04d51d1..204f848 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<Integer> 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 a404fa7..a0093e0 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 78f7188..7bce7a6 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 0e7e6bd..caeff2a 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 d758234..6142355 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<Cursor> 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<MediaItem> mediaItems = new SparseArray<MediaItem>();
diff --git a/src/com/android/photos/shims/MediaSetLoader.java b/src/com/android/photos/shims/MediaSetLoader.java
index d200807..9093bc1 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<Cursor> 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<MediaItem> coverItems = new ArrayList<MediaItem>(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 de457bf..5e800e2 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 67fc97a..8f6a46b 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 42f874b..fa83c79 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 7a984ef..526cfe3 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, "");
}