summaryrefslogtreecommitdiffstats
path: root/src/com/android/gallery3d/data/LocalAlbumSet.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/gallery3d/data/LocalAlbumSet.java')
-rw-r--r--src/com/android/gallery3d/data/LocalAlbumSet.java113
1 files changed, 79 insertions, 34 deletions
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<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.