summaryrefslogtreecommitdiffstats
path: root/src/com/android/gallery3d/app/AlbumDataLoader.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/gallery3d/app/AlbumDataLoader.java')
-rw-r--r--src/com/android/gallery3d/app/AlbumDataLoader.java397
1 files changed, 0 insertions, 397 deletions
diff --git a/src/com/android/gallery3d/app/AlbumDataLoader.java b/src/com/android/gallery3d/app/AlbumDataLoader.java
deleted file mode 100644
index 28a822830..000000000
--- a/src/com/android/gallery3d/app/AlbumDataLoader.java
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Copyright (C) 2010 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.app;
-
-import android.os.Handler;
-import android.os.Message;
-import android.os.Process;
-
-import com.android.gallery3d.common.Utils;
-import com.android.gallery3d.data.ContentListener;
-import com.android.gallery3d.data.MediaItem;
-import com.android.gallery3d.data.MediaObject;
-import com.android.gallery3d.data.MediaSet;
-import com.android.gallery3d.data.Path;
-import com.android.gallery3d.ui.SynchronizedHandler;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.FutureTask;
-
-public class AlbumDataLoader {
- @SuppressWarnings("unused")
- private static final String TAG = "AlbumDataAdapter";
- private static final int DATA_CACHE_SIZE = 1000;
-
- private static final int MSG_LOAD_START = 1;
- private static final int MSG_LOAD_FINISH = 2;
- private static final int MSG_RUN_OBJECT = 3;
-
- private static final int MIN_LOAD_COUNT = 32;
- private static final int MAX_LOAD_COUNT = 64;
-
- private final MediaItem[] mData;
- private final long[] mItemVersion;
- private final long[] mSetVersion;
-
- public static interface DataListener {
- public void onContentChanged(int index);
- public void onSizeChanged(int size);
- }
-
- private int mActiveStart = 0;
- private int mActiveEnd = 0;
-
- private int mContentStart = 0;
- private int mContentEnd = 0;
-
- private final MediaSet mSource;
- private long mSourceVersion = MediaObject.INVALID_DATA_VERSION;
-
- private final Handler mMainHandler;
- private int mSize = 0;
-
- private DataListener mDataListener;
- private MySourceListener mSourceListener = new MySourceListener();
- private LoadingListener mLoadingListener;
-
- private ReloadTask mReloadTask;
- // the data version on which last loading failed
- private long mFailedVersion = MediaObject.INVALID_DATA_VERSION;
-
- public AlbumDataLoader(AbstractGalleryActivity context, MediaSet mediaSet) {
- mSource = mediaSet;
-
- mData = new MediaItem[DATA_CACHE_SIZE];
- mItemVersion = new long[DATA_CACHE_SIZE];
- mSetVersion = new long[DATA_CACHE_SIZE];
- Arrays.fill(mItemVersion, MediaObject.INVALID_DATA_VERSION);
- Arrays.fill(mSetVersion, MediaObject.INVALID_DATA_VERSION);
-
- mMainHandler = new SynchronizedHandler(context.getGLRoot()) {
- @Override
- public void handleMessage(Message message) {
- switch (message.what) {
- case MSG_RUN_OBJECT:
- ((Runnable) message.obj).run();
- return;
- case MSG_LOAD_START:
- if (mLoadingListener != null) mLoadingListener.onLoadingStarted();
- return;
- case MSG_LOAD_FINISH:
- if (mLoadingListener != null) {
- boolean loadingFailed =
- (mFailedVersion != MediaObject.INVALID_DATA_VERSION);
- mLoadingListener.onLoadingFinished(loadingFailed);
- }
- return;
- }
- }
- };
- }
-
- public void resume() {
- mSource.addContentListener(mSourceListener);
- mReloadTask = new ReloadTask();
- mReloadTask.start();
- }
-
- public void pause() {
- mReloadTask.terminate();
- mReloadTask = null;
- mSource.removeContentListener(mSourceListener);
- }
-
- public MediaItem get(int index) {
- if (!isActive(index)) {
- return mSource.getMediaItem(index, 1).get(0);
- }
- return mData[index % mData.length];
- }
-
- public int getActiveStart() {
- return mActiveStart;
- }
-
- public boolean isActive(int index) {
- return index >= mActiveStart && index < mActiveEnd;
- }
-
- public int size() {
- return mSize;
- }
-
- // Returns the index of the MediaItem with the given path or
- // -1 if the path is not cached
- public int findItem(Path id) {
- for (int i = mContentStart; i < mContentEnd; i++) {
- MediaItem item = mData[i % DATA_CACHE_SIZE];
- if (item != null && id == item.getPath()) {
- return i;
- }
- }
- return -1;
- }
-
- private void clearSlot(int slotIndex) {
- mData[slotIndex] = null;
- mItemVersion[slotIndex] = MediaObject.INVALID_DATA_VERSION;
- mSetVersion[slotIndex] = MediaObject.INVALID_DATA_VERSION;
- }
-
- private void setContentWindow(int contentStart, int contentEnd) {
- if (contentStart == mContentStart && contentEnd == mContentEnd) return;
- int end = mContentEnd;
- int start = mContentStart;
-
- // We need change the content window before calling reloadData(...)
- synchronized (this) {
- mContentStart = contentStart;
- mContentEnd = contentEnd;
- }
- long[] itemVersion = mItemVersion;
- long[] setVersion = mSetVersion;
- if (contentStart >= end || start >= contentEnd) {
- for (int i = start, n = end; i < n; ++i) {
- clearSlot(i % DATA_CACHE_SIZE);
- }
- } else {
- for (int i = start; i < contentStart; ++i) {
- clearSlot(i % DATA_CACHE_SIZE);
- }
- for (int i = contentEnd, n = end; i < n; ++i) {
- clearSlot(i % DATA_CACHE_SIZE);
- }
- }
- if (mReloadTask != null) mReloadTask.notifyDirty();
- }
-
- public void setActiveWindow(int start, int end) {
- if (start == mActiveStart && end == mActiveEnd) return;
-
- Utils.assertTrue(start <= end
- && end - start <= mData.length && end <= mSize);
-
- int length = mData.length;
- mActiveStart = start;
- mActiveEnd = end;
-
- // If no data is visible, keep the cache content
- if (start == end) return;
-
- int contentStart = Utils.clamp((start + end) / 2 - length / 2,
- 0, Math.max(0, mSize - length));
- int contentEnd = Math.min(contentStart + length, mSize);
- if (mContentStart > start || mContentEnd < end
- || Math.abs(contentStart - mContentStart) > MIN_LOAD_COUNT) {
- setContentWindow(contentStart, contentEnd);
- }
- }
-
- private class MySourceListener implements ContentListener {
- @Override
- public void onContentDirty() {
- if (mReloadTask != null) mReloadTask.notifyDirty();
- }
- }
-
- public void setDataListener(DataListener listener) {
- mDataListener = listener;
- }
-
- public void setLoadingListener(LoadingListener listener) {
- mLoadingListener = listener;
- }
-
- private <T> T executeAndWait(Callable<T> callable) {
- FutureTask<T> task = new FutureTask<T>(callable);
- mMainHandler.sendMessage(
- mMainHandler.obtainMessage(MSG_RUN_OBJECT, task));
- try {
- return task.get();
- } catch (InterruptedException e) {
- return null;
- } catch (ExecutionException e) {
- throw new RuntimeException(e);
- }
- }
-
- private static class UpdateInfo {
- public long version;
- public int reloadStart;
- public int reloadCount;
-
- public int size;
- public ArrayList<MediaItem> items;
- }
-
- private class GetUpdateInfo implements Callable<UpdateInfo> {
- private final long mVersion;
-
- public GetUpdateInfo(long version) {
- mVersion = version;
- }
-
- @Override
- public UpdateInfo call() throws Exception {
- if (mFailedVersion == mVersion) {
- // previous loading failed, return null to pause loading
- return null;
- }
- UpdateInfo info = new UpdateInfo();
- long version = mVersion;
- info.version = mSourceVersion;
- info.size = mSize;
- long setVersion[] = mSetVersion;
- for (int i = mContentStart, n = mContentEnd; i < n; ++i) {
- int index = i % DATA_CACHE_SIZE;
- if (setVersion[index] != version) {
- info.reloadStart = i;
- info.reloadCount = Math.min(MAX_LOAD_COUNT, n - i);
- return info;
- }
- }
- return mSourceVersion == mVersion ? null : info;
- }
- }
-
- private class UpdateContent implements Callable<Void> {
-
- private UpdateInfo mUpdateInfo;
-
- public UpdateContent(UpdateInfo info) {
- mUpdateInfo = info;
- }
-
- @Override
- public Void call() throws Exception {
- UpdateInfo info = mUpdateInfo;
- mSourceVersion = info.version;
- if (mSize != info.size) {
- mSize = info.size;
- if (mDataListener != null) mDataListener.onSizeChanged(mSize);
- if (mContentEnd > mSize) mContentEnd = mSize;
- if (mActiveEnd > mSize) mActiveEnd = mSize;
- }
-
- ArrayList<MediaItem> items = info.items;
-
- mFailedVersion = MediaObject.INVALID_DATA_VERSION;
- if ((items == null) || items.isEmpty()) {
- if (info.reloadCount > 0) {
- mFailedVersion = info.version;
- Log.d(TAG, "loading failed: " + mFailedVersion);
- }
- return null;
- }
- int start = Math.max(info.reloadStart, mContentStart);
- int end = Math.min(info.reloadStart + items.size(), mContentEnd);
-
- for (int i = start; i < end; ++i) {
- int index = i % DATA_CACHE_SIZE;
- mSetVersion[index] = info.version;
- MediaItem updateItem = items.get(i - info.reloadStart);
- long itemVersion = updateItem.getDataVersion();
- if (mItemVersion[index] != itemVersion) {
- mItemVersion[index] = itemVersion;
- mData[index] = updateItem;
- if (mDataListener != null && i >= mActiveStart && i < mActiveEnd) {
- mDataListener.onContentChanged(i);
- }
- }
- }
- return null;
- }
- }
-
- /*
- * The thread model of ReloadTask
- * *
- * [Reload Task] [Main Thread]
- * | |
- * getUpdateInfo() --> | (synchronous call)
- * (wait) <---- getUpdateInfo()
- * | |
- * Load Data |
- * | |
- * updateContent() --> | (synchronous call)
- * (wait) updateContent()
- * | |
- * | |
- */
- private class ReloadTask extends Thread {
-
- private volatile boolean mActive = true;
- private volatile boolean mDirty = true;
- private boolean mIsLoading = false;
-
- private void updateLoading(boolean loading) {
- if (mIsLoading == loading) return;
- mIsLoading = loading;
- mMainHandler.sendEmptyMessage(loading ? MSG_LOAD_START : MSG_LOAD_FINISH);
- }
-
- @Override
- public void run() {
- Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
-
- boolean updateComplete = false;
- while (mActive) {
- synchronized (this) {
- if (mActive && !mDirty && updateComplete) {
- updateLoading(false);
- if (mFailedVersion != MediaObject.INVALID_DATA_VERSION) {
- Log.d(TAG, "reload pause");
- }
- Utils.waitWithoutInterrupt(this);
- if (mActive && (mFailedVersion != MediaObject.INVALID_DATA_VERSION)) {
- Log.d(TAG, "reload resume");
- }
- continue;
- }
- mDirty = false;
- }
- updateLoading(true);
- long version = mSource.reload();
- UpdateInfo info = executeAndWait(new GetUpdateInfo(version));
- updateComplete = info == null;
- if (updateComplete) continue;
- if (info.version != version) {
- info.size = mSource.getMediaItemCount();
- info.version = version;
- }
- if (info.reloadCount > 0) {
- info.items = mSource.getMediaItem(info.reloadStart, info.reloadCount);
- }
- executeAndWait(new UpdateContent(info));
- }
- updateLoading(false);
- }
-
- public synchronized void notifyDirty() {
- mDirty = true;
- notifyAll();
- }
-
- public synchronized void terminate() {
- mActive = false;
- notifyAll();
- }
- }
-}