MediaFeed.java revision 053a906072e581a9bd381003ceefdf14636a7c1d
1f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparkspackage com.cooliris.media; 2f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 3f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport java.util.ArrayList; 4f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport java.util.HashMap; 5f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 6f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.content.Context; 7f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.view.Gravity; 8f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.widget.Toast; 9f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.os.Process; 10f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 11f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport com.cooliris.media.MediaClustering.Cluster; 12f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 13f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparkspublic final class MediaFeed implements Runnable { 14f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public static final int OPERATION_DELETE = 0; 15f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public static final int OPERATION_ROTATE = 1; 16f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public static final int OPERATION_CROP = 2; 17f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 18f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private static final int NUM_ITEMS_LOOKAHEAD = 60; 19f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 20f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private IndexRange mVisibleRange = new IndexRange(); 21f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private IndexRange mBufferedRange = new IndexRange(); 22f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private ArrayList<MediaSet> mMediaSets = new ArrayList<MediaSet>(); 23f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private Listener mListener; 24f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private DataSource mDataSource; 25f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private boolean mListenerNeedsUpdate = false; 26d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks private boolean mMediaFeedNeedsToRun = false; 27f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private MediaSet mSingleWrapper = new MediaSet(); 28f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private boolean mInClusteringMode = false; 29f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private HashMap<MediaSet, MediaClustering> mClusterSets = new HashMap<MediaSet, MediaClustering>(32); 30f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private int mExpandedMediaSetIndex = Shared.INVALID; 31f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private MediaFilter mMediaFilter; 32f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private MediaSet mMediaFilteredSet; 33f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private Context mContext; 34f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private Thread mDataSourceThread = null; 35f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private Thread mAlbumSourceThread = null; 36f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private boolean mListenerNeedsLayout; 37f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private boolean mWaitingForMediaScanner; 38f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private boolean mSingleImageMode; 39f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private boolean mLoading; 40f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 41f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public interface Listener { 42f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public abstract void onFeedAboutToChange(MediaFeed feed); 43f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 44f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public abstract void onFeedChanged(MediaFeed feed, boolean needsLayout); 45f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 46f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 47f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public MediaFeed(Context context, DataSource dataSource, Listener listener) { 48f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mContext = context; 49f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener = listener; 50f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mDataSource = dataSource; 51f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mSingleWrapper.setNumExpectedItems(1); 52f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mLoading = true; 53f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 54d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks 55f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void shutdown() { 56f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mDataSourceThread != null) { 57f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mDataSource.shutdown(); 58f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mDataSourceThread.interrupt(); 59f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mDataSourceThread = null; 60f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 61f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mAlbumSourceThread != null) { 62f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mAlbumSourceThread.interrupt(); 63f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mAlbumSourceThread = null; 64f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 65f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numSets = mMediaSets.size(); 66f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 0; i < numSets; ++i) { 67f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mMediaSets.get(i); 68f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks set.clear(); 69f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 70f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks synchronized (mMediaSets) { 71f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mMediaSets.clear(); 72f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 73f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numClusters = mClusterSets.size(); 74f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 0; i < numClusters; ++i) { 75f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering mc = mClusterSets.get(i); 76f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mc != null) { 77f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mc.clear(); 78f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 79f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 80f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mClusterSets.clear(); 81f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener = null; 82f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mDataSource = null; 83f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mSingleWrapper = null; 84f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 85f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 86f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void setVisibleRange(int begin, int end) { 87d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks if (begin != mVisibleRange.begin || end != mVisibleRange.end) { 88d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mVisibleRange.begin = begin; 89d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mVisibleRange.end = end; 90d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks int numItems = 96; 91d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks int numItemsBy2 = numItems / 2; 92d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks int numItemsBy4 = numItems / 4; 93d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mBufferedRange.begin = (begin / numItemsBy2) * numItemsBy2 - numItemsBy4; 94d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mBufferedRange.end = mBufferedRange.begin + numItems; 95d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 96d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks } 97f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 98f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 99f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void setFilter(MediaFilter filter) { 100f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mMediaFilter = filter; 101f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mMediaFilteredSet = null; 102f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mListener != null) { 103f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener.onFeedAboutToChange(this); 104f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 105d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 106f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 107f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 108f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void removeFilter() { 109f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mMediaFilter = null; 110f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mMediaFilteredSet = null; 111f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mListener != null) { 112f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener.onFeedAboutToChange(this); 113f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks updateListener(true); 114f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 115d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 116f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 117f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 118f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public ArrayList<MediaSet> getMediaSets() { 119f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mMediaSets; 120f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 121f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 122d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks public MediaSet getMediaSet(final long setId) { 123f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (setId != Shared.INVALID) { 124d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks try { 125d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks int mMediaSetsSize = mMediaSets.size(); 126d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks for (int i = 0; i < mMediaSetsSize; i++) { 127d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks if (mMediaSets.get(i).mId == setId) { 128d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks return mMediaSets.get(i); 129d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks } 130f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 131d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks } catch (Exception e) { 132d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks return null; 133f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 134f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 135f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 136f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 137f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 138f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public MediaSet getFilteredSet() { 139f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mMediaFilteredSet; 140f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 141f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 142f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public MediaSet addMediaSet(final long setId, DataSource dataSource) { 143f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet mediaSet = new MediaSet(dataSource); 144f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSet.mId = setId; 145f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mMediaSets.add(mediaSet); 146d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks if (mDataSourceThread != null && !mDataSourceThread.isAlive()) { 147d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mDataSourceThread.start(); 148d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks } 149d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 150f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mediaSet; 151f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 152f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 153f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public DataSource getDataSource() { 154f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mDataSource; 155f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 156f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 157f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public MediaClustering getClustering() { 158f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mExpandedMediaSetIndex != Shared.INVALID && mExpandedMediaSetIndex < mMediaSets.size()) { 159f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mClusterSets.get(mMediaSets.get(mExpandedMediaSetIndex)); 160f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 161f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 162f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 163f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 164f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public ArrayList<Cluster> getClustersForSet(final MediaSet set) { 165f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<Cluster> clusters = null; 166f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mClusterSets != null && mClusterSets.containsKey(set)) { 167f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering mediaClustering = mClusterSets.get(set); 168f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mediaClustering != null) { 169f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clusters = mediaClustering.getClusters(); 170f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 171f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 172f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return clusters; 173f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 174f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 175f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void addItemToMediaSet(MediaItem item, MediaSet mediaSet) { 176f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks item.mParentMediaSet = mediaSet; 177f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSet.addItem(item); 178d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks synchronized (mClusterSets) { 179f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (item.mClusteringState == MediaItem.NOT_CLUSTERED) { 180f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = mClusterSets.get(mediaSet); 181f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clustering == null) { 182f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering = new MediaClustering(mediaSet.isPicassaAlbum()); 183f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mClusterSets.put(mediaSet, clustering); 184f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 185f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering.setTimeRange(mediaSet.mMaxTimestamp - mediaSet.mMinTimestamp, mediaSet.getNumExpectedItems()); 186f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering.addItemForClustering(item); 187f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks item.mClusteringState = MediaItem.CLUSTERED; 188f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 189f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 190d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 191f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 192f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 193f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void performOperation(final int operation, final ArrayList<MediaBucket> mediaBuckets, final Object data) { 194f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numBuckets = mediaBuckets.size(); 195f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks final ArrayList<MediaBucket> copyMediaBuckets = new ArrayList<MediaBucket>(numBuckets); 196f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 0; i < numBuckets; ++i) { 197f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks copyMediaBuckets.add(mediaBuckets.get(i)); 198f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 199f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (operation == OPERATION_DELETE && mListener != null) { 200f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener.onFeedAboutToChange(this); 201f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 202f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks Thread operationThread = new Thread(new Runnable() { 203f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void run() { 204f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaBucket> mediaBuckets = copyMediaBuckets; 205f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (operation == OPERATION_DELETE) { 206f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numBuckets = mediaBuckets.size(); 207f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 0; i < numBuckets; ++i) { 208f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaBucket bucket = mediaBuckets.get(i); 209f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = bucket.mediaSet; 210f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaItem> items = bucket.mediaItems; 211f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (set != null && items == null) { 212f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // Remove the entire bucket. 213f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks removeMediaSet(set); 214f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } else if (set != null && items != null) { 215f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // We need to remove these items from the set. 216f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numItems = items.size(); 217f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // We also need to delete the items from the cluster. 218f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = mClusterSets.get(set); 219f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int j = 0; j < numItems; ++j) { 220f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaItem item = items.get(j); 221f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks removeItemFromMediaSet(item, set); 222f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clustering != null) { 223f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering.removeItemFromClustering(item); 224f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 225f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 226f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks set.updateNumExpectedItems(); 227f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks set.generateTitle(true); 228f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 229f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 230f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks updateListener(true); 231d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 232f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mDataSource != null) { 233f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mDataSource.performOperation(OPERATION_DELETE, mediaBuckets, null); 234f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 235f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } else { 236f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mDataSource.performOperation(operation, mediaBuckets, data); 237f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 238f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 239f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks }); 240f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks operationThread.setName("Operation " + operation); 241f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks operationThread.start(); 242f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 243f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 244f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void removeMediaSet(MediaSet set) { 2452b04f591f758b7af03c43d90e91b939cbd515506Venkat Krishnaraj synchronized (mMediaSets) { 2462b04f591f758b7af03c43d90e91b939cbd515506Venkat Krishnaraj mMediaSets.remove(set); 2472b04f591f758b7af03c43d90e91b939cbd515506Venkat Krishnaraj } 248d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 249f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 250f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 251f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private void removeItemFromMediaSet(MediaItem item, MediaSet mediaSet) { 252f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSet.removeItem(item); 253d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks synchronized (mClusterSets) { 254f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = mClusterSets.get(mediaSet); 255f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clustering != null) { 256f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering.removeItemFromClustering(item); 257f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 258f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 259d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 260f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 261f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 262f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void updateListener(boolean needsLayout) { 263f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListenerNeedsUpdate = true; 264f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListenerNeedsLayout = needsLayout; 265f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 266f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 267f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public int getNumSlots() { 268f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int currentMediaSetIndex = mExpandedMediaSetIndex; 269f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaSet> mediaSets = mMediaSets; 270f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int mediaSetsSize = mediaSets.size(); 271f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 272f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mInClusteringMode == false) { 273f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (currentMediaSetIndex == Shared.INVALID || currentMediaSetIndex >= mediaSetsSize) { 274f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mediaSetsSize; 275f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } else { 276f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet setToUse = (mMediaFilteredSet == null) ? mediaSets.get(currentMediaSetIndex) : mMediaFilteredSet; 277f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return setToUse.getNumItems(); 278f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 279f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } else if (currentMediaSetIndex != Shared.INVALID && currentMediaSetIndex < mediaSetsSize) { 280f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mediaSets.get(currentMediaSetIndex); 281f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = mClusterSets.get(set); 282f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clustering != null) { 283f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return clustering.getClustersForDisplay().size(); 284f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 285f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 286f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return 0; 287f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 288f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 289f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public MediaSet getSetForSlot(int slotIndex) { 290f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (slotIndex < 0) { 291f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 292f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 293f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 294f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaSet> mediaSets = mMediaSets; 295f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int mediaSetsSize = mediaSets.size(); 296f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int currentMediaSetIndex = mExpandedMediaSetIndex; 297f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 298f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mInClusteringMode == false) { 299f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (currentMediaSetIndex == Shared.INVALID || currentMediaSetIndex >= mediaSetsSize) { 300f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (slotIndex >= mediaSetsSize) { 301f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 302f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 303f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mMediaSets.get(slotIndex); 304f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 305f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mSingleWrapper.getNumItems() == 0) { 306f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mSingleWrapper.addItem(null); 307f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 308f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet setToUse = (mMediaFilteredSet == null) ? mMediaSets.get(currentMediaSetIndex) : mMediaFilteredSet; 309f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaItem> items = setToUse.getItems(); 310f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (slotIndex >= setToUse.getNumItems()) { 311f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 312f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 313f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mSingleWrapper.getItems().set(0, items.get(slotIndex)); 314f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mSingleWrapper; 315f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } else if (currentMediaSetIndex != Shared.INVALID && currentMediaSetIndex < mediaSetsSize) { 316f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mediaSets.get(currentMediaSetIndex); 317f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = mClusterSets.get(set); 318f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clustering != null) { 319f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaClustering.Cluster> clusters = clustering.getClustersForDisplay(); 320f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clusters.size() > slotIndex) { 321f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering.Cluster cluster = clusters.get(slotIndex); 322f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks cluster.generateCaption(mContext); 323f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return cluster; 324f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 325f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 326f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 327f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 328f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 329f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 330f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public boolean getWaitingForMediaScanner() { 331f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mWaitingForMediaScanner; 332f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 333d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks 334f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public boolean isLoading() { 335f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mLoading; 336f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 337f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 338f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void start() { 339f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks final MediaFeed feed = this; 340f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mLoading = true; 341d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mDataSourceThread = new Thread(this); 342d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mDataSourceThread.setName("MediaFeed"); 343f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mAlbumSourceThread = new Thread(new Runnable() { 344f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void run() { 345f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mContext == null) 346f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return; 347f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 348f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks DataSource dataSource = mDataSource; 349f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // We must wait while the SD card is mounted or the MediaScanner is running. 350d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks if (dataSource != null) { 351d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks dataSource.loadMediaSets(feed); 352d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks } 353f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mWaitingForMediaScanner = false; 354f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks while (ImageManager.isMediaScannerScanning(mContext.getContentResolver())) { 355f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // MediaScanner is still running, wait 356f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mWaitingForMediaScanner = true; 357f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks try { 358f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mContext == null) 359f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return; 360f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks showToast(mContext.getResources().getString(R.string.initializing), Toast.LENGTH_LONG); 361f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks Thread.sleep(6000); 362f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } catch (InterruptedException e) { 363f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 364f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 365f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 366f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mWaitingForMediaScanner) { 367f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks showToast(mContext.getResources().getString(R.string.loading_new), Toast.LENGTH_LONG); 368d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mWaitingForMediaScanner = false; 369d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks if (dataSource != null) { 370d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks dataSource.loadMediaSets(feed); 371d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks } 372f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 373f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mLoading = false; 374f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 375f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks }); 376f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mAlbumSourceThread.setName("MediaSets"); 377f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mAlbumSourceThread.start(); 378f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 379f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 380f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private void showToast(final String string, final int duration) { 381f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks showToast(string, duration, false); 382f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 383f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 384f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private void showToast(final String string, final int duration, final boolean centered) { 385d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks if (mContext != null && !((Gallery) mContext).isPaused()) { 386f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ((Gallery) mContext).getHandler().post(new Runnable() { 387f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void run() { 388f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mContext != null) { 389f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks Toast toast = Toast.makeText(mContext, string, duration); 390f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (centered) { 391f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks toast.setGravity(Gravity.CENTER, 0, 0); 392f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 393f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks toast.show(); 394f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 395f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 396f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks }); 397f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 398f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 399f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 400f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void run() { 401f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks DataSource dataSource = mDataSource; 402d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks int sleepMs = 10; 403f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 404f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (dataSource != null) { 405d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks while (!Thread.interrupted()) { 406f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mListenerNeedsUpdate) { 407f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListenerNeedsUpdate = false; 408f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mListener != null) 409f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener.onFeedChanged(this, mListenerNeedsLayout); 410f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks try { 411f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks Thread.sleep(sleepMs); 412f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } catch (InterruptedException e) { 413f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return; 414f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 415f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } else { 416d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks if (mWaitingForMediaScanner) { 417d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks synchronized (mMediaSets) { 418d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaSets.clear(); 419d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks } 420d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks } 421f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks try { 422f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks Thread.sleep(sleepMs); 423f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } catch (InterruptedException e) { 424f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return; 425f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 426f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 427d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks sleepMs = 300; 428d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks if (!mMediaFeedNeedsToRun) 429d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks continue; 430d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = false; 431f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaSet> mediaSets = mMediaSets; 432f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks synchronized (mediaSets) { 433f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int expandedSetIndex = mExpandedMediaSetIndex; 434f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (expandedSetIndex >= mMediaSets.size()) { 435f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks expandedSetIndex = Shared.INVALID; 436f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 437f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (expandedSetIndex == Shared.INVALID) { 438f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // We purge the sets outside this visibleRange. 4392b04f591f758b7af03c43d90e91b939cbd515506Venkat Krishnaraj int numSets = mediaSets.size(); 440f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks IndexRange visibleRange = mVisibleRange; 441f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks IndexRange bufferedRange = mBufferedRange; 442f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks boolean scanMediaSets = true; 443f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 0; i < numSets; ++i) { 444f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (i >= visibleRange.begin && i <= visibleRange.end && scanMediaSets) { 445f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mediaSets.get(i); 446f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numItemsLoaded = set.mNumItemsLoaded; 447f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (numItemsLoaded < set.getNumExpectedItems() && numItemsLoaded < 8) { 448f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks dataSource.loadItemsForSet(this, set, numItemsLoaded, 8); 449f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (set.getNumExpectedItems() == 0) { 450f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSets.remove(set); 451f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks break; 452f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 453f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mListener != null) { 454f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener.onFeedChanged(this, false); 455f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 456f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks sleepMs = 100; 457f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks scanMediaSets = false; 458f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 459d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks if (!set.setContainsValidItems()) { 460d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mediaSets.remove(set); 461d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks if (mListener != null) { 462d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mListener.onFeedChanged(this, false); 463d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks } 464d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks break; 465d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks } 466f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 467f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 4682b04f591f758b7af03c43d90e91b939cbd515506Venkat Krishnaraj numSets = mediaSets.size(); 469f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 0; i < numSets; ++i) { 470f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mediaSets.get(i); 471f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (i >= bufferedRange.begin && i <= bufferedRange.end) { 472f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (scanMediaSets) { 473f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numItemsLoaded = set.mNumItemsLoaded; 474f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (numItemsLoaded < set.getNumExpectedItems() && numItemsLoaded < 8) { 475f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks dataSource.loadItemsForSet(this, set, numItemsLoaded, 8); 476f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (set.getNumExpectedItems() == 0) { 477f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSets.remove(set); 478f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks break; 479f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 480f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mListener != null) { 481f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener.onFeedChanged(this, false); 482f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 483f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks sleepMs = 100; 484f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks scanMediaSets = false; 485f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 486f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 487d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks } else if (i < bufferedRange.begin || i > bufferedRange.end) { 488f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // Purge this set to its initial status. 489f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = mClusterSets.get(set); 490f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clustering != null) { 491f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering.clear(); 492f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mClusterSets.remove(set); 493f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 494f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (set.getNumItems() != 0) 495f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks set.clear(); 496f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 497f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 498f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 499f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (expandedSetIndex != Shared.INVALID) { 500f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numSets = mMediaSets.size(); 501f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 0; i < numSets; ++i) { 502f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // Purge other sets. 503f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (i != expandedSetIndex) { 504f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mediaSets.get(i); 505f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = mClusterSets.get(set); 506f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clustering != null) { 507f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering.clear(); 508f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mClusterSets.remove(set); 509f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 510f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (set.getNumItems() != 0) 511f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks set.clear(); 512f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 513f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 514f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // Make sure all the items are loaded for the album. 515f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numItemsLoaded = mediaSets.get(expandedSetIndex).mNumItemsLoaded; 516f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int requestedItems = mVisibleRange.end; 517f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // requestedItems count changes in clustering mode. 518f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mInClusteringMode && mClusterSets != null) { 519f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks requestedItems = 0; 520f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = mClusterSets.get(mediaSets.get(expandedSetIndex)); 521db87908d640e17ef0946824be158d86c6e2d6836Dave Sparks if (clustering != null) { 522db87908d640e17ef0946824be158d86c6e2d6836Dave Sparks ArrayList<Cluster> clusters = clustering.getClustersForDisplay(); 523db87908d640e17ef0946824be158d86c6e2d6836Dave Sparks int numClusters = clusters.size(); 524db87908d640e17ef0946824be158d86c6e2d6836Dave Sparks for (int i = 0; i < numClusters; i++) { 525db87908d640e17ef0946824be158d86c6e2d6836Dave Sparks requestedItems += clusters.get(i).getNumExpectedItems(); 526db87908d640e17ef0946824be158d86c6e2d6836Dave Sparks } 527f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 528f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 529f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mediaSets.get(expandedSetIndex); 530f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (numItemsLoaded < set.getNumExpectedItems()) { 531f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // TODO(Venkat) Why are we doing 4th param calculations like this? 532f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks dataSource.loadItemsForSet(this, set, numItemsLoaded, (requestedItems / NUM_ITEMS_LOOKAHEAD) 533f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks * NUM_ITEMS_LOOKAHEAD + NUM_ITEMS_LOOKAHEAD); 534f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (set.getNumExpectedItems() == 0) { 535f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSets.remove(set); 536f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener.onFeedChanged(this, false); 537f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 538f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (numItemsLoaded != set.mNumItemsLoaded && mListener != null) { 539f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener.onFeedChanged(this, false); 540f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 541f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 542f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 543f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaFilter filter = mMediaFilter; 544f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (filter != null && mMediaFilteredSet == null) { 545f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (expandedSetIndex != Shared.INVALID) { 546f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mediaSets.get(expandedSetIndex); 547f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaItem> items = set.getItems(); 548f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numItems = set.getNumItems(); 549f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet filteredSet = new MediaSet(); 550f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks filteredSet.setNumExpectedItems(numItems); 551f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mMediaFilteredSet = filteredSet; 552f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 0; i < numItems; ++i) { 553f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaItem item = items.get(i); 554f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (filter.pass(item)) { 555f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks filteredSet.addItem(item); 556f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 557f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 558f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks filteredSet.updateNumExpectedItems(); 559f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks filteredSet.generateTitle(true); 560f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 561f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks updateListener(true); 562f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 563f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 564f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 565f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 566f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 567f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 568f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void expandMediaSet(int mediaSetIndex) { 569f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // We need to check if this slot can be focused or not. 570f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mListener != null) { 571f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener.onFeedAboutToChange(this); 572f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 573f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mExpandedMediaSetIndex > 0 && mediaSetIndex == Shared.INVALID) { 574f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // We are collapsing a previously expanded media set 575f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mediaSetIndex < mMediaSets.size() && mExpandedMediaSetIndex >= 0) { 576f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mMediaSets.get(mExpandedMediaSetIndex); 577f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (set.getNumItems() == 0) { 578f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks set.clear(); 579f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 580f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 581f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 582f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mExpandedMediaSetIndex = mediaSetIndex; 583f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mediaSetIndex < mMediaSets.size() && mediaSetIndex >= 0) { 584f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // Notify Picasa that the user entered the album. 585f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // MediaSet set = mMediaSets.get(mediaSetIndex); 586f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // PicasaService.requestSync(mContext, PicasaService.TYPE_ALBUM_PHOTOS, set.mPicasaAlbumId); 587f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 588f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks updateListener(true); 589d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 590f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 591f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 592f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public boolean canExpandSet(int slotIndex) { 593f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int mediaSetIndex = slotIndex; 594f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mediaSetIndex < mMediaSets.size() && mediaSetIndex >= 0) { 595f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mMediaSets.get(mediaSetIndex); 596f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (set.getNumItems() > 0) { 597f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaItem item = set.getItems().get(0); 598f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (item.mId == Shared.INVALID) { 599f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return false; 600f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 601f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return true; 602f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 603f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 604f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return false; 605f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 606f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 607f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public boolean hasExpandedMediaSet() { 608f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return (mExpandedMediaSetIndex != Shared.INVALID); 609f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 610f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 611f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public boolean restorePreviousClusteringState() { 612f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks boolean retVal = disableClusteringIfNecessary(); 613f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (retVal) { 614f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mListener != null) { 615f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener.onFeedAboutToChange(this); 616f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 617f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks updateListener(true); 618d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 619f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 620f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return retVal; 621f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 622f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 623f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private boolean disableClusteringIfNecessary() { 624f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mInClusteringMode) { 625f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // Disable clustering. 626f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mInClusteringMode = false; 627d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 628f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return true; 629f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 630f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return false; 631f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 632f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 633f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public boolean isClustered() { 634f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mInClusteringMode; 635f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 636f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 637f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public MediaSet getCurrentSet() { 638f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mExpandedMediaSetIndex != Shared.INVALID && mExpandedMediaSetIndex < mMediaSets.size()) { 639f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mMediaSets.get(mExpandedMediaSetIndex); 640f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 641f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 642f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 643f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 644f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void performClustering() { 645f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mListener != null) { 646f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener.onFeedAboutToChange(this); 647f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 648f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet setToUse = null; 649f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mExpandedMediaSetIndex != Shared.INVALID || mExpandedMediaSetIndex < mMediaSets.size()) { 650f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks setToUse = mMediaSets.get(mExpandedMediaSetIndex); 651f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 652f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (setToUse != null) { 653f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = null; 654d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks synchronized (mClusterSets) { 655f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // Make sure the computation is completed to the end. 656f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering = mClusterSets.get(setToUse); 657f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clustering != null) { 658f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering.compute(null, true); 659f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } else { 660f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return; 661f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 662f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 663f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mInClusteringMode = true; 664d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 665f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks updateListener(true); 666f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 667f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 668f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 669f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void moveSetToFront(MediaSet mediaSet) { 670f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaSet> mediaSets = mMediaSets; 671f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numSets = mediaSets.size(); 672f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (numSets == 0) { 673f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSets.add(mediaSet); 674f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return; 675f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 676f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet setToFind = mediaSets.get(0); 677f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (setToFind == mediaSet) { 678f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return; 679f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 680f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSets.set(0, mediaSet); 681f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int indexToSwapTill = -1; 682f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 1; i < numSets; ++i) { 683f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mediaSets.get(i); 684f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (set == mediaSet) { 685f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSets.set(i, setToFind); 686f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks indexToSwapTill = i; 687f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks break; 688f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 689f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 690f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (indexToSwapTill != Shared.INVALID) { 691f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = indexToSwapTill; i > 1; --i) { 692f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet setEnd = mediaSets.get(i); 693f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet setPrev = mediaSets.get(i - 1); 694f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSets.set(i, setPrev); 695f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSets.set(i - 1, setEnd); 696f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 697f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 698d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 699f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 700f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 701f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public MediaSet replaceMediaSet(long setId, DataSource dataSource) { 702f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet mediaSet = new MediaSet(dataSource); 703f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSet.mId = setId; 704f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaSet> mediaSets = mMediaSets; 705f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numSets = mediaSets.size(); 706f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 0; i < numSets; ++i) { 707053a906072e581a9bd381003ceefdf14636a7c1dVenkat Krishnaraj final MediaSet thisSet = mediaSets.get(i); 708053a906072e581a9bd381003ceefdf14636a7c1dVenkat Krishnaraj if (thisSet.mId == setId) { 709f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSet.mName = thisSet.mName; 710053a906072e581a9bd381003ceefdf14636a7c1dVenkat Krishnaraj mediaSet.mHasImages = thisSet.mHasImages; 711053a906072e581a9bd381003ceefdf14636a7c1dVenkat Krishnaraj mediaSet.mHasVideos = thisSet.mHasVideos; 712f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSets.set(i, mediaSet); 713f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks break; 714f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 715f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 716d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 717f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mediaSet; 718f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 719d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks 720f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void setSingleImageMode(boolean singleImageMode) { 721f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mSingleImageMode = singleImageMode; 722f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 723f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 724f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public boolean isSingleImageMode() { 725f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mSingleImageMode; 726f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 727f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 728f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public MediaSet getExpandedMediaSet() { 729f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mExpandedMediaSetIndex == Shared.INVALID) 730f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 731f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mExpandedMediaSetIndex >= mMediaSets.size()) 732f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 733f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mMediaSets.get(mExpandedMediaSetIndex); 734f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 735f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks} 736