diff options
Diffstat (limited to 'src/com/android/gallery3d/data/MediaSet.java')
-rw-r--r-- | src/com/android/gallery3d/data/MediaSet.java | 348 |
1 files changed, 0 insertions, 348 deletions
diff --git a/src/com/android/gallery3d/data/MediaSet.java b/src/com/android/gallery3d/data/MediaSet.java deleted file mode 100644 index 683aa6b32..000000000 --- a/src/com/android/gallery3d/data/MediaSet.java +++ /dev/null @@ -1,348 +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.data; - -import com.android.gallery3d.common.Utils; -import com.android.gallery3d.util.Future; - -import java.util.ArrayList; -import java.util.WeakHashMap; - -// MediaSet is a directory-like data structure. -// It contains MediaItems and sub-MediaSets. -// -// The primary interface are: -// getMediaItemCount(), getMediaItem() and -// getSubMediaSetCount(), getSubMediaSet(). -// -// getTotalMediaItemCount() returns the number of all MediaItems, including -// those in sub-MediaSets. -public abstract class MediaSet extends MediaObject { - @SuppressWarnings("unused") - private static final String TAG = "MediaSet"; - - public static final int MEDIAITEM_BATCH_FETCH_COUNT = 500; - public static final int INDEX_NOT_FOUND = -1; - - public static final int SYNC_RESULT_SUCCESS = 0; - public static final int SYNC_RESULT_CANCELLED = 1; - public static final int SYNC_RESULT_ERROR = 2; - - /** Listener to be used with requestSync(SyncListener). */ - public static interface SyncListener { - /** - * Called when the sync task completed. Completion may be due to normal termination, - * an exception, or cancellation. - * - * @param mediaSet the MediaSet that's done with sync - * @param resultCode one of the SYNC_RESULT_* constants - */ - void onSyncDone(MediaSet mediaSet, int resultCode); - } - - public MediaSet(Path path, long version) { - super(path, version); - } - - public int getMediaItemCount() { - return 0; - } - - // Returns the media items in the range [start, start + count). - // - // The number of media items returned may be less than the specified count - // if there are not enough media items available. The number of - // media items available may not be consistent with the return value of - // getMediaItemCount() because the contents of database may have already - // changed. - public ArrayList<MediaItem> getMediaItem(int start, int count) { - return new ArrayList<MediaItem>(); - } - - public MediaItem getCoverMediaItem() { - ArrayList<MediaItem> items = getMediaItem(0, 1); - if (items.size() > 0) return items.get(0); - for (int i = 0, n = getSubMediaSetCount(); i < n; i++) { - MediaItem cover = getSubMediaSet(i).getCoverMediaItem(); - if (cover != null) return cover; - } - return null; - } - - public int getSubMediaSetCount() { - return 0; - } - - public MediaSet getSubMediaSet(int index) { - throw new IndexOutOfBoundsException(); - } - - public boolean isLeafAlbum() { - return false; - } - - public boolean isCameraRoll() { - 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++) { - total += getSubMediaSet(i).getTotalMediaItemCount(); - } - return total; - } - - // TODO: we should have better implementation of sub classes - public int getIndexOfItem(Path path, int hint) { - // hint < 0 is handled below - // first, try to find it around the hint - int start = Math.max(0, - hint - MEDIAITEM_BATCH_FETCH_COUNT / 2); - ArrayList<MediaItem> list = getMediaItem( - start, MEDIAITEM_BATCH_FETCH_COUNT); - int index = getIndexOf(path, list); - if (index != INDEX_NOT_FOUND) return start + index; - - // try to find it globally - start = start == 0 ? MEDIAITEM_BATCH_FETCH_COUNT : 0; - list = getMediaItem(start, MEDIAITEM_BATCH_FETCH_COUNT); - while (true) { - index = getIndexOf(path, list); - if (index != INDEX_NOT_FOUND) return start + index; - if (list.size() < MEDIAITEM_BATCH_FETCH_COUNT) return INDEX_NOT_FOUND; - start += MEDIAITEM_BATCH_FETCH_COUNT; - list = getMediaItem(start, MEDIAITEM_BATCH_FETCH_COUNT); - } - } - - protected int getIndexOf(Path path, ArrayList<MediaItem> list) { - for (int i = 0, n = list.size(); i < n; ++i) { - // item could be null only in ClusterAlbum - MediaObject item = list.get(i); - if (item != null && item.mPath == path) return i; - } - return INDEX_NOT_FOUND; - } - - public abstract String getName(); - - private WeakHashMap<ContentListener, Object> mListeners = - new WeakHashMap<ContentListener, Object>(); - - // NOTE: The MediaSet only keeps a weak reference to the listener. The - // listener is automatically removed when there is no other reference to - // the listener. - public void addContentListener(ContentListener listener) { - mListeners.put(listener, null); - } - - public void removeContentListener(ContentListener listener) { - mListeners.remove(listener); - } - - // This should be called by subclasses when the content is changed. - public void notifyContentChanged() { - for (ContentListener listener : mListeners.keySet()) { - listener.onContentDirty(); - } - } - - // 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() { - MediaDetails details = super.getDetails(); - details.addDetail(MediaDetails.INDEX_TITLE, getName()); - return details; - } - - // Enumerate all media items in this media set (including the ones in sub - // media sets), in an efficient order. ItemConsumer.consumer() will be - // called for each media item with its index. - public void enumerateMediaItems(ItemConsumer consumer) { - enumerateMediaItems(consumer, 0); - } - - public void enumerateTotalMediaItems(ItemConsumer consumer) { - enumerateTotalMediaItems(consumer, 0); - } - - public static interface ItemConsumer { - void consume(int index, MediaItem item); - } - - // The default implementation uses getMediaItem() for enumerateMediaItems(). - // Subclasses may override this and use more efficient implementations. - // Returns the number of items enumerated. - protected int enumerateMediaItems(ItemConsumer consumer, int startIndex) { - int total = getMediaItemCount(); - int start = 0; - while (start < total) { - int count = Math.min(MEDIAITEM_BATCH_FETCH_COUNT, total - start); - ArrayList<MediaItem> items = getMediaItem(start, count); - for (int i = 0, n = items.size(); i < n; i++) { - MediaItem item = items.get(i); - consumer.consume(startIndex + start + i, item); - } - start += count; - } - return total; - } - - // Recursively enumerate all media items under this set. - // Returns the number of items enumerated. - protected int enumerateTotalMediaItems( - ItemConsumer consumer, int startIndex) { - int start = 0; - start += enumerateMediaItems(consumer, startIndex); - int m = getSubMediaSetCount(); - for (int i = 0; i < m; i++) { - start += getSubMediaSet(i).enumerateTotalMediaItems( - consumer, startIndex + start); - } - return start; - } - - /** - * Requests sync on this MediaSet. It returns a Future object that can be used by the caller - * to query the status of the sync. The sync result code is one of the SYNC_RESULT_* constants - * defined in this class and can be obtained by Future.get(). - * - * Subclasses should perform sync on a different thread. - * - * The default implementation here returns a Future stub that does nothing and returns - * SYNC_RESULT_SUCCESS by get(). - */ - public Future<Integer> requestSync(SyncListener listener) { - listener.onSyncDone(this, SYNC_RESULT_SUCCESS); - return FUTURE_STUB; - } - - private static final Future<Integer> FUTURE_STUB = new Future<Integer>() { - @Override - public void cancel() {} - - @Override - public boolean isCancelled() { - return false; - } - - @Override - public boolean isDone() { - return true; - } - - @Override - public Integer get() { - return SYNC_RESULT_SUCCESS; - } - - @Override - public void waitDone() {} - }; - - protected Future<Integer> requestSyncOnMultipleSets(MediaSet[] sets, SyncListener listener) { - return new MultiSetSyncFuture(sets, listener); - } - - private class MultiSetSyncFuture implements Future<Integer>, SyncListener { - @SuppressWarnings("hiding") - private static final String TAG = "Gallery.MultiSetSync"; - - private final SyncListener mListener; - private final Future<Integer> mFutures[]; - - private boolean mIsCancelled = false; - private int mResult = -1; - private int mPendingCount; - - @SuppressWarnings("unchecked") - MultiSetSyncFuture(MediaSet[] sets, SyncListener listener) { - mListener = listener; - mPendingCount = sets.length; - mFutures = new Future[sets.length]; - - synchronized (this) { - for (int i = 0, n = sets.length; i < n; ++i) { - mFutures[i] = sets[i].requestSync(this); - Log.d(TAG, " request sync: " + Utils.maskDebugInfo(sets[i].getName())); - } - } - } - - @Override - public synchronized void cancel() { - if (mIsCancelled) return; - mIsCancelled = true; - for (Future<Integer> future : mFutures) future.cancel(); - if (mResult < 0) mResult = SYNC_RESULT_CANCELLED; - } - - @Override - public synchronized boolean isCancelled() { - return mIsCancelled; - } - - @Override - public synchronized boolean isDone() { - return mPendingCount == 0; - } - - @Override - public synchronized Integer get() { - waitDone(); - return mResult; - } - - @Override - public synchronized void waitDone() { - try { - while (!isDone()) wait(); - } catch (InterruptedException e) { - Log.d(TAG, "waitDone() interrupted"); - } - } - - // SyncListener callback - @Override - public void onSyncDone(MediaSet mediaSet, int resultCode) { - SyncListener listener = null; - synchronized (this) { - if (resultCode == SYNC_RESULT_ERROR) mResult = SYNC_RESULT_ERROR; - --mPendingCount; - if (mPendingCount == 0) { - listener = mListener; - notifyAll(); - } - Log.d(TAG, "onSyncDone: " + Utils.maskDebugInfo(mediaSet.getName()) - + " #pending=" + mPendingCount); - } - if (listener != null) listener.onSyncDone(MediaSet.this, mResult); - } - } -} |