MediaFeed.java revision 7cde3b179f4d12f53c2a1db1e4f903bd06b7011e
1f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparkspackage com.cooliris.media; 2f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 3f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport java.util.ArrayList; 4f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport java.util.HashMap; 5897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnarajimport java.util.HashSet; 61b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkatimport java.util.Set; 7f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 8897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnarajimport android.content.ContentResolver; 9f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.content.Context; 10897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnarajimport android.database.ContentObserver; 111c729acdafe147abda6b3479eafb17607f172780Venkatimport android.util.Log; 12f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.view.Gravity; 13f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.widget.Toast; 14897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnarajimport android.net.Uri; 15897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnarajimport android.os.Handler; 16f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.os.Process; 17f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 18d93f177bf2bc26f4ad64ca2f7725da8b0347a77fVenkatimport com.cooliris.app.App; 1929dcedb79b7eb9e3d65adc5d2ea95c1dd5c01df9Chih-Chung Changimport com.cooliris.app.Res; 20f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport com.cooliris.media.MediaClustering.Cluster; 21f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 22f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparkspublic final class MediaFeed implements Runnable { 231c729acdafe147abda6b3479eafb17607f172780Venkat private final String TAG = "MediaFeed"; 24f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public static final int OPERATION_DELETE = 0; 25f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public static final int OPERATION_ROTATE = 1; 26f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public static final int OPERATION_CROP = 2; 27f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 28f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private static final int NUM_ITEMS_LOOKAHEAD = 60; 29f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 30f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private IndexRange mVisibleRange = new IndexRange(); 31f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private IndexRange mBufferedRange = new IndexRange(); 32f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private ArrayList<MediaSet> mMediaSets = new ArrayList<MediaSet>(); 33f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private Listener mListener; 34f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private DataSource mDataSource; 35f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private boolean mListenerNeedsUpdate = false; 36d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks private boolean mMediaFeedNeedsToRun = false; 37f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private MediaSet mSingleWrapper = new MediaSet(); 38f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private boolean mInClusteringMode = false; 39f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private HashMap<MediaSet, MediaClustering> mClusterSets = new HashMap<MediaSet, MediaClustering>(32); 40f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private int mExpandedMediaSetIndex = Shared.INVALID; 41f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private MediaFilter mMediaFilter; 42f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private MediaSet mMediaFilteredSet; 43f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private Context mContext; 44f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private Thread mDataSourceThread = null; 45f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private Thread mAlbumSourceThread = null; 46f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private boolean mListenerNeedsLayout; 47f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private boolean mWaitingForMediaScanner; 48f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private boolean mSingleImageMode; 49f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private boolean mLoading; 50897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj private HashMap<String, ContentObserver> mContentObservers = new HashMap<String, ContentObserver>(); 5162dd11281ef6e12049dd6798b184157e9583d7d4Venkat private ArrayList<String[]> mRequestedRefresh = new ArrayList<String[]>(); 52f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 53f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public interface Listener { 54f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public abstract void onFeedAboutToChange(MediaFeed feed); 5562dd11281ef6e12049dd6798b184157e9583d7d4Venkat 56f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public abstract void onFeedChanged(MediaFeed feed, boolean needsLayout); 57f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 58f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 59f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public MediaFeed(Context context, DataSource dataSource, Listener listener) { 60f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mContext = context; 61f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener = listener; 62f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mDataSource = dataSource; 63f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mSingleWrapper.setNumExpectedItems(1); 64f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mLoading = true; 65f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 66d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks 67f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void shutdown() { 68f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mDataSourceThread != null) { 69f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mDataSource.shutdown(); 70f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mDataSourceThread.interrupt(); 71eafbb1d497c67b916493da66e86f9f86656c17c8Wei-Ta Chen try { 72eafbb1d497c67b916493da66e86f9f86656c17c8Wei-Ta Chen mDataSourceThread.join(); 73eafbb1d497c67b916493da66e86f9f86656c17c8Wei-Ta Chen } catch (InterruptedException e) { 74eafbb1d497c67b916493da66e86f9f86656c17c8Wei-Ta Chen Log.w(TAG, "Cannot stop data source thread.", e); 75eafbb1d497c67b916493da66e86f9f86656c17c8Wei-Ta Chen } 76f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mDataSourceThread = null; 77f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 78f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mAlbumSourceThread != null) { 79f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mAlbumSourceThread.interrupt(); 80eafbb1d497c67b916493da66e86f9f86656c17c8Wei-Ta Chen try { 81eafbb1d497c67b916493da66e86f9f86656c17c8Wei-Ta Chen mAlbumSourceThread.join(); 82eafbb1d497c67b916493da66e86f9f86656c17c8Wei-Ta Chen } catch (InterruptedException e) { 83eafbb1d497c67b916493da66e86f9f86656c17c8Wei-Ta Chen Log.w(TAG, "Cannot stop album source thread.", e); 84eafbb1d497c67b916493da66e86f9f86656c17c8Wei-Ta Chen } 85f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mAlbumSourceThread = null; 86f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 87f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numSets = mMediaSets.size(); 88f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 0; i < numSets; ++i) { 89f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mMediaSets.get(i); 90f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks set.clear(); 91f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 92f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks synchronized (mMediaSets) { 93f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mMediaSets.clear(); 94f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 95f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numClusters = mClusterSets.size(); 96f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 0; i < numClusters; ++i) { 97f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering mc = mClusterSets.get(i); 98f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mc != null) { 99f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mc.clear(); 100f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 101f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 102f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mClusterSets.clear(); 103f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener = null; 104f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mDataSource = null; 105f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mSingleWrapper = null; 106f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 107f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 108f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void setVisibleRange(int begin, int end) { 109d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks if (begin != mVisibleRange.begin || end != mVisibleRange.end) { 110d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mVisibleRange.begin = begin; 111d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mVisibleRange.end = end; 112d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks int numItems = 96; 113d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks int numItemsBy2 = numItems / 2; 114d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks int numItemsBy4 = numItems / 4; 115d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mBufferedRange.begin = (begin / numItemsBy2) * numItemsBy2 - numItemsBy4; 116d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mBufferedRange.end = mBufferedRange.begin + numItems; 117d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 118d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks } 119f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 120f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 121f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void setFilter(MediaFilter filter) { 122f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mMediaFilter = filter; 123f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mMediaFilteredSet = null; 124f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mListener != null) { 125f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener.onFeedAboutToChange(this); 126f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 127d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 128f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 129f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 130f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void removeFilter() { 131f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mMediaFilter = null; 132f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mMediaFilteredSet = null; 133f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mListener != null) { 134f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener.onFeedAboutToChange(this); 135f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks updateListener(true); 136f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 137d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 138f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 139f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 140f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public ArrayList<MediaSet> getMediaSets() { 141f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mMediaSets; 142f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 143f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 144d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks public MediaSet getMediaSet(final long setId) { 145f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (setId != Shared.INVALID) { 146d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks try { 147d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks int mMediaSetsSize = mMediaSets.size(); 148d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks for (int i = 0; i < mMediaSetsSize; i++) { 1491b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj final MediaSet set = mMediaSets.get(i); 1501b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj if (set.mId == setId) { 1511b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj set.mFlagForDelete = false; 1521b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj return set; 153d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks } 154f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 155d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks } catch (Exception e) { 156d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks return null; 157f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 158f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 159f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 160f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 161f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 162f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public MediaSet getFilteredSet() { 163f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mMediaFilteredSet; 164f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 165f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 166f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public MediaSet addMediaSet(final long setId, DataSource dataSource) { 167f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet mediaSet = new MediaSet(dataSource); 168f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSet.mId = setId; 169f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mMediaSets.add(mediaSet); 170d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks if (mDataSourceThread != null && !mDataSourceThread.isAlive()) { 171d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mDataSourceThread.start(); 172d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks } 173d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 174f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mediaSet; 175f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 176f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 177f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public DataSource getDataSource() { 178f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mDataSource; 179f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 180f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 181f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public MediaClustering getClustering() { 182f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mExpandedMediaSetIndex != Shared.INVALID && mExpandedMediaSetIndex < mMediaSets.size()) { 183f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mClusterSets.get(mMediaSets.get(mExpandedMediaSetIndex)); 184f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 185f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 186f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 187f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 188f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public ArrayList<Cluster> getClustersForSet(final MediaSet set) { 189f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<Cluster> clusters = null; 190f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mClusterSets != null && mClusterSets.containsKey(set)) { 191f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering mediaClustering = mClusterSets.get(set); 192f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mediaClustering != null) { 193f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clusters = mediaClustering.getClusters(); 194f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 195f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 196f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return clusters; 197f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 198f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 199f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void addItemToMediaSet(MediaItem item, MediaSet mediaSet) { 200f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks item.mParentMediaSet = mediaSet; 201f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSet.addItem(item); 202d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks synchronized (mClusterSets) { 203f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (item.mClusteringState == MediaItem.NOT_CLUSTERED) { 204f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = mClusterSets.get(mediaSet); 205f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clustering == null) { 206f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering = new MediaClustering(mediaSet.isPicassaAlbum()); 207f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mClusterSets.put(mediaSet, clustering); 208f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 209f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering.setTimeRange(mediaSet.mMaxTimestamp - mediaSet.mMinTimestamp, mediaSet.getNumExpectedItems()); 210f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering.addItemForClustering(item); 211f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks item.mClusteringState = MediaItem.CLUSTERED; 212f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 213f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 214d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 215f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 216f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 217f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void performOperation(final int operation, final ArrayList<MediaBucket> mediaBuckets, final Object data) { 218f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numBuckets = mediaBuckets.size(); 219f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks final ArrayList<MediaBucket> copyMediaBuckets = new ArrayList<MediaBucket>(numBuckets); 220f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 0; i < numBuckets; ++i) { 221f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks copyMediaBuckets.add(mediaBuckets.get(i)); 222f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 223f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (operation == OPERATION_DELETE && mListener != null) { 224f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener.onFeedAboutToChange(this); 225f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 226f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks Thread operationThread = new Thread(new Runnable() { 227f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void run() { 228f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaBucket> mediaBuckets = copyMediaBuckets; 229f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (operation == OPERATION_DELETE) { 230f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numBuckets = mediaBuckets.size(); 231f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 0; i < numBuckets; ++i) { 232f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaBucket bucket = mediaBuckets.get(i); 233f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = bucket.mediaSet; 234f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaItem> items = bucket.mediaItems; 235f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (set != null && items == null) { 236f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // Remove the entire bucket. 237f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks removeMediaSet(set); 238f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } else if (set != null && items != null) { 239f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // We need to remove these items from the set. 240f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numItems = items.size(); 2411bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks // We also need to delete the items from the 2421bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks // cluster. 243f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = mClusterSets.get(set); 244f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int j = 0; j < numItems; ++j) { 245f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaItem item = items.get(j); 246f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks removeItemFromMediaSet(item, set); 247f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clustering != null) { 248f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering.removeItemFromClustering(item); 249f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 250f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 251f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks set.updateNumExpectedItems(); 252f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks set.generateTitle(true); 253f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 254f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 255f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks updateListener(true); 256d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 257f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mDataSource != null) { 258f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mDataSource.performOperation(OPERATION_DELETE, mediaBuckets, null); 259f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 260f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } else { 261f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mDataSource.performOperation(operation, mediaBuckets, data); 262f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 263f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 264f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks }); 265f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks operationThread.setName("Operation " + operation); 266f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks operationThread.start(); 267f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 268f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 269f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void removeMediaSet(MediaSet set) { 2702b04f591f758b7af03c43d90e91b939cbd515506Venkat Krishnaraj synchronized (mMediaSets) { 2711bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks mMediaSets.remove(set); 2722b04f591f758b7af03c43d90e91b939cbd515506Venkat Krishnaraj } 273d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 274f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 275f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 276f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private void removeItemFromMediaSet(MediaItem item, MediaSet mediaSet) { 277f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSet.removeItem(item); 278d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks synchronized (mClusterSets) { 279f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = mClusterSets.get(mediaSet); 280f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clustering != null) { 281f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering.removeItemFromClustering(item); 282f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 283f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 284d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 285f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 286f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 287f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void updateListener(boolean needsLayout) { 288f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListenerNeedsUpdate = true; 289f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListenerNeedsLayout = needsLayout; 290f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 291f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 292f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public int getNumSlots() { 293f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int currentMediaSetIndex = mExpandedMediaSetIndex; 294f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaSet> mediaSets = mMediaSets; 295f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int mediaSetsSize = mediaSets.size(); 296f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 297f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mInClusteringMode == false) { 298f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (currentMediaSetIndex == Shared.INVALID || currentMediaSetIndex >= mediaSetsSize) { 299f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mediaSetsSize; 300f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } else { 301f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet setToUse = (mMediaFilteredSet == null) ? mediaSets.get(currentMediaSetIndex) : mMediaFilteredSet; 3025e0474e8e1942c41234eb251f948c2fbb7445b02Venkat Krishnaraj return setToUse.getNumExpectedItems(); 303f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 304f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } else if (currentMediaSetIndex != Shared.INVALID && currentMediaSetIndex < mediaSetsSize) { 305f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mediaSets.get(currentMediaSetIndex); 306f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = mClusterSets.get(set); 307f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clustering != null) { 308f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return clustering.getClustersForDisplay().size(); 309f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 310f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 311f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return 0; 312f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 31362dd11281ef6e12049dd6798b184157e9583d7d4Venkat 3147cde3b179f4d12f53c2a1db1e4f903bd06b7011eWei-Ta Chen public void copySlotStateFrom(MediaFeed another) { 3157cde3b179f4d12f53c2a1db1e4f903bd06b7011eWei-Ta Chen mExpandedMediaSetIndex = another.mExpandedMediaSetIndex; 3167cde3b179f4d12f53c2a1db1e4f903bd06b7011eWei-Ta Chen mInClusteringMode = another.mInClusteringMode; 3177cde3b179f4d12f53c2a1db1e4f903bd06b7011eWei-Ta Chen } 3187cde3b179f4d12f53c2a1db1e4f903bd06b7011eWei-Ta Chen 31988dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat public ArrayList<Integer> getBreaks() { 32088dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat if (true) 32188dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat return null; 32288dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat int currentMediaSetIndex = mExpandedMediaSetIndex; 32388dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat ArrayList<MediaSet> mediaSets = mMediaSets; 32488dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat int mediaSetsSize = mediaSets.size(); 32588dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat if (currentMediaSetIndex == Shared.INVALID || currentMediaSetIndex >= mediaSetsSize) 32688dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat return null; 32788dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat MediaSet set = mediaSets.get(currentMediaSetIndex); 32888dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat MediaClustering clustering = mClusterSets.get(set); 32988dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat if (clustering != null) { 33088dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat clustering.compute(null, true); 33188dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat final ArrayList<Cluster> clusters = clustering.getClustersForDisplay(); 33288dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat int numClusters = clusters.size(); 33388dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat final ArrayList<Integer> retVal = new ArrayList<Integer>(numClusters); 33488dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat int size = 0; 33588dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat for (int i = 0; i < numClusters; ++i) { 33688dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat size += clusters.get(i).getItems().size(); 33788dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat retVal.add(size); 33888dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat } 33988dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat return retVal; 34088dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat } else { 34188dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat return null; 34288dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat } 34388dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat } 344f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 345f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public MediaSet getSetForSlot(int slotIndex) { 346f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (slotIndex < 0) { 347f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 348f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 349f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 350f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaSet> mediaSets = mMediaSets; 351f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int mediaSetsSize = mediaSets.size(); 352f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int currentMediaSetIndex = mExpandedMediaSetIndex; 353f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 354f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mInClusteringMode == false) { 355f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (currentMediaSetIndex == Shared.INVALID || currentMediaSetIndex >= mediaSetsSize) { 356f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (slotIndex >= mediaSetsSize) { 357f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 358f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 359f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mMediaSets.get(slotIndex); 360f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 361f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mSingleWrapper.getNumItems() == 0) { 362f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mSingleWrapper.addItem(null); 363f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 364f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet setToUse = (mMediaFilteredSet == null) ? mMediaSets.get(currentMediaSetIndex) : mMediaFilteredSet; 365f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaItem> items = setToUse.getItems(); 366f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (slotIndex >= setToUse.getNumItems()) { 367f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 368f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 369f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mSingleWrapper.getItems().set(0, items.get(slotIndex)); 370f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mSingleWrapper; 371f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } else if (currentMediaSetIndex != Shared.INVALID && currentMediaSetIndex < mediaSetsSize) { 372f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mediaSets.get(currentMediaSetIndex); 373f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = mClusterSets.get(set); 374f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clustering != null) { 375f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaClustering.Cluster> clusters = clustering.getClustersForDisplay(); 376f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clusters.size() > slotIndex) { 377f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering.Cluster cluster = clusters.get(slotIndex); 378f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks cluster.generateCaption(mContext); 379f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return cluster; 380f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 381f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 382f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 383f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 384f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 385f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 386f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public boolean getWaitingForMediaScanner() { 387f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mWaitingForMediaScanner; 388f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 389d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks 390f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public boolean isLoading() { 391f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mLoading; 392f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 393f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 394f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void start() { 395f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks final MediaFeed feed = this; 39662f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat onResume(); 397f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mLoading = true; 398d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mDataSourceThread = new Thread(this); 399d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mDataSourceThread.setName("MediaFeed"); 400f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mAlbumSourceThread = new Thread(new Runnable() { 401f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void run() { 402f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mContext == null) 403f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return; 404f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 405f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks DataSource dataSource = mDataSource; 4061bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks // We must wait while the SD card is mounted or the MediaScanner 4071bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks // is running. 408d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks if (dataSource != null) { 4091b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj loadMediaSets(); 410d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks } 411f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mWaitingForMediaScanner = false; 412f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks while (ImageManager.isMediaScannerScanning(mContext.getContentResolver())) { 413f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // MediaScanner is still running, wait 41488ed7e72a2a0bfdbef7f72aea2b2ddfd74961bdbVenkat Krishnaraj if (Thread.interrupted()) 41588ed7e72a2a0bfdbef7f72aea2b2ddfd74961bdbVenkat Krishnaraj return; 416f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mWaitingForMediaScanner = true; 417f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks try { 418f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mContext == null) 419f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return; 42029dcedb79b7eb9e3d65adc5d2ea95c1dd5c01df9Chih-Chung Chang showToast(mContext.getResources().getString(Res.string.initializing), Toast.LENGTH_LONG); 4211b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj if (dataSource != null) { 4221b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj loadMediaSets(); 4231b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj } 4241b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj Thread.sleep(10000); 425f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } catch (InterruptedException e) { 42688ed7e72a2a0bfdbef7f72aea2b2ddfd74961bdbVenkat Krishnaraj return; 427f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 428f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 429f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mWaitingForMediaScanner) { 43029dcedb79b7eb9e3d65adc5d2ea95c1dd5c01df9Chih-Chung Chang showToast(mContext.getResources().getString(Res.string.loading_new), Toast.LENGTH_LONG); 431d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mWaitingForMediaScanner = false; 4321b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj loadMediaSets(); 433f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 434f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mLoading = false; 435f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 436f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks }); 437f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mAlbumSourceThread.setName("MediaSets"); 438f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mAlbumSourceThread.start(); 439f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 440897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj 4411b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj private void loadMediaSets() { 4421b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj if (mDataSource == null) 4431b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj return; 4441b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj final ArrayList<MediaSet> sets = mMediaSets; 44562f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat synchronized (sets) { 44680182dccb216689e392da1c749f32f6c0cda6f42Venkat final int numSets = sets.size(); 44780182dccb216689e392da1c749f32f6c0cda6f42Venkat for (int i = 0; i < numSets; ++i) { 44880182dccb216689e392da1c749f32f6c0cda6f42Venkat final MediaSet set = sets.get(i); 44980182dccb216689e392da1c749f32f6c0cda6f42Venkat set.mFlagForDelete = true; 45080182dccb216689e392da1c749f32f6c0cda6f42Venkat } 45162f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat mDataSource.refresh(MediaFeed.this, mDataSource.getDatabaseUris()); 45262f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat mDataSource.loadMediaSets(MediaFeed.this); 45380182dccb216689e392da1c749f32f6c0cda6f42Venkat final ArrayList<MediaSet> setsToRemove = new ArrayList<MediaSet>(); 45480182dccb216689e392da1c749f32f6c0cda6f42Venkat for (int i = 0; i < numSets; ++i) { 45580182dccb216689e392da1c749f32f6c0cda6f42Venkat final MediaSet set = sets.get(i); 45680182dccb216689e392da1c749f32f6c0cda6f42Venkat if (set.mFlagForDelete) { 45780182dccb216689e392da1c749f32f6c0cda6f42Venkat setsToRemove.add(set); 45880182dccb216689e392da1c749f32f6c0cda6f42Venkat } 4591b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj } 46080182dccb216689e392da1c749f32f6c0cda6f42Venkat int numSetsToRemove = setsToRemove.size(); 46180182dccb216689e392da1c749f32f6c0cda6f42Venkat for (int i = 0; i < numSetsToRemove; ++i) { 46280182dccb216689e392da1c749f32f6c0cda6f42Venkat sets.remove(setsToRemove.get(i)); 46380182dccb216689e392da1c749f32f6c0cda6f42Venkat } 46480182dccb216689e392da1c749f32f6c0cda6f42Venkat setsToRemove.clear(); 4651b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj } 46680182dccb216689e392da1c749f32f6c0cda6f42Venkat mMediaFeedNeedsToRun = true; 4671b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj updateListener(false); 4681b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj } 469f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 470f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private void showToast(final String string, final int duration) { 471f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks showToast(string, duration, false); 472f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 473f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 474f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private void showToast(final String string, final int duration, final boolean centered) { 475d93f177bf2bc26f4ad64ca2f7725da8b0347a77fVenkat if (mContext != null && !App.get(mContext).isPaused()) { 47662f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat App.get(mContext).getHandler().post(new Runnable() { 477f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void run() { 478f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mContext != null) { 479f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks Toast toast = Toast.makeText(mContext, string, duration); 480f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (centered) { 481f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks toast.setGravity(Gravity.CENTER, 0, 0); 482f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 483f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks toast.show(); 484f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 485f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 486f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks }); 487f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 488f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 489f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 490f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void run() { 491f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks DataSource dataSource = mDataSource; 492d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks int sleepMs = 10; 493f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 494f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (dataSource != null) { 495d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks while (!Thread.interrupted()) { 49662dd11281ef6e12049dd6798b184157e9583d7d4Venkat String[] databaseUris = null; 49762dd11281ef6e12049dd6798b184157e9583d7d4Venkat boolean performRefresh = false; 49862dd11281ef6e12049dd6798b184157e9583d7d4Venkat synchronized (mRequestedRefresh) { 49962dd11281ef6e12049dd6798b184157e9583d7d4Venkat if (mRequestedRefresh.size() > 0) { 50062dd11281ef6e12049dd6798b184157e9583d7d4Venkat // We prune this first. 50162dd11281ef6e12049dd6798b184157e9583d7d4Venkat int numRequests = mRequestedRefresh.size(); 50262dd11281ef6e12049dd6798b184157e9583d7d4Venkat for (int i = 0; i < numRequests; ++i) { 50362dd11281ef6e12049dd6798b184157e9583d7d4Venkat databaseUris = ArrayUtils.addAll(databaseUris, mRequestedRefresh.get(i)); 50462dd11281ef6e12049dd6798b184157e9583d7d4Venkat } 50562dd11281ef6e12049dd6798b184157e9583d7d4Venkat mRequestedRefresh.clear(); 50662dd11281ef6e12049dd6798b184157e9583d7d4Venkat performRefresh = true; 50762dd11281ef6e12049dd6798b184157e9583d7d4Venkat // We need to eliminate duplicate uris in this array 50862dd11281ef6e12049dd6798b184157e9583d7d4Venkat final HashMap<String, String> uris = new HashMap<String, String>(); 50962dd11281ef6e12049dd6798b184157e9583d7d4Venkat if (databaseUris != null) { 51062dd11281ef6e12049dd6798b184157e9583d7d4Venkat int numUris = databaseUris.length; 51162dd11281ef6e12049dd6798b184157e9583d7d4Venkat for (int i = 0; i < numUris; ++i) { 51262dd11281ef6e12049dd6798b184157e9583d7d4Venkat final String uri = databaseUris[i]; 51362dd11281ef6e12049dd6798b184157e9583d7d4Venkat if (uri != null) 51462dd11281ef6e12049dd6798b184157e9583d7d4Venkat uris.put(uri, uri); 51562dd11281ef6e12049dd6798b184157e9583d7d4Venkat } 51662dd11281ef6e12049dd6798b184157e9583d7d4Venkat } 51762dd11281ef6e12049dd6798b184157e9583d7d4Venkat databaseUris = new String[0]; 51862dd11281ef6e12049dd6798b184157e9583d7d4Venkat databaseUris = (String[]) uris.keySet().toArray(databaseUris); 51962dd11281ef6e12049dd6798b184157e9583d7d4Venkat } 52062dd11281ef6e12049dd6798b184157e9583d7d4Venkat } 521b832709e16e0d018447f3d20755d3c22d09e2ba0Venkat boolean settingFeedAboutToChange = false; 52262dd11281ef6e12049dd6798b184157e9583d7d4Venkat if (performRefresh) { 5231c729acdafe147abda6b3479eafb17607f172780Venkat if (dataSource != null) { 524b832709e16e0d018447f3d20755d3c22d09e2ba0Venkat if (mListener != null) { 525b832709e16e0d018447f3d20755d3c22d09e2ba0Venkat settingFeedAboutToChange = true; 526b832709e16e0d018447f3d20755d3c22d09e2ba0Venkat mListener.onFeedAboutToChange(this); 527b832709e16e0d018447f3d20755d3c22d09e2ba0Venkat } 52862dd11281ef6e12049dd6798b184157e9583d7d4Venkat dataSource.refresh(this, databaseUris); 52971660902f0aa83113bf11a2933e92b08c524fed5Venkat mMediaFeedNeedsToRun = true; 5301c729acdafe147abda6b3479eafb17607f172780Venkat } 5311c729acdafe147abda6b3479eafb17607f172780Venkat } 5321c729acdafe147abda6b3479eafb17607f172780Venkat if (mListenerNeedsUpdate && !mMediaFeedNeedsToRun) { 533f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListenerNeedsUpdate = false; 534f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mListener != null) 53546afd9b71156248a494ea618c37b5a373fd8e386Venkat synchronized (mMediaSets) { 53646afd9b71156248a494ea618c37b5a373fd8e386Venkat mListener.onFeedChanged(this, mListenerNeedsLayout); 53746afd9b71156248a494ea618c37b5a373fd8e386Venkat } 538f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks try { 539f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks Thread.sleep(sleepMs); 540f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } catch (InterruptedException e) { 541f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return; 542f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 543f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } else { 544f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks try { 545f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks Thread.sleep(sleepMs); 546f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } catch (InterruptedException e) { 547f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return; 548f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 549f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 550d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks sleepMs = 300; 551d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks if (!mMediaFeedNeedsToRun) 552d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks continue; 553d93f177bf2bc26f4ad64ca2f7725da8b0347a77fVenkat App app = App.get(mContext); 55462f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat if (app == null || app.isPaused()) 55562f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat continue; 556b832709e16e0d018447f3d20755d3c22d09e2ba0Venkat if (settingFeedAboutToChange) { 557b832709e16e0d018447f3d20755d3c22d09e2ba0Venkat updateListener(true); 558b832709e16e0d018447f3d20755d3c22d09e2ba0Venkat } 559d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = false; 560f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaSet> mediaSets = mMediaSets; 561f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks synchronized (mediaSets) { 562f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int expandedSetIndex = mExpandedMediaSetIndex; 563f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (expandedSetIndex >= mMediaSets.size()) { 564f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks expandedSetIndex = Shared.INVALID; 565f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 566f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (expandedSetIndex == Shared.INVALID) { 567f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // We purge the sets outside this visibleRange. 5682b04f591f758b7af03c43d90e91b939cbd515506Venkat Krishnaraj int numSets = mediaSets.size(); 569f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks IndexRange visibleRange = mVisibleRange; 570f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks IndexRange bufferedRange = mBufferedRange; 571f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks boolean scanMediaSets = true; 572f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 0; i < numSets; ++i) { 573f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (i >= visibleRange.begin && i <= visibleRange.end && scanMediaSets) { 574f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mediaSets.get(i); 575f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numItemsLoaded = set.mNumItemsLoaded; 576f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (numItemsLoaded < set.getNumExpectedItems() && numItemsLoaded < 8) { 57762f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat synchronized (set) { 57862f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat dataSource.loadItemsForSet(this, set, numItemsLoaded, 8); 579eb50ae54adfb694b1a424e7a36eed99dc0be1620Venkat set.checkForDeletedItems(); 58062f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat } 581f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (set.getNumExpectedItems() == 0) { 582f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSets.remove(set); 583f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks break; 584f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 585f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mListener != null) { 5861c729acdafe147abda6b3479eafb17607f172780Venkat mListenerNeedsUpdate = false; 5871c729acdafe147abda6b3479eafb17607f172780Venkat mListener.onFeedChanged(this, mListenerNeedsLayout); 5881c729acdafe147abda6b3479eafb17607f172780Venkat mListenerNeedsLayout = false; 589f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 590f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks sleepMs = 100; 591f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks scanMediaSets = false; 592f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 593d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks if (!set.setContainsValidItems()) { 594d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mediaSets.remove(set); 595d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks if (mListener != null) { 5961c729acdafe147abda6b3479eafb17607f172780Venkat mListenerNeedsUpdate = false; 5971c729acdafe147abda6b3479eafb17607f172780Venkat mListener.onFeedChanged(this, mListenerNeedsLayout); 5981c729acdafe147abda6b3479eafb17607f172780Venkat mListenerNeedsLayout = false; 599d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks } 600d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks break; 601d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks } 602f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 603f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 6042b04f591f758b7af03c43d90e91b939cbd515506Venkat Krishnaraj numSets = mediaSets.size(); 605f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 0; i < numSets; ++i) { 606f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mediaSets.get(i); 607f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (i >= bufferedRange.begin && i <= bufferedRange.end) { 608f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (scanMediaSets) { 609f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numItemsLoaded = set.mNumItemsLoaded; 610f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (numItemsLoaded < set.getNumExpectedItems() && numItemsLoaded < 8) { 61162f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat synchronized (set) { 61262f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat dataSource.loadItemsForSet(this, set, numItemsLoaded, 8); 613eb50ae54adfb694b1a424e7a36eed99dc0be1620Venkat set.checkForDeletedItems(); 61462f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat } 615f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (set.getNumExpectedItems() == 0) { 616f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSets.remove(set); 617f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks break; 618f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 619f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mListener != null) { 6201c729acdafe147abda6b3479eafb17607f172780Venkat mListenerNeedsUpdate = false; 6211c729acdafe147abda6b3479eafb17607f172780Venkat mListener.onFeedChanged(this, mListenerNeedsLayout); 6221c729acdafe147abda6b3479eafb17607f172780Venkat mListenerNeedsLayout = false; 623f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 624f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks sleepMs = 100; 625f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks scanMediaSets = false; 626f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 627f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 628897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj } else if (!mListenerNeedsUpdate && (i < bufferedRange.begin || i > bufferedRange.end)) { 629f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // Purge this set to its initial status. 630f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = mClusterSets.get(set); 631f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clustering != null) { 632f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering.clear(); 633f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mClusterSets.remove(set); 634f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 635f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (set.getNumItems() != 0) 636f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks set.clear(); 637f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 638f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 639f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 640f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (expandedSetIndex != Shared.INVALID) { 641f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numSets = mMediaSets.size(); 642f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 0; i < numSets; ++i) { 643f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // Purge other sets. 644f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (i != expandedSetIndex) { 645f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mediaSets.get(i); 646f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = mClusterSets.get(set); 647f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clustering != null) { 648f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering.clear(); 649f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mClusterSets.remove(set); 650f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 651897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj if (set.mNumItemsLoaded != 0) 652f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks set.clear(); 653f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 654f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 655f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // Make sure all the items are loaded for the album. 656f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numItemsLoaded = mediaSets.get(expandedSetIndex).mNumItemsLoaded; 657f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int requestedItems = mVisibleRange.end; 658f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // requestedItems count changes in clustering mode. 659f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mInClusteringMode && mClusterSets != null) { 660f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks requestedItems = 0; 661f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = mClusterSets.get(mediaSets.get(expandedSetIndex)); 662db87908d640e17ef0946824be158d86c6e2d6836Dave Sparks if (clustering != null) { 663db87908d640e17ef0946824be158d86c6e2d6836Dave Sparks ArrayList<Cluster> clusters = clustering.getClustersForDisplay(); 664db87908d640e17ef0946824be158d86c6e2d6836Dave Sparks int numClusters = clusters.size(); 665db87908d640e17ef0946824be158d86c6e2d6836Dave Sparks for (int i = 0; i < numClusters; i++) { 666db87908d640e17ef0946824be158d86c6e2d6836Dave Sparks requestedItems += clusters.get(i).getNumExpectedItems(); 667db87908d640e17ef0946824be158d86c6e2d6836Dave Sparks } 668f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 669f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 670f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mediaSets.get(expandedSetIndex); 671f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (numItemsLoaded < set.getNumExpectedItems()) { 672897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj // We perform calculations for a window that gets 673897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj // anchored to a multiple of NUM_ITEMS_LOOKAHEAD. 674897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj // The start of the window is 0, x, 2x, 3x ... etc 675897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj // where x = NUM_ITEMS_LOOKAHEAD. 67662f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat synchronized (set) { 67762f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat dataSource.loadItemsForSet(this, set, numItemsLoaded, (requestedItems / NUM_ITEMS_LOOKAHEAD) 67862f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat * NUM_ITEMS_LOOKAHEAD + NUM_ITEMS_LOOKAHEAD); 679eb50ae54adfb694b1a424e7a36eed99dc0be1620Venkat set.checkForDeletedItems(); 68062f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat } 681f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (set.getNumExpectedItems() == 0) { 682f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSets.remove(set); 6831c729acdafe147abda6b3479eafb17607f172780Venkat mListenerNeedsUpdate = false; 6841c729acdafe147abda6b3479eafb17607f172780Venkat mListener.onFeedChanged(this, mListenerNeedsLayout); 6851c729acdafe147abda6b3479eafb17607f172780Venkat mListenerNeedsLayout = false; 686f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 687f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (numItemsLoaded != set.mNumItemsLoaded && mListener != null) { 6881c729acdafe147abda6b3479eafb17607f172780Venkat mListenerNeedsUpdate = false; 6891c729acdafe147abda6b3479eafb17607f172780Venkat mListener.onFeedChanged(this, mListenerNeedsLayout); 6901c729acdafe147abda6b3479eafb17607f172780Venkat mListenerNeedsLayout = false; 691f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 692f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 693f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 694f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaFilter filter = mMediaFilter; 695f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (filter != null && mMediaFilteredSet == null) { 696f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (expandedSetIndex != Shared.INVALID) { 697f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mediaSets.get(expandedSetIndex); 698f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaItem> items = set.getItems(); 699f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numItems = set.getNumItems(); 700f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet filteredSet = new MediaSet(); 701f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks filteredSet.setNumExpectedItems(numItems); 702f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mMediaFilteredSet = filteredSet; 703f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 0; i < numItems; ++i) { 704f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaItem item = items.get(i); 705f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (filter.pass(item)) { 706f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks filteredSet.addItem(item); 707f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 708f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 709f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks filteredSet.updateNumExpectedItems(); 710f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks filteredSet.generateTitle(true); 711f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 712f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks updateListener(true); 713f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 714f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 715f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 716f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 717f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 718f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 719f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void expandMediaSet(int mediaSetIndex) { 720f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // We need to check if this slot can be focused or not. 721f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mListener != null) { 722f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener.onFeedAboutToChange(this); 723f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 724f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mExpandedMediaSetIndex > 0 && mediaSetIndex == Shared.INVALID) { 725f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // We are collapsing a previously expanded media set 7261bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks if (mediaSetIndex < mMediaSets.size() && mExpandedMediaSetIndex >= 0 && mExpandedMediaSetIndex < mMediaSets.size()) { 727f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mMediaSets.get(mExpandedMediaSetIndex); 728f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (set.getNumItems() == 0) { 729f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks set.clear(); 730f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 731f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 732f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 733f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mExpandedMediaSetIndex = mediaSetIndex; 734f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mediaSetIndex < mMediaSets.size() && mediaSetIndex >= 0) { 735f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // Notify Picasa that the user entered the album. 736f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // MediaSet set = mMediaSets.get(mediaSetIndex); 7371bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks // PicasaService.requestSync(mContext, 7381bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks // PicasaService.TYPE_ALBUM_PHOTOS, set.mPicasaAlbumId); 739f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 740f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks updateListener(true); 741d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 742f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 743f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 744f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public boolean canExpandSet(int slotIndex) { 745f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int mediaSetIndex = slotIndex; 746f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mediaSetIndex < mMediaSets.size() && mediaSetIndex >= 0) { 747f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mMediaSets.get(mediaSetIndex); 748f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (set.getNumItems() > 0) { 749f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaItem item = set.getItems().get(0); 750f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (item.mId == Shared.INVALID) { 751f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return false; 752f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 753f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return true; 754f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 755f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 756f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return false; 757f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 758f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 759f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public boolean hasExpandedMediaSet() { 760f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return (mExpandedMediaSetIndex != Shared.INVALID); 761f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 762f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 763f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public boolean restorePreviousClusteringState() { 764f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks boolean retVal = disableClusteringIfNecessary(); 765f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (retVal) { 766f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mListener != null) { 767f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener.onFeedAboutToChange(this); 768f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 769f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks updateListener(true); 770d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 771f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 772f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return retVal; 773f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 774f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 775f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private boolean disableClusteringIfNecessary() { 776f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mInClusteringMode) { 777f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // Disable clustering. 778f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mInClusteringMode = false; 779d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 780f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return true; 781f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 782f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return false; 783f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 784f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 785f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public boolean isClustered() { 786f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mInClusteringMode; 787f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 788f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 789f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public MediaSet getCurrentSet() { 790f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mExpandedMediaSetIndex != Shared.INVALID && mExpandedMediaSetIndex < mMediaSets.size()) { 791f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mMediaSets.get(mExpandedMediaSetIndex); 792f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 793f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 794f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 795f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 796f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void performClustering() { 797f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mListener != null) { 798f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener.onFeedAboutToChange(this); 799f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 800f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet setToUse = null; 8012a6f302015b435941369d94f04f3018972558c46Venkat Krishnaraj if (mExpandedMediaSetIndex != Shared.INVALID && mExpandedMediaSetIndex < mMediaSets.size()) { 802f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks setToUse = mMediaSets.get(mExpandedMediaSetIndex); 803f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 804f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (setToUse != null) { 805f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = null; 806d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks synchronized (mClusterSets) { 807f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // Make sure the computation is completed to the end. 808f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering = mClusterSets.get(setToUse); 809f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clustering != null) { 810f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering.compute(null, true); 811f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } else { 812f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return; 813f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 814f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 815f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mInClusteringMode = true; 816f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks updateListener(true); 817f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 818f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 819f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 820f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void moveSetToFront(MediaSet mediaSet) { 821f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaSet> mediaSets = mMediaSets; 822f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numSets = mediaSets.size(); 823f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (numSets == 0) { 824f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSets.add(mediaSet); 825f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return; 826f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 827f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet setToFind = mediaSets.get(0); 828f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (setToFind == mediaSet) { 829f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return; 830f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 831f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSets.set(0, mediaSet); 832f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int indexToSwapTill = -1; 833f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 1; i < numSets; ++i) { 834f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mediaSets.get(i); 835f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (set == mediaSet) { 836f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSets.set(i, setToFind); 837f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks indexToSwapTill = i; 838f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks break; 839f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 840f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 841f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (indexToSwapTill != Shared.INVALID) { 842f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = indexToSwapTill; i > 1; --i) { 843f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet setEnd = mediaSets.get(i); 844f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet setPrev = mediaSets.get(i - 1); 845f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSets.set(i, setPrev); 846f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSets.set(i - 1, setEnd); 847f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 848f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 849d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 850f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 851f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 852f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public MediaSet replaceMediaSet(long setId, DataSource dataSource) { 8531c729acdafe147abda6b3479eafb17607f172780Venkat Log.i(TAG, "Replacing media set " + setId); 8541b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj final MediaSet set = getMediaSet(setId); 855db6a1a6960d791d6004694da52b747de58886634Venkat if (set != null) 856db6a1a6960d791d6004694da52b747de58886634Venkat set.refresh(); 8571b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj return set; 858f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 859d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks 860f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void setSingleImageMode(boolean singleImageMode) { 861f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mSingleImageMode = singleImageMode; 862f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 863f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 864f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public boolean isSingleImageMode() { 865f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mSingleImageMode; 866f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 867f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 868f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public MediaSet getExpandedMediaSet() { 869f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mExpandedMediaSetIndex == Shared.INVALID) 870f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 871f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mExpandedMediaSetIndex >= mMediaSets.size()) 872f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 873f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mMediaSets.get(mExpandedMediaSetIndex); 874f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 8755e0474e8e1942c41234eb251f948c2fbb7445b02Venkat Krishnaraj 8765e0474e8e1942c41234eb251f948c2fbb7445b02Venkat Krishnaraj public void refresh() { 87762dd11281ef6e12049dd6798b184157e9583d7d4Venkat if (mDataSource != null) { 87862dd11281ef6e12049dd6798b184157e9583d7d4Venkat synchronized (mRequestedRefresh) { 87962dd11281ef6e12049dd6798b184157e9583d7d4Venkat mRequestedRefresh.add(mDataSource.getDatabaseUris()); 88062dd11281ef6e12049dd6798b184157e9583d7d4Venkat } 88162dd11281ef6e12049dd6798b184157e9583d7d4Venkat } 882897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj } 883897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj 884897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj private void refresh(final String[] databaseUris) { 88562f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat synchronized (mMediaSets) { 88662f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat if (mDataSource != null) { 88762dd11281ef6e12049dd6798b184157e9583d7d4Venkat synchronized (mRequestedRefresh) { 88862dd11281ef6e12049dd6798b184157e9583d7d4Venkat mRequestedRefresh.add(databaseUris); 88962dd11281ef6e12049dd6798b184157e9583d7d4Venkat } 89062f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat } 8915e0474e8e1942c41234eb251f948c2fbb7445b02Venkat Krishnaraj } 8925e0474e8e1942c41234eb251f948c2fbb7445b02Venkat Krishnaraj } 893897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj 894897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj public void onPause() { 895897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj final HashMap<String, ContentObserver> observers = mContentObservers; 8961b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat final int numObservers = observers.size(); 8971b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat if (numObservers > 0) { 8981b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat String[] uris = new String[numObservers]; 8991b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat final Set<String> keySet = observers.keySet(); 9001b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat if (keySet != null) { 9011b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat uris = keySet.toArray(uris); 9021b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat final int numUris = uris.length; 9031b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat final ContentResolver cr = mContext.getContentResolver(); 9041b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat for (int i = 0; i < numUris; ++i) { 9051b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat final String uri = uris[i]; 9061b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat if (uri != null) { 9071b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat final ContentObserver observer = observers.get(uri); 9081b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat cr.unregisterContentObserver(observer); 9091b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat observers.remove(uri); 9101b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat } 9111b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat } 912897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj } 913897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj } 914897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj observers.clear(); 915897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj } 916897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj 917897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj public void onResume() { 9185a626da1e8c21ee7c9e5f4d8142fc5adf7252f10Venkat final Context context = mContext; 9195a626da1e8c21ee7c9e5f4d8142fc5adf7252f10Venkat final DataSource dataSource = mDataSource; 9205a626da1e8c21ee7c9e5f4d8142fc5adf7252f10Venkat if (context == null || dataSource == null) 9215a626da1e8c21ee7c9e5f4d8142fc5adf7252f10Venkat return; 922897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj // We setup the listeners for this datasource 9235a626da1e8c21ee7c9e5f4d8142fc5adf7252f10Venkat final String[] uris = dataSource.getDatabaseUris(); 924897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj final HashMap<String, ContentObserver> observers = mContentObservers; 9255a626da1e8c21ee7c9e5f4d8142fc5adf7252f10Venkat if (context instanceof Gallery) { 9265a626da1e8c21ee7c9e5f4d8142fc5adf7252f10Venkat final Gallery gallery = (Gallery) context; 9275a626da1e8c21ee7c9e5f4d8142fc5adf7252f10Venkat final ContentResolver cr = context.getContentResolver(); 928897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj if (uris != null) { 929897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj final int numUris = uris.length; 930897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj for (int i = 0; i < numUris; ++i) { 931897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj final String uri = uris[i]; 932897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj final ContentObserver presentObserver = observers.get(uri); 933897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj if (presentObserver == null) { 9345a626da1e8c21ee7c9e5f4d8142fc5adf7252f10Venkat final Handler handler = App.get(context).getHandler(); 935897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj final ContentObserver observer = new ContentObserver(handler) { 936897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj public void onChange(boolean selfChange) { 937897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj if (!mWaitingForMediaScanner) { 938897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj MediaFeed.this.refresh(new String[] { uri }); 939897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj } 940897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj } 941897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj }; 94262dd11281ef6e12049dd6798b184157e9583d7d4Venkat cr.registerContentObserver(Uri.parse(uri), true, observer); 943897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj observers.put(uri, observer); 944897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj } 945897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj } 946897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj } 947897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj } 948897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj refresh(); 949897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj } 950f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks} 951