summaryrefslogtreecommitdiffstats
path: root/src/com/android/gallery3d/app/AlbumSetDataLoader.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/gallery3d/app/AlbumSetDataLoader.java')
-rw-r--r--src/com/android/gallery3d/app/AlbumSetDataLoader.java393
1 files changed, 0 insertions, 393 deletions
diff --git a/src/com/android/gallery3d/app/AlbumSetDataLoader.java b/src/com/android/gallery3d/app/AlbumSetDataLoader.java
deleted file mode 100644
index cf380f812..000000000
--- a/src/com/android/gallery3d/app/AlbumSetDataLoader.java
+++ /dev/null
@@ -1,393 +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.Arrays;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutionException;
-import java.util.concurrent.FutureTask;
-
-public class AlbumSetDataLoader {
- @SuppressWarnings("unused")
- private static final String TAG = "AlbumSetDataAdapter";
-
- private static final int INDEX_NONE = -1;
-
- private static final int MIN_LOAD_COUNT = 4;
-
- private static final int MSG_LOAD_START = 1;
- private static final int MSG_LOAD_FINISH = 2;
- private static final int MSG_RUN_OBJECT = 3;
-
- public static interface DataListener {
- public void onContentChanged(int index);
- public void onSizeChanged(int size);
- }
-
- private final MediaSet[] mData;
- private final MediaItem[] mCoverItem;
- private final int[] mTotalCount;
- private final long[] mItemVersion;
- private final long[] mSetVersion;
-
- 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 int mSize;
-
- private DataListener mDataListener;
- private LoadingListener mLoadingListener;
- private ReloadTask mReloadTask;
-
- private final Handler mMainHandler;
-
- private final MySourceListener mSourceListener = new MySourceListener();
-
- public AlbumSetDataLoader(AbstractGalleryActivity activity, MediaSet albumSet, int cacheSize) {
- mSource = Utils.checkNotNull(albumSet);
- mCoverItem = new MediaItem[cacheSize];
- mData = new MediaSet[cacheSize];
- mTotalCount = new int[cacheSize];
- mItemVersion = new long[cacheSize];
- mSetVersion = new long[cacheSize];
- Arrays.fill(mItemVersion, MediaObject.INVALID_DATA_VERSION);
- Arrays.fill(mSetVersion, MediaObject.INVALID_DATA_VERSION);
-
- mMainHandler = new SynchronizedHandler(activity.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) mLoadingListener.onLoadingFinished(false);
- return;
- }
- }
- };
- }
-
- public void pause() {
- mReloadTask.terminate();
- mReloadTask = null;
- mSource.removeContentListener(mSourceListener);
- }
-
- public void resume() {
- mSource.addContentListener(mSourceListener);
- mReloadTask = new ReloadTask();
- mReloadTask.start();
- }
-
- private void assertIsActive(int index) {
- if (index < mActiveStart && index >= mActiveEnd) {
- throw new IllegalArgumentException(String.format(
- "%s not in (%s, %s)", index, mActiveStart, mActiveEnd));
- }
- }
-
- public MediaSet getMediaSet(int index) {
- assertIsActive(index);
- return mData[index % mData.length];
- }
-
- public MediaItem getCoverItem(int index) {
- assertIsActive(index);
- return mCoverItem[index % mCoverItem.length];
- }
-
- public int getTotalCount(int index) {
- assertIsActive(index);
- return mTotalCount[index % mTotalCount.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 MediaSet with the given path or
- // -1 if the path is not cached
- public int findSet(Path id) {
- int length = mData.length;
- for (int i = mContentStart; i < mContentEnd; i++) {
- MediaSet set = mData[i % length];
- if (set != null && id == set.getPath()) {
- return i;
- }
- }
- return -1;
- }
-
- private void clearSlot(int slotIndex) {
- mData[slotIndex] = null;
- mCoverItem[slotIndex] = null;
- mTotalCount[slotIndex] = 0;
- 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 length = mCoverItem.length;
-
- int start = this.mContentStart;
- int end = this.mContentEnd;
-
- mContentStart = contentStart;
- mContentEnd = contentEnd;
-
- if (contentStart >= end || start >= contentEnd) {
- for (int i = start, n = end; i < n; ++i) {
- clearSlot(i % length);
- }
- } else {
- for (int i = start; i < contentStart; ++i) {
- clearSlot(i % length);
- }
- for (int i = contentEnd, n = end; i < n; ++i) {
- clearSlot(i % length);
- }
- }
- mReloadTask.notifyDirty();
- }
-
- public void setActiveWindow(int start, int end) {
- if (start == mActiveStart && end == mActiveEnd) return;
-
- Utils.assertTrue(start <= end
- && end - start <= mCoverItem.length && end <= mSize);
-
- mActiveStart = start;
- mActiveEnd = end;
-
- int length = mCoverItem.length;
- // 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() {
- mReloadTask.notifyDirty();
- }
- }
-
- public void setModelListener(DataListener listener) {
- mDataListener = listener;
- }
-
- public void setLoadingListener(LoadingListener listener) {
- mLoadingListener = listener;
- }
-
- private static class UpdateInfo {
- public long version;
- public int index;
-
- public int size;
- public MediaSet item;
- public MediaItem cover;
- public int totalCount;
- }
-
- private class GetUpdateInfo implements Callable<UpdateInfo> {
-
- private final long mVersion;
-
- public GetUpdateInfo(long version) {
- mVersion = version;
- }
-
- private int getInvalidIndex(long version) {
- long setVersion[] = mSetVersion;
- int length = setVersion.length;
- for (int i = mContentStart, n = mContentEnd; i < n; ++i) {
- int index = i % length;
- if (setVersion[i % length] != version) return i;
- }
- return INDEX_NONE;
- }
-
- @Override
- public UpdateInfo call() throws Exception {
- int index = getInvalidIndex(mVersion);
- if (index == INDEX_NONE && mSourceVersion == mVersion) return null;
- UpdateInfo info = new UpdateInfo();
- info.version = mSourceVersion;
- info.index = index;
- info.size = mSize;
- return info;
- }
- }
-
- private class UpdateContent implements Callable<Void> {
- private final UpdateInfo mUpdateInfo;
-
- public UpdateContent(UpdateInfo info) {
- mUpdateInfo = info;
- }
-
- @Override
- public Void call() {
- // Avoid notifying listeners of status change after pause
- // Otherwise gallery will be in inconsistent state after resume.
- if (mReloadTask == null) return null;
- 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;
- }
- // Note: info.index could be INDEX_NONE, i.e., -1
- if (info.index >= mContentStart && info.index < mContentEnd) {
- int pos = info.index % mCoverItem.length;
- mSetVersion[pos] = info.version;
- long itemVersion = info.item.getDataVersion();
- if (mItemVersion[pos] == itemVersion) return null;
- mItemVersion[pos] = itemVersion;
- mData[pos] = info.item;
- mCoverItem[pos] = info.cover;
- mTotalCount[pos] = info.totalCount;
- if (mDataListener != null
- && info.index >= mActiveStart && info.index < mActiveEnd) {
- mDataListener.onContentChanged(info.index);
- }
- }
- return null;
- }
- }
-
- 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);
- }
- }
-
- // TODO: load active range first
- private class ReloadTask extends Thread {
- private volatile boolean mActive = true;
- private volatile boolean mDirty = true;
- private volatile 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) {
- if (!mSource.isLoading()) updateLoading(false);
- Utils.waitWithoutInterrupt(this);
- 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.version = version;
- info.size = mSource.getSubMediaSetCount();
-
- // If the size becomes smaller after reload(), we may
- // receive from GetUpdateInfo an index which is too
- // big. Because the main thread is not aware of the size
- // change until we call UpdateContent.
- if (info.index >= info.size) {
- info.index = INDEX_NONE;
- }
- }
- if (info.index != INDEX_NONE) {
- info.item = mSource.getSubMediaSet(info.index);
- if (info.item == null) continue;
- info.cover = info.item.getCoverMediaItem();
- info.totalCount = info.item.getTotalMediaItemCount();
- }
- executeAndWait(new UpdateContent(info));
- }
- updateLoading(false);
- }
-
- public synchronized void notifyDirty() {
- mDirty = true;
- notifyAll();
- }
-
- public synchronized void terminate() {
- mActive = false;
- notifyAll();
- }
- }
-}
-
-