13c02f2877dc2f8f0b5c01d03fa2b487c040e4000Wei-Ta Chen/* 23c02f2877dc2f8f0b5c01d03fa2b487c040e4000Wei-Ta Chen * Copyright (C) 2009 The Android Open Source Project 33c02f2877dc2f8f0b5c01d03fa2b487c040e4000Wei-Ta Chen * 43c02f2877dc2f8f0b5c01d03fa2b487c040e4000Wei-Ta Chen * Licensed under the Apache License, Version 2.0 (the "License"); 53c02f2877dc2f8f0b5c01d03fa2b487c040e4000Wei-Ta Chen * you may not use this file except in compliance with the License. 63c02f2877dc2f8f0b5c01d03fa2b487c040e4000Wei-Ta Chen * You may obtain a copy of the License at 73c02f2877dc2f8f0b5c01d03fa2b487c040e4000Wei-Ta Chen * 83c02f2877dc2f8f0b5c01d03fa2b487c040e4000Wei-Ta Chen * http://www.apache.org/licenses/LICENSE-2.0 93c02f2877dc2f8f0b5c01d03fa2b487c040e4000Wei-Ta Chen * 103c02f2877dc2f8f0b5c01d03fa2b487c040e4000Wei-Ta Chen * Unless required by applicable law or agreed to in writing, software 113c02f2877dc2f8f0b5c01d03fa2b487c040e4000Wei-Ta Chen * distributed under the License is distributed on an "AS IS" BASIS, 123c02f2877dc2f8f0b5c01d03fa2b487c040e4000Wei-Ta Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133c02f2877dc2f8f0b5c01d03fa2b487c040e4000Wei-Ta Chen * See the License for the specific language governing permissions and 143c02f2877dc2f8f0b5c01d03fa2b487c040e4000Wei-Ta Chen * limitations under the License. 153c02f2877dc2f8f0b5c01d03fa2b487c040e4000Wei-Ta Chen */ 163c02f2877dc2f8f0b5c01d03fa2b487c040e4000Wei-Ta Chen 17f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparkspackage com.cooliris.media; 18f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 19f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport java.util.ArrayList; 20f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport java.util.HashMap; 21897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnarajimport java.util.HashSet; 221b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkatimport java.util.Set; 23f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 24897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnarajimport android.content.ContentResolver; 25f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.content.Context; 26897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnarajimport android.database.ContentObserver; 271c729acdafe147abda6b3479eafb17607f172780Venkatimport android.util.Log; 28f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.view.Gravity; 29f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.widget.Toast; 30897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnarajimport android.net.Uri; 31897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnarajimport android.os.Handler; 32f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.os.Process; 33f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 34d93f177bf2bc26f4ad64ca2f7725da8b0347a77fVenkatimport com.cooliris.app.App; 3529dcedb79b7eb9e3d65adc5d2ea95c1dd5c01df9Chih-Chung Changimport com.cooliris.app.Res; 36f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport com.cooliris.media.MediaClustering.Cluster; 37f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 38f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparkspublic final class MediaFeed implements Runnable { 391c729acdafe147abda6b3479eafb17607f172780Venkat private final String TAG = "MediaFeed"; 40f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public static final int OPERATION_DELETE = 0; 41f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public static final int OPERATION_ROTATE = 1; 42f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public static final int OPERATION_CROP = 2; 43f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 44f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private static final int NUM_ITEMS_LOOKAHEAD = 60; 450e0a636482418d6836bb783d2b00e9e3706dfc14Wei-Ta Chen private static final int NUM_INTERRUPT_RETRIES = 30; 460e0a636482418d6836bb783d2b00e9e3706dfc14Wei-Ta Chen private static final int JOIN_TIMEOUT = 50; 47f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 48f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private IndexRange mVisibleRange = new IndexRange(); 49f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private IndexRange mBufferedRange = new IndexRange(); 50f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private ArrayList<MediaSet> mMediaSets = new ArrayList<MediaSet>(); 51f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private Listener mListener; 52f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private DataSource mDataSource; 53f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private boolean mListenerNeedsUpdate = false; 54d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks private boolean mMediaFeedNeedsToRun = false; 55f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private MediaSet mSingleWrapper = new MediaSet(); 56f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private boolean mInClusteringMode = false; 57f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private HashMap<MediaSet, MediaClustering> mClusterSets = new HashMap<MediaSet, MediaClustering>(32); 58f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private int mExpandedMediaSetIndex = Shared.INVALID; 59f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private MediaFilter mMediaFilter; 60f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private MediaSet mMediaFilteredSet; 61f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private Context mContext; 62f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private Thread mDataSourceThread = null; 63f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private Thread mAlbumSourceThread = null; 64f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private boolean mListenerNeedsLayout; 65f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private boolean mWaitingForMediaScanner; 66f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private boolean mSingleImageMode; 67f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private boolean mLoading; 68897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj private HashMap<String, ContentObserver> mContentObservers = new HashMap<String, ContentObserver>(); 6962dd11281ef6e12049dd6798b184157e9583d7d4Venkat private ArrayList<String[]> mRequestedRefresh = new ArrayList<String[]>(); 700e0a636482418d6836bb783d2b00e9e3706dfc14Wei-Ta Chen private volatile boolean mIsShutdown = false; 71f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 72f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public interface Listener { 73f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public abstract void onFeedAboutToChange(MediaFeed feed); 7462dd11281ef6e12049dd6798b184157e9583d7d4Venkat 75f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public abstract void onFeedChanged(MediaFeed feed, boolean needsLayout); 76f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 77f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 78f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public MediaFeed(Context context, DataSource dataSource, Listener listener) { 79f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mContext = context; 80f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener = listener; 81f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mDataSource = dataSource; 82f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mSingleWrapper.setNumExpectedItems(1); 83f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mLoading = true; 84f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 85d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks 86f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void shutdown() { 870e0a636482418d6836bb783d2b00e9e3706dfc14Wei-Ta Chen mIsShutdown = true; 88f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mDataSourceThread != null) { 89f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mDataSource.shutdown(); 900e0a636482418d6836bb783d2b00e9e3706dfc14Wei-Ta Chen repeatShuttingDownThread(mDataSourceThread); 91f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mDataSourceThread = null; 92f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 93f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mAlbumSourceThread != null) { 940e0a636482418d6836bb783d2b00e9e3706dfc14Wei-Ta Chen repeatShuttingDownThread(mAlbumSourceThread); 95f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mAlbumSourceThread = null; 96f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 97f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numSets = mMediaSets.size(); 98f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 0; i < numSets; ++i) { 99f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mMediaSets.get(i); 100f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks set.clear(); 101f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 102f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks synchronized (mMediaSets) { 103f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mMediaSets.clear(); 104f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 105f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numClusters = mClusterSets.size(); 106f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 0; i < numClusters; ++i) { 107f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering mc = mClusterSets.get(i); 108f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mc != null) { 109f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mc.clear(); 110f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 111f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 112f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mClusterSets.clear(); 113f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener = null; 114f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mDataSource = null; 115f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mSingleWrapper = null; 116f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 117f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 1180e0a636482418d6836bb783d2b00e9e3706dfc14Wei-Ta Chen private void repeatShuttingDownThread(Thread targetThread) { 1190e0a636482418d6836bb783d2b00e9e3706dfc14Wei-Ta Chen for (int i = 0; i < NUM_INTERRUPT_RETRIES && targetThread.isAlive(); ++i) { 1200e0a636482418d6836bb783d2b00e9e3706dfc14Wei-Ta Chen targetThread.interrupt(); 1210e0a636482418d6836bb783d2b00e9e3706dfc14Wei-Ta Chen try { 1220e0a636482418d6836bb783d2b00e9e3706dfc14Wei-Ta Chen targetThread.join(JOIN_TIMEOUT); 1230e0a636482418d6836bb783d2b00e9e3706dfc14Wei-Ta Chen } catch (InterruptedException e) { 1240e0a636482418d6836bb783d2b00e9e3706dfc14Wei-Ta Chen Log.w(TAG, "Cannot stop the thread: " + targetThread.getName(), e); 1250e0a636482418d6836bb783d2b00e9e3706dfc14Wei-Ta Chen Thread.currentThread().interrupt(); 1260e0a636482418d6836bb783d2b00e9e3706dfc14Wei-Ta Chen return; 1270e0a636482418d6836bb783d2b00e9e3706dfc14Wei-Ta Chen } 1280e0a636482418d6836bb783d2b00e9e3706dfc14Wei-Ta Chen } 1290e0a636482418d6836bb783d2b00e9e3706dfc14Wei-Ta Chen 1300e0a636482418d6836bb783d2b00e9e3706dfc14Wei-Ta Chen if (targetThread.isAlive()) { 1310e0a636482418d6836bb783d2b00e9e3706dfc14Wei-Ta Chen Log.w(TAG, "Cannot stop the thread: " + targetThread.getName()); 1320e0a636482418d6836bb783d2b00e9e3706dfc14Wei-Ta Chen } 1330e0a636482418d6836bb783d2b00e9e3706dfc14Wei-Ta Chen } 1340e0a636482418d6836bb783d2b00e9e3706dfc14Wei-Ta Chen 135f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void setVisibleRange(int begin, int end) { 136d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks if (begin != mVisibleRange.begin || end != mVisibleRange.end) { 137d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mVisibleRange.begin = begin; 138d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mVisibleRange.end = end; 139d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks int numItems = 96; 140d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks int numItemsBy2 = numItems / 2; 141d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks int numItemsBy4 = numItems / 4; 142d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mBufferedRange.begin = (begin / numItemsBy2) * numItemsBy2 - numItemsBy4; 143d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mBufferedRange.end = mBufferedRange.begin + numItems; 144d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 145d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks } 146f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 147f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 148f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void setFilter(MediaFilter filter) { 149f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mMediaFilter = filter; 150f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mMediaFilteredSet = null; 151f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mListener != null) { 152f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener.onFeedAboutToChange(this); 153f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 154d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 155f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 156f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 157f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void removeFilter() { 158f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mMediaFilter = null; 159f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mMediaFilteredSet = null; 160f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mListener != null) { 161f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener.onFeedAboutToChange(this); 162f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks updateListener(true); 163f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 164d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 165f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 166f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 167f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public ArrayList<MediaSet> getMediaSets() { 168f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mMediaSets; 169f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 170f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 171d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks public MediaSet getMediaSet(final long setId) { 172f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (setId != Shared.INVALID) { 173d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks try { 174d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks int mMediaSetsSize = mMediaSets.size(); 175d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks for (int i = 0; i < mMediaSetsSize; i++) { 1761b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj final MediaSet set = mMediaSets.get(i); 1771b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj if (set.mId == setId) { 1781b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj set.mFlagForDelete = false; 1791b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj return set; 180d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks } 181f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 182d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks } catch (Exception e) { 183d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks return null; 184f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 185f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 186f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 187f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 188f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 189f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public MediaSet getFilteredSet() { 190f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mMediaFilteredSet; 191f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 192f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 193f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public MediaSet addMediaSet(final long setId, DataSource dataSource) { 194f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet mediaSet = new MediaSet(dataSource); 195f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSet.mId = setId; 196f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mMediaSets.add(mediaSet); 197d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks if (mDataSourceThread != null && !mDataSourceThread.isAlive()) { 198d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mDataSourceThread.start(); 199d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks } 200d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 201f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mediaSet; 202f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 203f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 204f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public DataSource getDataSource() { 205f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mDataSource; 206f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 207f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 208f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public MediaClustering getClustering() { 209f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mExpandedMediaSetIndex != Shared.INVALID && mExpandedMediaSetIndex < mMediaSets.size()) { 210f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mClusterSets.get(mMediaSets.get(mExpandedMediaSetIndex)); 211f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 212f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 213f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 214f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 215f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public ArrayList<Cluster> getClustersForSet(final MediaSet set) { 216f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<Cluster> clusters = null; 217f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mClusterSets != null && mClusterSets.containsKey(set)) { 218f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering mediaClustering = mClusterSets.get(set); 219f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mediaClustering != null) { 220f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clusters = mediaClustering.getClusters(); 221f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 222f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 223f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return clusters; 224f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 225f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 226f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void addItemToMediaSet(MediaItem item, MediaSet mediaSet) { 227f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks item.mParentMediaSet = mediaSet; 228f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSet.addItem(item); 229d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks synchronized (mClusterSets) { 230f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (item.mClusteringState == MediaItem.NOT_CLUSTERED) { 231f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = mClusterSets.get(mediaSet); 232f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clustering == null) { 233f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering = new MediaClustering(mediaSet.isPicassaAlbum()); 234f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mClusterSets.put(mediaSet, clustering); 235f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 236f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering.setTimeRange(mediaSet.mMaxTimestamp - mediaSet.mMinTimestamp, mediaSet.getNumExpectedItems()); 237f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering.addItemForClustering(item); 238f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks item.mClusteringState = MediaItem.CLUSTERED; 239f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 240f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 241d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 242f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 243f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 244f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void performOperation(final int operation, final ArrayList<MediaBucket> mediaBuckets, final Object data) { 245f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numBuckets = mediaBuckets.size(); 246f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks final ArrayList<MediaBucket> copyMediaBuckets = new ArrayList<MediaBucket>(numBuckets); 247f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 0; i < numBuckets; ++i) { 248f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks copyMediaBuckets.add(mediaBuckets.get(i)); 249f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 250f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (operation == OPERATION_DELETE && mListener != null) { 251f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener.onFeedAboutToChange(this); 252f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 253f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks Thread operationThread = new Thread(new Runnable() { 254f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void run() { 255f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaBucket> mediaBuckets = copyMediaBuckets; 256f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (operation == OPERATION_DELETE) { 257f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numBuckets = mediaBuckets.size(); 258f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 0; i < numBuckets; ++i) { 259f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaBucket bucket = mediaBuckets.get(i); 260f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = bucket.mediaSet; 261f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaItem> items = bucket.mediaItems; 262f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (set != null && items == null) { 263f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // Remove the entire bucket. 264f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks removeMediaSet(set); 265f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } else if (set != null && items != null) { 266f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // We need to remove these items from the set. 267f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numItems = items.size(); 2681bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks // We also need to delete the items from the 2691bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks // cluster. 270f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = mClusterSets.get(set); 271f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int j = 0; j < numItems; ++j) { 272f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaItem item = items.get(j); 273f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks removeItemFromMediaSet(item, set); 274f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clustering != null) { 275f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering.removeItemFromClustering(item); 276f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 277f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 278f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks set.updateNumExpectedItems(); 279f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks set.generateTitle(true); 280f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 281f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 282f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks updateListener(true); 283d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 284f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mDataSource != null) { 285f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mDataSource.performOperation(OPERATION_DELETE, mediaBuckets, null); 286f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 287f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } else { 288f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mDataSource.performOperation(operation, mediaBuckets, data); 289f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 290f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 291f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks }); 292f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks operationThread.setName("Operation " + operation); 293f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks operationThread.start(); 294f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 295f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 296f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void removeMediaSet(MediaSet set) { 2972b04f591f758b7af03c43d90e91b939cbd515506Venkat Krishnaraj synchronized (mMediaSets) { 2981bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks mMediaSets.remove(set); 2992b04f591f758b7af03c43d90e91b939cbd515506Venkat Krishnaraj } 300d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 301f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 302f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 303f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private void removeItemFromMediaSet(MediaItem item, MediaSet mediaSet) { 304f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSet.removeItem(item); 305d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks synchronized (mClusterSets) { 306f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = mClusterSets.get(mediaSet); 307f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clustering != null) { 308f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering.removeItemFromClustering(item); 309f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 310f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 311d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 312f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 313f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 314f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void updateListener(boolean needsLayout) { 315f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListenerNeedsUpdate = true; 316f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListenerNeedsLayout = needsLayout; 317f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 318f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 319f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public int getNumSlots() { 320f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int currentMediaSetIndex = mExpandedMediaSetIndex; 321f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaSet> mediaSets = mMediaSets; 322f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int mediaSetsSize = mediaSets.size(); 323f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 324f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mInClusteringMode == false) { 325f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (currentMediaSetIndex == Shared.INVALID || currentMediaSetIndex >= mediaSetsSize) { 326f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mediaSetsSize; 327f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } else { 328f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet setToUse = (mMediaFilteredSet == null) ? mediaSets.get(currentMediaSetIndex) : mMediaFilteredSet; 3295e0474e8e1942c41234eb251f948c2fbb7445b02Venkat Krishnaraj return setToUse.getNumExpectedItems(); 330f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 331f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } else if (currentMediaSetIndex != Shared.INVALID && currentMediaSetIndex < mediaSetsSize) { 332f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mediaSets.get(currentMediaSetIndex); 333f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = mClusterSets.get(set); 334f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clustering != null) { 335f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return clustering.getClustersForDisplay().size(); 336f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 337f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 338f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return 0; 339f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 34062dd11281ef6e12049dd6798b184157e9583d7d4Venkat 3417cde3b179f4d12f53c2a1db1e4f903bd06b7011eWei-Ta Chen public void copySlotStateFrom(MediaFeed another) { 3427cde3b179f4d12f53c2a1db1e4f903bd06b7011eWei-Ta Chen mExpandedMediaSetIndex = another.mExpandedMediaSetIndex; 3437cde3b179f4d12f53c2a1db1e4f903bd06b7011eWei-Ta Chen mInClusteringMode = another.mInClusteringMode; 3447cde3b179f4d12f53c2a1db1e4f903bd06b7011eWei-Ta Chen } 3457cde3b179f4d12f53c2a1db1e4f903bd06b7011eWei-Ta Chen 34688dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat public ArrayList<Integer> getBreaks() { 34788dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat if (true) 34888dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat return null; 34988dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat int currentMediaSetIndex = mExpandedMediaSetIndex; 35088dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat ArrayList<MediaSet> mediaSets = mMediaSets; 35188dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat int mediaSetsSize = mediaSets.size(); 35288dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat if (currentMediaSetIndex == Shared.INVALID || currentMediaSetIndex >= mediaSetsSize) 35388dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat return null; 35488dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat MediaSet set = mediaSets.get(currentMediaSetIndex); 35588dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat MediaClustering clustering = mClusterSets.get(set); 35688dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat if (clustering != null) { 35788dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat clustering.compute(null, true); 35888dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat final ArrayList<Cluster> clusters = clustering.getClustersForDisplay(); 35988dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat int numClusters = clusters.size(); 36088dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat final ArrayList<Integer> retVal = new ArrayList<Integer>(numClusters); 36188dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat int size = 0; 36288dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat for (int i = 0; i < numClusters; ++i) { 36388dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat size += clusters.get(i).getItems().size(); 36488dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat retVal.add(size); 36588dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat } 36688dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat return retVal; 36788dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat } else { 36888dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat return null; 36988dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat } 37088dc4ec391fdd373821aa94ae93ca0c231eb98bbVenkat } 371f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 372f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public MediaSet getSetForSlot(int slotIndex) { 373f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (slotIndex < 0) { 374f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 375f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 376f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 377f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaSet> mediaSets = mMediaSets; 378f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int mediaSetsSize = mediaSets.size(); 379f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int currentMediaSetIndex = mExpandedMediaSetIndex; 380f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 381f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mInClusteringMode == false) { 382f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (currentMediaSetIndex == Shared.INVALID || currentMediaSetIndex >= mediaSetsSize) { 383f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (slotIndex >= mediaSetsSize) { 384f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 385f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 386f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mMediaSets.get(slotIndex); 387f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 388f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mSingleWrapper.getNumItems() == 0) { 389f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mSingleWrapper.addItem(null); 390f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 391f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet setToUse = (mMediaFilteredSet == null) ? mMediaSets.get(currentMediaSetIndex) : mMediaFilteredSet; 392f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaItem> items = setToUse.getItems(); 393f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (slotIndex >= setToUse.getNumItems()) { 394f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 395f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 396f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mSingleWrapper.getItems().set(0, items.get(slotIndex)); 397f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mSingleWrapper; 398f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } else if (currentMediaSetIndex != Shared.INVALID && currentMediaSetIndex < mediaSetsSize) { 399f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mediaSets.get(currentMediaSetIndex); 400f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = mClusterSets.get(set); 401f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clustering != null) { 402f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaClustering.Cluster> clusters = clustering.getClustersForDisplay(); 403f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clusters.size() > slotIndex) { 404f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering.Cluster cluster = clusters.get(slotIndex); 405f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks cluster.generateCaption(mContext); 406f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return cluster; 407f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 408f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 409f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 410f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 411f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 412f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 413f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public boolean getWaitingForMediaScanner() { 414f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mWaitingForMediaScanner; 415f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 416d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks 417f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public boolean isLoading() { 418f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mLoading; 419f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 420f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 421f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void start() { 422f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks final MediaFeed feed = this; 42362f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat onResume(); 424f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mLoading = true; 425d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mDataSourceThread = new Thread(this); 426d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mDataSourceThread.setName("MediaFeed"); 4270e0a636482418d6836bb783d2b00e9e3706dfc14Wei-Ta Chen mIsShutdown = false; 428f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mAlbumSourceThread = new Thread(new Runnable() { 429f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void run() { 430f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mContext == null) 431f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return; 432f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 433f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks DataSource dataSource = mDataSource; 4341bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks // We must wait while the SD card is mounted or the MediaScanner 4351bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks // is running. 436d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks if (dataSource != null) { 4371b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj loadMediaSets(); 438d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks } 439f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mWaitingForMediaScanner = false; 440f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks while (ImageManager.isMediaScannerScanning(mContext.getContentResolver())) { 441f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // MediaScanner is still running, wait 44288ed7e72a2a0bfdbef7f72aea2b2ddfd74961bdbVenkat Krishnaraj if (Thread.interrupted()) 44388ed7e72a2a0bfdbef7f72aea2b2ddfd74961bdbVenkat Krishnaraj return; 444f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mWaitingForMediaScanner = true; 445f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks try { 446f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mContext == null) 447f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return; 44829dcedb79b7eb9e3d65adc5d2ea95c1dd5c01df9Chih-Chung Chang showToast(mContext.getResources().getString(Res.string.initializing), Toast.LENGTH_LONG); 4491b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj if (dataSource != null) { 4501b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj loadMediaSets(); 4511b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj } 4521b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj Thread.sleep(10000); 453f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } catch (InterruptedException e) { 45488ed7e72a2a0bfdbef7f72aea2b2ddfd74961bdbVenkat Krishnaraj return; 455f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 456f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 457f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mWaitingForMediaScanner) { 45829dcedb79b7eb9e3d65adc5d2ea95c1dd5c01df9Chih-Chung Chang showToast(mContext.getResources().getString(Res.string.loading_new), Toast.LENGTH_LONG); 459d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mWaitingForMediaScanner = false; 4601b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj loadMediaSets(); 461f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 462f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mLoading = false; 463f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 464f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks }); 465f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mAlbumSourceThread.setName("MediaSets"); 466f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mAlbumSourceThread.start(); 467f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 468897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj 4691b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj private void loadMediaSets() { 4701b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj if (mDataSource == null) 4711b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj return; 4721b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj final ArrayList<MediaSet> sets = mMediaSets; 47362f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat synchronized (sets) { 47480182dccb216689e392da1c749f32f6c0cda6f42Venkat final int numSets = sets.size(); 47580182dccb216689e392da1c749f32f6c0cda6f42Venkat for (int i = 0; i < numSets; ++i) { 47680182dccb216689e392da1c749f32f6c0cda6f42Venkat final MediaSet set = sets.get(i); 47780182dccb216689e392da1c749f32f6c0cda6f42Venkat set.mFlagForDelete = true; 47880182dccb216689e392da1c749f32f6c0cda6f42Venkat } 47962f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat mDataSource.refresh(MediaFeed.this, mDataSource.getDatabaseUris()); 48062f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat mDataSource.loadMediaSets(MediaFeed.this); 48180182dccb216689e392da1c749f32f6c0cda6f42Venkat final ArrayList<MediaSet> setsToRemove = new ArrayList<MediaSet>(); 48280182dccb216689e392da1c749f32f6c0cda6f42Venkat for (int i = 0; i < numSets; ++i) { 48380182dccb216689e392da1c749f32f6c0cda6f42Venkat final MediaSet set = sets.get(i); 48480182dccb216689e392da1c749f32f6c0cda6f42Venkat if (set.mFlagForDelete) { 48580182dccb216689e392da1c749f32f6c0cda6f42Venkat setsToRemove.add(set); 48680182dccb216689e392da1c749f32f6c0cda6f42Venkat } 4871b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj } 48880182dccb216689e392da1c749f32f6c0cda6f42Venkat int numSetsToRemove = setsToRemove.size(); 48980182dccb216689e392da1c749f32f6c0cda6f42Venkat for (int i = 0; i < numSetsToRemove; ++i) { 49080182dccb216689e392da1c749f32f6c0cda6f42Venkat sets.remove(setsToRemove.get(i)); 49180182dccb216689e392da1c749f32f6c0cda6f42Venkat } 49280182dccb216689e392da1c749f32f6c0cda6f42Venkat setsToRemove.clear(); 4931b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj } 49480182dccb216689e392da1c749f32f6c0cda6f42Venkat mMediaFeedNeedsToRun = true; 4951b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj updateListener(false); 4961b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj } 497f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 498f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private void showToast(final String string, final int duration) { 499f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks showToast(string, duration, false); 500f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 501f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 502f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private void showToast(final String string, final int duration, final boolean centered) { 503d93f177bf2bc26f4ad64ca2f7725da8b0347a77fVenkat if (mContext != null && !App.get(mContext).isPaused()) { 50462f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat App.get(mContext).getHandler().post(new Runnable() { 505f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void run() { 506f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mContext != null) { 507f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks Toast toast = Toast.makeText(mContext, string, duration); 508f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (centered) { 509f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks toast.setGravity(Gravity.CENTER, 0, 0); 510f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 511f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks toast.show(); 512f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 513f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 514f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks }); 515f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 516f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 517f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 518f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void run() { 519f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks DataSource dataSource = mDataSource; 520d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks int sleepMs = 10; 521f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 522f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (dataSource != null) { 5230e0a636482418d6836bb783d2b00e9e3706dfc14Wei-Ta Chen while (!Thread.interrupted() && !mIsShutdown) { 52462dd11281ef6e12049dd6798b184157e9583d7d4Venkat String[] databaseUris = null; 52562dd11281ef6e12049dd6798b184157e9583d7d4Venkat boolean performRefresh = false; 52662dd11281ef6e12049dd6798b184157e9583d7d4Venkat synchronized (mRequestedRefresh) { 52762dd11281ef6e12049dd6798b184157e9583d7d4Venkat if (mRequestedRefresh.size() > 0) { 52862dd11281ef6e12049dd6798b184157e9583d7d4Venkat // We prune this first. 52962dd11281ef6e12049dd6798b184157e9583d7d4Venkat int numRequests = mRequestedRefresh.size(); 53062dd11281ef6e12049dd6798b184157e9583d7d4Venkat for (int i = 0; i < numRequests; ++i) { 53162dd11281ef6e12049dd6798b184157e9583d7d4Venkat databaseUris = ArrayUtils.addAll(databaseUris, mRequestedRefresh.get(i)); 53262dd11281ef6e12049dd6798b184157e9583d7d4Venkat } 53362dd11281ef6e12049dd6798b184157e9583d7d4Venkat mRequestedRefresh.clear(); 53462dd11281ef6e12049dd6798b184157e9583d7d4Venkat performRefresh = true; 53562dd11281ef6e12049dd6798b184157e9583d7d4Venkat // We need to eliminate duplicate uris in this array 53662dd11281ef6e12049dd6798b184157e9583d7d4Venkat final HashMap<String, String> uris = new HashMap<String, String>(); 53762dd11281ef6e12049dd6798b184157e9583d7d4Venkat if (databaseUris != null) { 53862dd11281ef6e12049dd6798b184157e9583d7d4Venkat int numUris = databaseUris.length; 53962dd11281ef6e12049dd6798b184157e9583d7d4Venkat for (int i = 0; i < numUris; ++i) { 54062dd11281ef6e12049dd6798b184157e9583d7d4Venkat final String uri = databaseUris[i]; 54162dd11281ef6e12049dd6798b184157e9583d7d4Venkat if (uri != null) 54262dd11281ef6e12049dd6798b184157e9583d7d4Venkat uris.put(uri, uri); 54362dd11281ef6e12049dd6798b184157e9583d7d4Venkat } 54462dd11281ef6e12049dd6798b184157e9583d7d4Venkat } 54562dd11281ef6e12049dd6798b184157e9583d7d4Venkat databaseUris = new String[0]; 54662dd11281ef6e12049dd6798b184157e9583d7d4Venkat databaseUris = (String[]) uris.keySet().toArray(databaseUris); 54762dd11281ef6e12049dd6798b184157e9583d7d4Venkat } 54862dd11281ef6e12049dd6798b184157e9583d7d4Venkat } 549b832709e16e0d018447f3d20755d3c22d09e2ba0Venkat boolean settingFeedAboutToChange = false; 55062dd11281ef6e12049dd6798b184157e9583d7d4Venkat if (performRefresh) { 5511c729acdafe147abda6b3479eafb17607f172780Venkat if (dataSource != null) { 552b832709e16e0d018447f3d20755d3c22d09e2ba0Venkat if (mListener != null) { 553b832709e16e0d018447f3d20755d3c22d09e2ba0Venkat settingFeedAboutToChange = true; 554b832709e16e0d018447f3d20755d3c22d09e2ba0Venkat mListener.onFeedAboutToChange(this); 555b832709e16e0d018447f3d20755d3c22d09e2ba0Venkat } 55662dd11281ef6e12049dd6798b184157e9583d7d4Venkat dataSource.refresh(this, databaseUris); 55771660902f0aa83113bf11a2933e92b08c524fed5Venkat mMediaFeedNeedsToRun = true; 5581c729acdafe147abda6b3479eafb17607f172780Venkat } 5591c729acdafe147abda6b3479eafb17607f172780Venkat } 5601c729acdafe147abda6b3479eafb17607f172780Venkat if (mListenerNeedsUpdate && !mMediaFeedNeedsToRun) { 561f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListenerNeedsUpdate = false; 562f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mListener != null) 56346afd9b71156248a494ea618c37b5a373fd8e386Venkat synchronized (mMediaSets) { 56446afd9b71156248a494ea618c37b5a373fd8e386Venkat mListener.onFeedChanged(this, mListenerNeedsLayout); 56546afd9b71156248a494ea618c37b5a373fd8e386Venkat } 566f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks try { 567f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks Thread.sleep(sleepMs); 568f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } catch (InterruptedException e) { 569f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return; 570f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 571f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } else { 572f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks try { 573f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks Thread.sleep(sleepMs); 574f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } catch (InterruptedException e) { 575f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return; 576f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 577f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 578d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks sleepMs = 300; 579d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks if (!mMediaFeedNeedsToRun) 580d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks continue; 581d93f177bf2bc26f4ad64ca2f7725da8b0347a77fVenkat App app = App.get(mContext); 58262f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat if (app == null || app.isPaused()) 58362f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat continue; 584b832709e16e0d018447f3d20755d3c22d09e2ba0Venkat if (settingFeedAboutToChange) { 585b832709e16e0d018447f3d20755d3c22d09e2ba0Venkat updateListener(true); 586b832709e16e0d018447f3d20755d3c22d09e2ba0Venkat } 587d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = false; 588f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaSet> mediaSets = mMediaSets; 589f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks synchronized (mediaSets) { 590f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int expandedSetIndex = mExpandedMediaSetIndex; 591f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (expandedSetIndex >= mMediaSets.size()) { 592f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks expandedSetIndex = Shared.INVALID; 593f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 594f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (expandedSetIndex == Shared.INVALID) { 595f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // We purge the sets outside this visibleRange. 5962b04f591f758b7af03c43d90e91b939cbd515506Venkat Krishnaraj int numSets = mediaSets.size(); 597f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks IndexRange visibleRange = mVisibleRange; 598f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks IndexRange bufferedRange = mBufferedRange; 599f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks boolean scanMediaSets = true; 600f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 0; i < numSets; ++i) { 601f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (i >= visibleRange.begin && i <= visibleRange.end && scanMediaSets) { 602f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mediaSets.get(i); 603f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numItemsLoaded = set.mNumItemsLoaded; 604f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (numItemsLoaded < set.getNumExpectedItems() && numItemsLoaded < 8) { 60562f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat synchronized (set) { 60662f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat dataSource.loadItemsForSet(this, set, numItemsLoaded, 8); 607eb50ae54adfb694b1a424e7a36eed99dc0be1620Venkat set.checkForDeletedItems(); 60862f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat } 609f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (set.getNumExpectedItems() == 0) { 610f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSets.remove(set); 611f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks break; 612f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 613f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mListener != null) { 6141c729acdafe147abda6b3479eafb17607f172780Venkat mListenerNeedsUpdate = false; 6151c729acdafe147abda6b3479eafb17607f172780Venkat mListener.onFeedChanged(this, mListenerNeedsLayout); 6161c729acdafe147abda6b3479eafb17607f172780Venkat mListenerNeedsLayout = false; 617f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 618f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks sleepMs = 100; 619f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks scanMediaSets = false; 620f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 621d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks if (!set.setContainsValidItems()) { 622d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mediaSets.remove(set); 623d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks if (mListener != null) { 6241c729acdafe147abda6b3479eafb17607f172780Venkat mListenerNeedsUpdate = false; 6251c729acdafe147abda6b3479eafb17607f172780Venkat mListener.onFeedChanged(this, mListenerNeedsLayout); 6261c729acdafe147abda6b3479eafb17607f172780Venkat mListenerNeedsLayout = false; 627d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks } 628d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks break; 629d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks } 630f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 631f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 6322b04f591f758b7af03c43d90e91b939cbd515506Venkat Krishnaraj numSets = mediaSets.size(); 633f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 0; i < numSets; ++i) { 634f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mediaSets.get(i); 635f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (i >= bufferedRange.begin && i <= bufferedRange.end) { 636f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (scanMediaSets) { 637f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numItemsLoaded = set.mNumItemsLoaded; 638f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (numItemsLoaded < set.getNumExpectedItems() && numItemsLoaded < 8) { 63962f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat synchronized (set) { 64062f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat dataSource.loadItemsForSet(this, set, numItemsLoaded, 8); 641eb50ae54adfb694b1a424e7a36eed99dc0be1620Venkat set.checkForDeletedItems(); 64262f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat } 643f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (set.getNumExpectedItems() == 0) { 644f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSets.remove(set); 645f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks break; 646f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 647f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mListener != null) { 6481c729acdafe147abda6b3479eafb17607f172780Venkat mListenerNeedsUpdate = false; 6491c729acdafe147abda6b3479eafb17607f172780Venkat mListener.onFeedChanged(this, mListenerNeedsLayout); 6501c729acdafe147abda6b3479eafb17607f172780Venkat mListenerNeedsLayout = false; 651f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 652f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks sleepMs = 100; 653f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks scanMediaSets = false; 654f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 655f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 656897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj } else if (!mListenerNeedsUpdate && (i < bufferedRange.begin || i > bufferedRange.end)) { 657f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // Purge this set to its initial status. 658f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = mClusterSets.get(set); 659f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clustering != null) { 660f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering.clear(); 661f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mClusterSets.remove(set); 662f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 663f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (set.getNumItems() != 0) 664f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks set.clear(); 665f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 666f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 667f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 668f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (expandedSetIndex != Shared.INVALID) { 669f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numSets = mMediaSets.size(); 670f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 0; i < numSets; ++i) { 671f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // Purge other sets. 672f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (i != expandedSetIndex) { 673f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mediaSets.get(i); 674f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = mClusterSets.get(set); 675f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clustering != null) { 676f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering.clear(); 677f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mClusterSets.remove(set); 678f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 679897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj if (set.mNumItemsLoaded != 0) 680f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks set.clear(); 681f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 682f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 683f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // Make sure all the items are loaded for the album. 684f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numItemsLoaded = mediaSets.get(expandedSetIndex).mNumItemsLoaded; 685f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int requestedItems = mVisibleRange.end; 686f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // requestedItems count changes in clustering mode. 687f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mInClusteringMode && mClusterSets != null) { 688f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks requestedItems = 0; 689f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = mClusterSets.get(mediaSets.get(expandedSetIndex)); 690db87908d640e17ef0946824be158d86c6e2d6836Dave Sparks if (clustering != null) { 691db87908d640e17ef0946824be158d86c6e2d6836Dave Sparks ArrayList<Cluster> clusters = clustering.getClustersForDisplay(); 692db87908d640e17ef0946824be158d86c6e2d6836Dave Sparks int numClusters = clusters.size(); 693db87908d640e17ef0946824be158d86c6e2d6836Dave Sparks for (int i = 0; i < numClusters; i++) { 694db87908d640e17ef0946824be158d86c6e2d6836Dave Sparks requestedItems += clusters.get(i).getNumExpectedItems(); 695db87908d640e17ef0946824be158d86c6e2d6836Dave Sparks } 696f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 697f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 698f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mediaSets.get(expandedSetIndex); 699f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (numItemsLoaded < set.getNumExpectedItems()) { 700897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj // We perform calculations for a window that gets 701897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj // anchored to a multiple of NUM_ITEMS_LOOKAHEAD. 702897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj // The start of the window is 0, x, 2x, 3x ... etc 703897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj // where x = NUM_ITEMS_LOOKAHEAD. 70462f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat synchronized (set) { 70562f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat dataSource.loadItemsForSet(this, set, numItemsLoaded, (requestedItems / NUM_ITEMS_LOOKAHEAD) 70662f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat * NUM_ITEMS_LOOKAHEAD + NUM_ITEMS_LOOKAHEAD); 707eb50ae54adfb694b1a424e7a36eed99dc0be1620Venkat set.checkForDeletedItems(); 70862f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat } 709f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (set.getNumExpectedItems() == 0) { 710f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSets.remove(set); 7111c729acdafe147abda6b3479eafb17607f172780Venkat mListenerNeedsUpdate = false; 7121c729acdafe147abda6b3479eafb17607f172780Venkat mListener.onFeedChanged(this, mListenerNeedsLayout); 7131c729acdafe147abda6b3479eafb17607f172780Venkat mListenerNeedsLayout = false; 714f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 715f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (numItemsLoaded != set.mNumItemsLoaded && mListener != null) { 7161c729acdafe147abda6b3479eafb17607f172780Venkat mListenerNeedsUpdate = false; 7171c729acdafe147abda6b3479eafb17607f172780Venkat mListener.onFeedChanged(this, mListenerNeedsLayout); 7181c729acdafe147abda6b3479eafb17607f172780Venkat mListenerNeedsLayout = false; 719f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 720f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 721f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 722f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaFilter filter = mMediaFilter; 723f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (filter != null && mMediaFilteredSet == null) { 724f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (expandedSetIndex != Shared.INVALID) { 725f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mediaSets.get(expandedSetIndex); 726f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaItem> items = set.getItems(); 727f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numItems = set.getNumItems(); 728f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet filteredSet = new MediaSet(); 729f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks filteredSet.setNumExpectedItems(numItems); 730f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mMediaFilteredSet = filteredSet; 731f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 0; i < numItems; ++i) { 732f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaItem item = items.get(i); 733f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (filter.pass(item)) { 734f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks filteredSet.addItem(item); 735f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 736f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 737f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks filteredSet.updateNumExpectedItems(); 738f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks filteredSet.generateTitle(true); 739f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 740f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks updateListener(true); 741f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 742f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 743f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 744f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 745f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 746f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 747f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void expandMediaSet(int mediaSetIndex) { 748f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // We need to check if this slot can be focused or not. 749f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mListener != null) { 750f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener.onFeedAboutToChange(this); 751f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 752f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mExpandedMediaSetIndex > 0 && mediaSetIndex == Shared.INVALID) { 753f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // We are collapsing a previously expanded media set 7541bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks if (mediaSetIndex < mMediaSets.size() && mExpandedMediaSetIndex >= 0 && mExpandedMediaSetIndex < mMediaSets.size()) { 755f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mMediaSets.get(mExpandedMediaSetIndex); 756f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (set.getNumItems() == 0) { 757f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks set.clear(); 758f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 759f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 760f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 761f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mExpandedMediaSetIndex = mediaSetIndex; 762f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mediaSetIndex < mMediaSets.size() && mediaSetIndex >= 0) { 763f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // Notify Picasa that the user entered the album. 764f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // MediaSet set = mMediaSets.get(mediaSetIndex); 7651bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks // PicasaService.requestSync(mContext, 7661bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks // PicasaService.TYPE_ALBUM_PHOTOS, set.mPicasaAlbumId); 767f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 768f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks updateListener(true); 769d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 770f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 771f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 772f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public boolean canExpandSet(int slotIndex) { 773f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int mediaSetIndex = slotIndex; 774f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mediaSetIndex < mMediaSets.size() && mediaSetIndex >= 0) { 775f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mMediaSets.get(mediaSetIndex); 776f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (set.getNumItems() > 0) { 777f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaItem item = set.getItems().get(0); 778f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (item.mId == Shared.INVALID) { 779f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return false; 780f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 781f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return true; 782f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 783f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 784f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return false; 785f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 786f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 787f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public boolean hasExpandedMediaSet() { 788f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return (mExpandedMediaSetIndex != Shared.INVALID); 789f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 790f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 791f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public boolean restorePreviousClusteringState() { 792f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks boolean retVal = disableClusteringIfNecessary(); 793f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (retVal) { 794f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mListener != null) { 795f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener.onFeedAboutToChange(this); 796f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 797f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks updateListener(true); 798d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 799f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 800f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return retVal; 801f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 802f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 803f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks private boolean disableClusteringIfNecessary() { 804f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mInClusteringMode) { 805f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // Disable clustering. 806f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mInClusteringMode = false; 807d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 808f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return true; 809f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 810f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return false; 811f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 812f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 813f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public boolean isClustered() { 814f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mInClusteringMode; 815f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 816f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 817f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public MediaSet getCurrentSet() { 818f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mExpandedMediaSetIndex != Shared.INVALID && mExpandedMediaSetIndex < mMediaSets.size()) { 819f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mMediaSets.get(mExpandedMediaSetIndex); 820f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 821f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 822f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 823f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 824f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void performClustering() { 825f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mListener != null) { 826f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mListener.onFeedAboutToChange(this); 827f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 828f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet setToUse = null; 8292a6f302015b435941369d94f04f3018972558c46Venkat Krishnaraj if (mExpandedMediaSetIndex != Shared.INVALID && mExpandedMediaSetIndex < mMediaSets.size()) { 830f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks setToUse = mMediaSets.get(mExpandedMediaSetIndex); 831f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 832f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (setToUse != null) { 833f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaClustering clustering = null; 834d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks synchronized (mClusterSets) { 835f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks // Make sure the computation is completed to the end. 836f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering = mClusterSets.get(setToUse); 837f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (clustering != null) { 838f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks clustering.compute(null, true); 839f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } else { 840f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return; 841f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 842f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 843f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mInClusteringMode = true; 844f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks updateListener(true); 845f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 846f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 847f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 848f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void moveSetToFront(MediaSet mediaSet) { 849f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks ArrayList<MediaSet> mediaSets = mMediaSets; 850f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int numSets = mediaSets.size(); 851f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (numSets == 0) { 852f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSets.add(mediaSet); 853f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return; 854f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 855f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet setToFind = mediaSets.get(0); 856f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (setToFind == mediaSet) { 857f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return; 858f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 859f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSets.set(0, mediaSet); 860f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks int indexToSwapTill = -1; 861f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = 1; i < numSets; ++i) { 862f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet set = mediaSets.get(i); 863f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (set == mediaSet) { 864f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSets.set(i, setToFind); 865f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks indexToSwapTill = i; 866f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks break; 867f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 868f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 869f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (indexToSwapTill != Shared.INVALID) { 870f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks for (int i = indexToSwapTill; i > 1; --i) { 871f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet setEnd = mediaSets.get(i); 872f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks MediaSet setPrev = mediaSets.get(i - 1); 873f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSets.set(i, setPrev); 874f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mediaSets.set(i - 1, setEnd); 875f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 876f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 877d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks mMediaFeedNeedsToRun = true; 878f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 879f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 880f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public MediaSet replaceMediaSet(long setId, DataSource dataSource) { 8811c729acdafe147abda6b3479eafb17607f172780Venkat Log.i(TAG, "Replacing media set " + setId); 8821b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj final MediaSet set = getMediaSet(setId); 883db6a1a6960d791d6004694da52b747de58886634Venkat if (set != null) 884db6a1a6960d791d6004694da52b747de58886634Venkat set.refresh(); 8851b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj return set; 886f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 887d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks 888f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public void setSingleImageMode(boolean singleImageMode) { 889f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks mSingleImageMode = singleImageMode; 890f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 891f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 892f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public boolean isSingleImageMode() { 893f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mSingleImageMode; 894f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 895f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks 896f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks public MediaSet getExpandedMediaSet() { 897f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mExpandedMediaSetIndex == Shared.INVALID) 898f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 899f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks if (mExpandedMediaSetIndex >= mMediaSets.size()) 900f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return null; 901f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks return mMediaSets.get(mExpandedMediaSetIndex); 902f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks } 9035e0474e8e1942c41234eb251f948c2fbb7445b02Venkat Krishnaraj 9045e0474e8e1942c41234eb251f948c2fbb7445b02Venkat Krishnaraj public void refresh() { 90562dd11281ef6e12049dd6798b184157e9583d7d4Venkat if (mDataSource != null) { 90662dd11281ef6e12049dd6798b184157e9583d7d4Venkat synchronized (mRequestedRefresh) { 90762dd11281ef6e12049dd6798b184157e9583d7d4Venkat mRequestedRefresh.add(mDataSource.getDatabaseUris()); 90862dd11281ef6e12049dd6798b184157e9583d7d4Venkat } 90962dd11281ef6e12049dd6798b184157e9583d7d4Venkat } 910897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj } 911897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj 912897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj private void refresh(final String[] databaseUris) { 91362f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat synchronized (mMediaSets) { 91462f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat if (mDataSource != null) { 91562dd11281ef6e12049dd6798b184157e9583d7d4Venkat synchronized (mRequestedRefresh) { 91662dd11281ef6e12049dd6798b184157e9583d7d4Venkat mRequestedRefresh.add(databaseUris); 91762dd11281ef6e12049dd6798b184157e9583d7d4Venkat } 91862f6a6a2e299c0706bfd0d4a0bca0ef1b10d3f37Venkat } 9195e0474e8e1942c41234eb251f948c2fbb7445b02Venkat Krishnaraj } 9205e0474e8e1942c41234eb251f948c2fbb7445b02Venkat Krishnaraj } 921897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj 922897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj public void onPause() { 923897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj final HashMap<String, ContentObserver> observers = mContentObservers; 9241b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat final int numObservers = observers.size(); 9251b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat if (numObservers > 0) { 9261b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat String[] uris = new String[numObservers]; 9271b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat final Set<String> keySet = observers.keySet(); 9281b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat if (keySet != null) { 9291b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat uris = keySet.toArray(uris); 9301b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat final int numUris = uris.length; 9311b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat final ContentResolver cr = mContext.getContentResolver(); 9321b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat for (int i = 0; i < numUris; ++i) { 9331b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat final String uri = uris[i]; 9341b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat if (uri != null) { 9351b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat final ContentObserver observer = observers.get(uri); 9361b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat cr.unregisterContentObserver(observer); 9371b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat observers.remove(uri); 9381b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat } 9391b2ccb78ad045ad14f4f18e218003bf317e7c85eVenkat } 940897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj } 941897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj } 942897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj observers.clear(); 943897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj } 944897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj 945897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj public void onResume() { 9465a626da1e8c21ee7c9e5f4d8142fc5adf7252f10Venkat final Context context = mContext; 9475a626da1e8c21ee7c9e5f4d8142fc5adf7252f10Venkat final DataSource dataSource = mDataSource; 9485a626da1e8c21ee7c9e5f4d8142fc5adf7252f10Venkat if (context == null || dataSource == null) 9495a626da1e8c21ee7c9e5f4d8142fc5adf7252f10Venkat return; 950897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj // We setup the listeners for this datasource 9515a626da1e8c21ee7c9e5f4d8142fc5adf7252f10Venkat final String[] uris = dataSource.getDatabaseUris(); 952897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj final HashMap<String, ContentObserver> observers = mContentObservers; 9535a626da1e8c21ee7c9e5f4d8142fc5adf7252f10Venkat if (context instanceof Gallery) { 9545a626da1e8c21ee7c9e5f4d8142fc5adf7252f10Venkat final Gallery gallery = (Gallery) context; 9555a626da1e8c21ee7c9e5f4d8142fc5adf7252f10Venkat final ContentResolver cr = context.getContentResolver(); 956897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj if (uris != null) { 957897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj final int numUris = uris.length; 958897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj for (int i = 0; i < numUris; ++i) { 959897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj final String uri = uris[i]; 960897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj final ContentObserver presentObserver = observers.get(uri); 961897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj if (presentObserver == null) { 9625a626da1e8c21ee7c9e5f4d8142fc5adf7252f10Venkat final Handler handler = App.get(context).getHandler(); 963897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj final ContentObserver observer = new ContentObserver(handler) { 964897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj public void onChange(boolean selfChange) { 965897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj if (!mWaitingForMediaScanner) { 966897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj MediaFeed.this.refresh(new String[] { uri }); 967897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj } 968897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj } 969897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj }; 97062dd11281ef6e12049dd6798b184157e9583d7d4Venkat cr.registerContentObserver(Uri.parse(uri), true, observer); 971897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj observers.put(uri, observer); 972897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj } 973897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj } 974897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj } 975897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj } 976897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj refresh(); 977897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj } 978f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks} 979