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.java33
-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_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
24 files changed, 300 insertions, 213 deletions
diff --git a/src/com/android/gallery3d/app/AlbumDataLoader.java b/src/com/android/gallery3d/app/AlbumDataLoader.java
index 28a8228..77fd0db 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.reload();
+ long version = mSource.loadIfDirty();
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 cf380f8..8c73d4e 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) {
- if (!mSource.isLoading()) updateLoading(false);
+ updateLoading(false);
Utils.waitWithoutInterrupt(this);
continue;
}
@@ -351,7 +351,7 @@ public class AlbumSetDataLoader {
mDirty = false;
updateLoading(true);
- long version = mSource.reload();
+ long version = mSource.loadIfDirty();
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 2b586da..faff146 100644
--- a/src/com/android/gallery3d/app/PhotoDataAdapter.java
+++ b/src/com/android/gallery3d/app/PhotoDataAdapter.java
@@ -1033,7 +1033,7 @@ public class PhotoDataAdapter implements PhotoPage.Model {
mDirty = false;
UpdateInfo info = executeAndWait(new GetUpdateInfo());
updateLoading(true);
- long version = mSource.reload();
+ long version = mSource.loadIfDirty();
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 54aae67..51bc70f 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.reload();
+ long version = mMediaSet.loadIfDirty();
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.reload();
+ long version = mMediaSet.loadIfDirty();
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 8681952..684e610 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 MediaSet implements ContentListener {
+public class ClusterAlbum extends MediaSetWrapper 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 MediaSet implements ContentListener {
public ClusterAlbum(Path path, DataManager dataManager,
MediaSet clusterAlbumSet) {
- super(path, nextVersionNumber());
+ super(clusterAlbumSet, path, nextVersionNumber());
mDataManager = dataManager;
mClusterAlbumSet = clusterAlbumSet;
mClusterAlbumSet.addContentListener(this);
@@ -106,14 +106,6 @@ public class ClusterAlbum extends MediaSet 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 cb212ba..a551de2 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 MediaSet implements ContentListener {
+public class ClusterAlbumSet extends MediaSetWrapper implements ContentListener {
@SuppressWarnings("unused")
private static final String TAG = "ClusterAlbumSet";
private GalleryApp mApplication;
@@ -35,7 +35,7 @@ public class ClusterAlbumSet extends MediaSet implements ContentListener {
public ClusterAlbumSet(Path path, GalleryApp application,
MediaSet baseSet, int kind) {
- super(path, INVALID_DATA_VERSION);
+ super(baseSet, path, INVALID_DATA_VERSION);
mApplication = application;
mBaseSet = baseSet;
mKind = kind;
@@ -58,17 +58,20 @@ public class ClusterAlbumSet extends MediaSet implements ContentListener {
}
@Override
- public long reload() {
- if (mBaseSet.reload() > mDataVersion) {
- if (mFirstReloadDone) {
- updateClustersContents();
- } else {
- updateClusters();
- mFirstReloadDone = true;
- }
- mDataVersion = nextVersionNumber();
+ protected boolean isDirtyLocked() {
+ return super.isDirtyLocked()
+ || !mFirstReloadDone;
+ }
+
+ @Override
+ public void load() throws InterruptedException {
+ super.load();
+ if (mFirstReloadDone) {
+ updateClustersContents();
+ } else {
+ updateClusters();
+ mFirstReloadDone = true;
}
- return mDataVersion;
}
@Override
diff --git a/src/com/android/gallery3d/data/ComboAlbum.java b/src/com/android/gallery3d/data/ComboAlbum.java
index cadd9f8..e193afa 100644
--- a/src/com/android/gallery3d/data/ComboAlbum.java
+++ b/src/com/android/gallery3d/data/ComboAlbum.java
@@ -27,11 +27,13 @@ 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);
}
@@ -81,14 +83,24 @@ public class ComboAlbum extends MediaSet implements ContentListener {
}
@Override
- public long reload() {
- boolean changed = false;
+ 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 {
for (int i = 0, n = mSets.length; i < n; ++i) {
- long version = mSets[i].reload();
- if (version > mDataVersion) changed = true;
+ if (mDirtySets[i]) {
+ mDirtySets[i] = false;
+ mSets[i].load();
+ }
}
- 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 a2a0412..528ffcf 100644
--- a/src/com/android/gallery3d/data/ComboAlbumSet.java
+++ b/src/com/android/gallery3d/data/ComboAlbumSet.java
@@ -27,11 +27,13 @@ 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);
}
@@ -66,31 +68,24 @@ public class ComboAlbumSet extends MediaSet implements ContentListener {
}
@Override
- public boolean isLoading() {
- for (int i = 0, n = mSets.length; i < n; ++i) {
- if (mSets[i].isLoading()) return true;
+ 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 false;
+ return dirty;
}
@Override
- public long reload() {
- boolean changed = false;
+ protected void load() throws InterruptedException {
for (int i = 0, n = mSets.length; i < n; ++i) {
- long version = mSets[i].reload();
- if (version > mDataVersion) changed = true;
- }
- if (changed) mDataVersion = nextVersionNumber();
- return mDataVersion;
- }
-
- @Override
- public boolean loadIfDirty() {
- boolean changed = false;
- for (int i = 0; i < mSets.length; i++) {
- changed |= mSets[i].loadIfDirty();
+ if (mDirtySets[i]) {
+ mDirtySets[i] = false;
+ mSets[i].load();
+ }
}
- return changed;
}
@Override
diff --git a/src/com/android/gallery3d/data/FilterDeleteSet.java b/src/com/android/gallery3d/data/FilterDeleteSet.java
index c76412f..7970d7c 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 MediaSet implements ContentListener {
+public class FilterDeleteSet extends MediaSetWrapper implements ContentListener {
@SuppressWarnings("unused")
private static final String TAG = "FilterDeleteSet";
@@ -65,7 +65,7 @@ public class FilterDeleteSet extends MediaSet implements ContentListener {
private ArrayList<Deletion> mCurrent = new ArrayList<Deletion>();
public FilterDeleteSet(Path path, MediaSet baseSet) {
- super(path, INVALID_DATA_VERSION);
+ super(baseSet, path, INVALID_DATA_VERSION);
mBaseSet = baseSet;
mBaseSet.addContentListener(this);
}
@@ -141,14 +141,18 @@ public class FilterDeleteSet extends MediaSet 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
- public long reload() {
- boolean newData = mBaseSet.reload() > mDataVersion;
+ protected void load() throws InterruptedException {
+ super.load();
synchronized (mRequests) {
- if (!newData && mRequests.isEmpty()) {
- return mDataVersion;
- }
for (int i = 0; i < mRequests.size(); i++) {
Request r = mRequests.get(i);
switch (r.type) {
@@ -218,9 +222,6 @@ public class FilterDeleteSet extends MediaSet 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 b576e06..f2623fb 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 MediaSet implements ContentListener {
+public class FilterEmptyPromptSet extends MediaSetWrapper implements ContentListener {
@SuppressWarnings("unused")
private static final String TAG = "FilterEmptyPromptSet";
@@ -26,7 +26,7 @@ public class FilterEmptyPromptSet extends MediaSet implements ContentListener {
private MediaSet mBaseSet;
public FilterEmptyPromptSet(Path path, MediaSet baseSet, MediaItem emptyItem) {
- super(path, INVALID_DATA_VERSION);
+ super(baseSet, path, INVALID_DATA_VERSION);
mEmptyItem = new ArrayList<MediaItem>(1);
mEmptyItem.add(emptyItem);
mBaseSet = baseSet;
@@ -71,11 +71,6 @@ public class FilterEmptyPromptSet extends MediaSet implements ContentListener {
}
@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 477ef73..d6fbbdb 100644
--- a/src/com/android/gallery3d/data/FilterTypeSet.java
+++ b/src/com/android/gallery3d/data/FilterTypeSet.java
@@ -25,6 +25,7 @@ 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>();
@@ -65,12 +66,17 @@ public class FilterTypeSet extends MediaSet implements ContentListener {
}
@Override
- public long reload() {
- if (mBaseSet.reload() > mDataVersion) {
- updateData();
- mDataVersion = nextVersionNumber();
+ protected boolean isDirtyLocked() {
+ mBaseSetIsDirty = mBaseSet.isDirtyLocked();
+ return mBaseSetIsDirty || mBaseSet.getDataVersion() > getDataVersion();
+ }
+
+ @Override
+ public void load() throws InterruptedException {
+ if (mBaseSetIsDirty) {
+ mBaseSet.load();
}
- return mDataVersion;
+ updateData();
}
@Override
@@ -78,7 +84,7 @@ public class FilterTypeSet extends MediaSet implements ContentListener {
notifyContentChanged();
}
- private void updateData() {
+ private void updateData() throws InterruptedException {
// Albums
mAlbums.clear();
String basePath = "/filter/mediatype/" + mMediaType;
@@ -87,7 +93,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.reload();
+ filteredSet.loadIfDirty();
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 7b7015a..8c92d3a 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
- public long reload() {
- if (mNotifier.isDirty()) {
- mDataVersion = nextVersionNumber();
- mCachedCount = INVALID_COUNT;
- }
- return mDataVersion;
+ protected boolean isDirtyLocked() {
+ return mNotifier.isDirty();
+ }
+ @Override
+ public void load() {
+ mCachedCount = INVALID_COUNT;
}
@Override
diff --git a/src/com/android/gallery3d/data/LocalAlbumSet.java b/src/com/android/gallery3d/data/LocalAlbumSet.java
index b2b4b8c..d71c9f7 100644
--- a/src/com/android/gallery3d/data/LocalAlbumSet.java
+++ b/src/com/android/gallery3d/data/LocalAlbumSet.java
@@ -17,26 +17,20 @@
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
- implements FutureListener<ArrayList<MediaSet>> {
+public class LocalAlbumSet extends MediaSet {
@SuppressWarnings("unused")
private static final String TAG = "LocalAlbumSet";
@@ -52,16 +46,10 @@ 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(
@@ -98,41 +86,6 @@ 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) {
@@ -155,43 +108,45 @@ public class LocalAlbumSet extends MediaSet
}
@Override
- public synchronized boolean isLoading() {
- return mIsLoading;
+ protected boolean isDirtyLocked() {
+ return mNotifier.isDirty();
}
@Override
- // 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);
+ 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();
}
- if (mLoadBuffer != null) {
- mAlbums = mLoadBuffer;
- mLoadBuffer = null;
- for (MediaSet album : mAlbums) {
- album.reload();
- }
- mDataVersion = nextVersionNumber();
+
+ 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);
}
- return mDataVersion;
- }
- @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();
- }
- });
+ mAlbums.clear();
+ DataManager dataManager = mApplication.getDataManager();
+ for (BucketEntry entry : entries) {
+ MediaSet album = getLocalAlbum(dataManager,
+ mType, mPath, entry.bucketId, entry.bucketName);
+ mAlbums.add(album);
+ }
+
+ for (MediaSet album : mAlbums) {
+ album.loadIfDirty();
+ }
}
// 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 f0b5e57..e07dc5e 100644
--- a/src/com/android/gallery3d/data/LocalMergeAlbum.java
+++ b/src/com/android/gallery3d/data/LocalMergeAlbum.java
@@ -24,7 +24,6 @@ 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;
@@ -40,6 +39,7 @@ 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,7 +70,6 @@ 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) {
@@ -173,17 +172,26 @@ public class LocalMergeAlbum extends MediaSet implements ContentListener {
}
@Override
- public long reload() {
- boolean changed = false;
+ protected boolean isDirtyLocked() {
+ boolean dirty = false;
for (int i = 0, n = mSources.length; i < n; ++i) {
- if (mSources[i].reload() > mDataVersion) changed = true;
+ mDirtySources[i] = mSources[i].isDirtyLocked();
+ dirty |= mDirtySources[i]
+ || mSources[i].getDataVersion() > getDataVersion();
}
- if (changed) {
- mDataVersion = nextVersionNumber();
- updateData();
- invalidateCache();
+ 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;
+ }
}
- return mDataVersion;
+ updateData();
+ invalidateCache();
}
@Override
diff --git a/src/com/android/gallery3d/data/MediaSet.java b/src/com/android/gallery3d/data/MediaSet.java
index 9bc148f..cc8a4a7 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;
diff --git a/src/com/android/gallery3d/data/MediaSetWrapper.java b/src/com/android/gallery3d/data/MediaSetWrapper.java
new file mode 100644
index 0000000..986c51f
--- /dev/null
+++ b/src/com/android/gallery3d/data/MediaSetWrapper.java
@@ -0,0 +1,47 @@
+/*
+ * 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 204f848..04d51d1 100644
--- a/src/com/android/gallery3d/data/SecureAlbum.java
+++ b/src/com/android/gallery3d/data/SecureAlbum.java
@@ -122,12 +122,13 @@ public class SecureAlbum extends MediaSet implements StitchingChangeListener {
}
@Override
- public long reload() {
- if (mNotifier.isDirty()) {
- mDataVersion = nextVersionNumber();
- updateExistingItems();
- }
- return mDataVersion;
+ protected boolean isDirtyLocked() {
+ return mNotifier.isDirty();
+ }
+
+ @Override
+ public void load() {
+ updateExistingItems();
}
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 a0093e0..a404fa7 100644
--- a/src/com/android/gallery3d/data/SingleItemAlbum.java
+++ b/src/com/android/gallery3d/data/SingleItemAlbum.java
@@ -62,7 +62,12 @@ public class SingleItemAlbum extends MediaSet {
}
@Override
- public long reload() {
- return mDataVersion;
+ protected boolean isDirtyLocked() {
+ return false;
}
+
+ @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 7bce7a6..78f7188 100644
--- a/src/com/android/gallery3d/data/SnailAlbum.java
+++ b/src/com/android/gallery3d/data/SnailAlbum.java
@@ -29,12 +29,13 @@ public class SnailAlbum extends SingleItemAlbum {
}
@Override
- public long reload() {
- if (mDirty.compareAndSet(true, false)) {
- ((SnailItem) getItem()).updateVersion();
- mDataVersion = nextVersionNumber();
- }
- return mDataVersion;
+ protected void load() throws InterruptedException {
+ ((SnailItem) getItem()).updateVersion();
+ }
+
+ @Override
+ protected boolean isDirtyLocked() {
+ return mDirty.compareAndSet(true, false);
}
public void notifyChange() {
diff --git a/src/com/android/gallery3d/gadget/MediaSetSource.java b/src/com/android/gallery3d/gadget/MediaSetSource.java
index caeff2a..0e7e6bd 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.reload();
+ long version = mSource.loadIfDirty();
if (mSourceVersion != version) {
mSourceVersion = version;
mCacheStart = 0;
diff --git a/src_pd/com/android/gallery3d/picasasource/PicasaSource.java b/src_pd/com/android/gallery3d/picasasource/PicasaSource.java
index 0418291..702b3b5 100644
--- a/src_pd/com/android/gallery3d/picasasource/PicasaSource.java
+++ b/src_pd/com/android/gallery3d/picasasource/PicasaSource.java
@@ -67,8 +67,12 @@ public class PicasaSource extends MediaSource {
}
@Override
- public long reload() {
- return mDataVersion;
+ protected boolean isDirtyLocked() {
+ return false;
+ }
+
+ @Override
+ protected void load() {
}
}
diff --git a/tests/src/com/android/gallery3d/data/LocalDataTest.java b/tests/src/com/android/gallery3d/data/LocalDataTest.java
index 8f6a46b..67fc97a 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.reload();
+ mAlbumSet.loadIfDirty();
verifyResult();
}
@@ -200,7 +200,7 @@ public class LocalDataTest extends AndroidTestCase {
sub.delete();
mAlbumSet.fakeChange();
latch.isOnContentDirtyBeCalled(DEFAULT_TIMEOUT);
- mAlbumSet.reload();
+ mAlbumSet.loadIfDirty();
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.reload();
+ sub.loadIfDirty();
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 fa83c79..42f874b 100644
--- a/tests/src/com/android/gallery3d/data/MockSet.java
+++ b/tests/src/com/android/gallery3d/data/MockSet.java
@@ -82,7 +82,12 @@ public class MockSet extends MediaSet {
}
@Override
- public long reload() {
- return 0;
+ protected boolean isDirtyLocked() {
+ return false;
}
+
+ @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 526cfe3..7a984ef 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.reload();
+ set.loadIfDirty();
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.reload();
+ set.loadIfDirty();
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.reload();
+ set.loadIfDirty();
Log.v(TAG, "PicasaAlbumSet");
dumpMediaSet(set, "");
}