MediaFeed.java revision 897ad622181117e8acbdeae2ff0afece68f1332c
1f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparkspackage com.cooliris.media;
2f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
3f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport java.util.ArrayList;
4f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport java.util.HashMap;
5897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnarajimport java.util.HashSet;
6f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
7897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnarajimport android.content.ContentResolver;
8f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.content.Context;
9897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnarajimport android.database.ContentObserver;
10f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.view.Gravity;
11f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.widget.Toast;
12897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnarajimport android.net.Uri;
13897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnarajimport android.os.Handler;
14f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport android.os.Process;
15f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
1629dcedb79b7eb9e3d65adc5d2ea95c1dd5c01df9Chih-Chung Changimport com.cooliris.app.Res;
17f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparksimport com.cooliris.media.MediaClustering.Cluster;
18f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
19f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparkspublic final class MediaFeed implements Runnable {
20f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public static final int OPERATION_DELETE = 0;
21f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public static final int OPERATION_ROTATE = 1;
22f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public static final int OPERATION_CROP = 2;
23f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
24f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private static final int NUM_ITEMS_LOOKAHEAD = 60;
25f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
26f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private IndexRange mVisibleRange = new IndexRange();
27f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private IndexRange mBufferedRange = new IndexRange();
28f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private ArrayList<MediaSet> mMediaSets = new ArrayList<MediaSet>();
29f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private Listener mListener;
30f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private DataSource mDataSource;
31f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private boolean mListenerNeedsUpdate = false;
32d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks    private boolean mMediaFeedNeedsToRun = false;
33f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private MediaSet mSingleWrapper = new MediaSet();
34f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private boolean mInClusteringMode = false;
35f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private HashMap<MediaSet, MediaClustering> mClusterSets = new HashMap<MediaSet, MediaClustering>(32);
36f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private int mExpandedMediaSetIndex = Shared.INVALID;
37f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private MediaFilter mMediaFilter;
38f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private MediaSet mMediaFilteredSet;
39f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private Context mContext;
40f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private Thread mDataSourceThread = null;
41f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private Thread mAlbumSourceThread = null;
42f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private boolean mListenerNeedsLayout;
43f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private boolean mWaitingForMediaScanner;
44f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private boolean mSingleImageMode;
45f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private boolean mLoading;
46897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj    private HashMap<String, ContentObserver> mContentObservers = new HashMap<String, ContentObserver>();
47f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
48f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public interface Listener {
49f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        public abstract void onFeedAboutToChange(MediaFeed feed);
50f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
51f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        public abstract void onFeedChanged(MediaFeed feed, boolean needsLayout);
52f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
53f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
54f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public MediaFeed(Context context, DataSource dataSource, Listener listener) {
55f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mContext = context;
56f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mListener = listener;
57f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mDataSource = dataSource;
58f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mSingleWrapper.setNumExpectedItems(1);
59f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mLoading = true;
60f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
61d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks
62f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public void shutdown() {
63f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (mDataSourceThread != null) {
64f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            mDataSource.shutdown();
65f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            mDataSourceThread.interrupt();
66f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            mDataSourceThread = null;
67f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
68f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (mAlbumSourceThread != null) {
69f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            mAlbumSourceThread.interrupt();
70f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            mAlbumSourceThread = null;
71f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
72f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        int numSets = mMediaSets.size();
73f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        for (int i = 0; i < numSets; ++i) {
74f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            MediaSet set = mMediaSets.get(i);
75f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            set.clear();
76f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
77f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        synchronized (mMediaSets) {
78f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            mMediaSets.clear();
79f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
80f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        int numClusters = mClusterSets.size();
81f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        for (int i = 0; i < numClusters; ++i) {
82f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            MediaClustering mc = mClusterSets.get(i);
83f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            if (mc != null) {
84f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                mc.clear();
85f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            }
86f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
87f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mClusterSets.clear();
88f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mListener = null;
89f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mDataSource = null;
90f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mSingleWrapper = null;
91f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
92f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
93f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public void setVisibleRange(int begin, int end) {
94d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks        if (begin != mVisibleRange.begin || end != mVisibleRange.end) {
95d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks            mVisibleRange.begin = begin;
96d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks            mVisibleRange.end = end;
97d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks            int numItems = 96;
98d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks            int numItemsBy2 = numItems / 2;
99d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks            int numItemsBy4 = numItems / 4;
100d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks            mBufferedRange.begin = (begin / numItemsBy2) * numItemsBy2 - numItemsBy4;
101d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks            mBufferedRange.end = mBufferedRange.begin + numItems;
102d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks            mMediaFeedNeedsToRun = true;
103d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks        }
104f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
105f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
106f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public void setFilter(MediaFilter filter) {
107f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mMediaFilter = filter;
108f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mMediaFilteredSet = null;
109f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (mListener != null) {
110f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            mListener.onFeedAboutToChange(this);
111f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
112d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks        mMediaFeedNeedsToRun = true;
113f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
114f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
115f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public void removeFilter() {
116f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mMediaFilter = null;
117f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mMediaFilteredSet = null;
118f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (mListener != null) {
119f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            mListener.onFeedAboutToChange(this);
120f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            updateListener(true);
121f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
122d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks        mMediaFeedNeedsToRun = true;
123f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
124f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
125f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public ArrayList<MediaSet> getMediaSets() {
126f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        return mMediaSets;
127f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
128f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
129d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks    public MediaSet getMediaSet(final long setId) {
130f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (setId != Shared.INVALID) {
131d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks            try {
132d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks                int mMediaSetsSize = mMediaSets.size();
133d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks                for (int i = 0; i < mMediaSetsSize; i++) {
1341b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj                    final MediaSet set = mMediaSets.get(i);
1351b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj                    if (set.mId == setId) {
1361b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj                        set.mFlagForDelete = false;
1371b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj                        return set;
138d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks                    }
139f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                }
140d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks            } catch (Exception e) {
141d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks                return null;
142f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            }
143f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
144f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        return null;
145f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
146f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
147f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public MediaSet getFilteredSet() {
148f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        return mMediaFilteredSet;
149f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
150f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
151f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public MediaSet addMediaSet(final long setId, DataSource dataSource) {
152f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        MediaSet mediaSet = new MediaSet(dataSource);
153f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mediaSet.mId = setId;
154f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mMediaSets.add(mediaSet);
155d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks        if (mDataSourceThread != null && !mDataSourceThread.isAlive()) {
156d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks            mDataSourceThread.start();
157d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks        }
158d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks        mMediaFeedNeedsToRun = true;
159f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        return mediaSet;
160f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
161f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
162f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public DataSource getDataSource() {
163f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        return mDataSource;
164f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
165f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
166f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public MediaClustering getClustering() {
167f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (mExpandedMediaSetIndex != Shared.INVALID && mExpandedMediaSetIndex < mMediaSets.size()) {
168f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            return mClusterSets.get(mMediaSets.get(mExpandedMediaSetIndex));
169f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
170f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        return null;
171f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
172f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
173f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public ArrayList<Cluster> getClustersForSet(final MediaSet set) {
174f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        ArrayList<Cluster> clusters = null;
175f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (mClusterSets != null && mClusterSets.containsKey(set)) {
176f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            MediaClustering mediaClustering = mClusterSets.get(set);
177f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            if (mediaClustering != null) {
178f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                clusters = mediaClustering.getClusters();
179f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            }
180f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
181f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        return clusters;
182f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
183f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
184f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public void addItemToMediaSet(MediaItem item, MediaSet mediaSet) {
185f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        item.mParentMediaSet = mediaSet;
186f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mediaSet.addItem(item);
187d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks        synchronized (mClusterSets) {
188f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            if (item.mClusteringState == MediaItem.NOT_CLUSTERED) {
189f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                MediaClustering clustering = mClusterSets.get(mediaSet);
190f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                if (clustering == null) {
191f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    clustering = new MediaClustering(mediaSet.isPicassaAlbum());
192f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    mClusterSets.put(mediaSet, clustering);
193f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                }
194f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                clustering.setTimeRange(mediaSet.mMaxTimestamp - mediaSet.mMinTimestamp, mediaSet.getNumExpectedItems());
195f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                clustering.addItemForClustering(item);
196f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                item.mClusteringState = MediaItem.CLUSTERED;
197f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            }
198f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
199d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks        mMediaFeedNeedsToRun = true;
200f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
201f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
202f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public void performOperation(final int operation, final ArrayList<MediaBucket> mediaBuckets, final Object data) {
203f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        int numBuckets = mediaBuckets.size();
204f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        final ArrayList<MediaBucket> copyMediaBuckets = new ArrayList<MediaBucket>(numBuckets);
205f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        for (int i = 0; i < numBuckets; ++i) {
206f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            copyMediaBuckets.add(mediaBuckets.get(i));
207f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
208f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (operation == OPERATION_DELETE && mListener != null) {
209f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            mListener.onFeedAboutToChange(this);
210f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
211f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        Thread operationThread = new Thread(new Runnable() {
212f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            public void run() {
213f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                ArrayList<MediaBucket> mediaBuckets = copyMediaBuckets;
214f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                if (operation == OPERATION_DELETE) {
215f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    int numBuckets = mediaBuckets.size();
216f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    for (int i = 0; i < numBuckets; ++i) {
217f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        MediaBucket bucket = mediaBuckets.get(i);
218f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        MediaSet set = bucket.mediaSet;
219f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        ArrayList<MediaItem> items = bucket.mediaItems;
220f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        if (set != null && items == null) {
221f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            // Remove the entire bucket.
222f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            removeMediaSet(set);
223f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        } else if (set != null && items != null) {
224f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            // We need to remove these items from the set.
225f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            int numItems = items.size();
2261bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks                            // We also need to delete the items from the
2271bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks                            // cluster.
228f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            MediaClustering clustering = mClusterSets.get(set);
229f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            for (int j = 0; j < numItems; ++j) {
230f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                MediaItem item = items.get(j);
231f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                removeItemFromMediaSet(item, set);
232f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                if (clustering != null) {
233f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                    clustering.removeItemFromClustering(item);
234f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                }
235f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            }
236f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            set.updateNumExpectedItems();
237f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            set.generateTitle(true);
238f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        }
239f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    }
240f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    updateListener(true);
241d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks                    mMediaFeedNeedsToRun = true;
242f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    if (mDataSource != null) {
243f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        mDataSource.performOperation(OPERATION_DELETE, mediaBuckets, null);
244f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    }
245f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                } else {
246f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    mDataSource.performOperation(operation, mediaBuckets, data);
247f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                }
248f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            }
249f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        });
250f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        operationThread.setName("Operation " + operation);
251f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        operationThread.start();
252f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
253f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
254f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public void removeMediaSet(MediaSet set) {
2552b04f591f758b7af03c43d90e91b939cbd515506Venkat Krishnaraj        synchronized (mMediaSets) {
2561bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks            mMediaSets.remove(set);
2572b04f591f758b7af03c43d90e91b939cbd515506Venkat Krishnaraj        }
258d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks        mMediaFeedNeedsToRun = true;
259f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
260f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
261f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private void removeItemFromMediaSet(MediaItem item, MediaSet mediaSet) {
262f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mediaSet.removeItem(item);
263d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks        synchronized (mClusterSets) {
264f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            MediaClustering clustering = mClusterSets.get(mediaSet);
265f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            if (clustering != null) {
266f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                clustering.removeItemFromClustering(item);
267f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            }
268f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
269d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks        mMediaFeedNeedsToRun = true;
270f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
271f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
272f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public void updateListener(boolean needsLayout) {
273f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mListenerNeedsUpdate = true;
274f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mListenerNeedsLayout = needsLayout;
275f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
276f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
277f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public int getNumSlots() {
278f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        int currentMediaSetIndex = mExpandedMediaSetIndex;
279f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        ArrayList<MediaSet> mediaSets = mMediaSets;
280f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        int mediaSetsSize = mediaSets.size();
281f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
282f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (mInClusteringMode == false) {
283f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            if (currentMediaSetIndex == Shared.INVALID || currentMediaSetIndex >= mediaSetsSize) {
284f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                return mediaSetsSize;
285f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            } else {
286f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                MediaSet setToUse = (mMediaFilteredSet == null) ? mediaSets.get(currentMediaSetIndex) : mMediaFilteredSet;
2875e0474e8e1942c41234eb251f948c2fbb7445b02Venkat Krishnaraj                return setToUse.getNumExpectedItems();
288f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            }
289f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        } else if (currentMediaSetIndex != Shared.INVALID && currentMediaSetIndex < mediaSetsSize) {
290f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            MediaSet set = mediaSets.get(currentMediaSetIndex);
291f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            MediaClustering clustering = mClusterSets.get(set);
292f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            if (clustering != null) {
293f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                return clustering.getClustersForDisplay().size();
294f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            }
295f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
296f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        return 0;
297f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
298f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
299f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public MediaSet getSetForSlot(int slotIndex) {
300f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (slotIndex < 0) {
301f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            return null;
302f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
303f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
304f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        ArrayList<MediaSet> mediaSets = mMediaSets;
305f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        int mediaSetsSize = mediaSets.size();
306f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        int currentMediaSetIndex = mExpandedMediaSetIndex;
307f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
308f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (mInClusteringMode == false) {
309f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            if (currentMediaSetIndex == Shared.INVALID || currentMediaSetIndex >= mediaSetsSize) {
310f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                if (slotIndex >= mediaSetsSize) {
311f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    return null;
312f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                }
313f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                return mMediaSets.get(slotIndex);
314f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            }
315f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            if (mSingleWrapper.getNumItems() == 0) {
316f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                mSingleWrapper.addItem(null);
317f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            }
318f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            MediaSet setToUse = (mMediaFilteredSet == null) ? mMediaSets.get(currentMediaSetIndex) : mMediaFilteredSet;
319f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            ArrayList<MediaItem> items = setToUse.getItems();
320f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            if (slotIndex >= setToUse.getNumItems()) {
321f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                return null;
322f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            }
323f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            mSingleWrapper.getItems().set(0, items.get(slotIndex));
324f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            return mSingleWrapper;
325f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        } else if (currentMediaSetIndex != Shared.INVALID && currentMediaSetIndex < mediaSetsSize) {
326f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            MediaSet set = mediaSets.get(currentMediaSetIndex);
327f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            MediaClustering clustering = mClusterSets.get(set);
328f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            if (clustering != null) {
329f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                ArrayList<MediaClustering.Cluster> clusters = clustering.getClustersForDisplay();
330f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                if (clusters.size() > slotIndex) {
331f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    MediaClustering.Cluster cluster = clusters.get(slotIndex);
332f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    cluster.generateCaption(mContext);
333f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    return cluster;
334f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                }
335f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            }
336f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
337f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        return null;
338f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
339f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
340f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public boolean getWaitingForMediaScanner() {
341f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        return mWaitingForMediaScanner;
342f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
343d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks
344f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public boolean isLoading() {
345f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        return mLoading;
346f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
347f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
348f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public void start() {
349f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        final MediaFeed feed = this;
350f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mLoading = true;
351d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks        mDataSourceThread = new Thread(this);
352d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks        mDataSourceThread.setName("MediaFeed");
353f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mAlbumSourceThread = new Thread(new Runnable() {
354f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            public void run() {
355f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                if (mContext == null)
356f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    return;
357f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
358f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                DataSource dataSource = mDataSource;
3591bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks                // We must wait while the SD card is mounted or the MediaScanner
3601bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks                // is running.
361d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks                if (dataSource != null) {
3621b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj                    loadMediaSets();
363d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks                }
364f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                mWaitingForMediaScanner = false;
365f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                while (ImageManager.isMediaScannerScanning(mContext.getContentResolver())) {
366f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    // MediaScanner is still running, wait
36788ed7e72a2a0bfdbef7f72aea2b2ddfd74961bdbVenkat Krishnaraj                    if (Thread.interrupted())
36888ed7e72a2a0bfdbef7f72aea2b2ddfd74961bdbVenkat Krishnaraj                        return;
369f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    mWaitingForMediaScanner = true;
370f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    try {
371f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        if (mContext == null)
372f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            return;
37329dcedb79b7eb9e3d65adc5d2ea95c1dd5c01df9Chih-Chung Chang                        showToast(mContext.getResources().getString(Res.string.initializing), Toast.LENGTH_LONG);
3741b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj                        if (dataSource != null) {
3751b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj                            loadMediaSets();
3761b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj                        }
3771b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj                        Thread.sleep(10000);
378f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    } catch (InterruptedException e) {
37988ed7e72a2a0bfdbef7f72aea2b2ddfd74961bdbVenkat Krishnaraj                        return;
380f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    }
381f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                }
382f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                if (mWaitingForMediaScanner) {
38329dcedb79b7eb9e3d65adc5d2ea95c1dd5c01df9Chih-Chung Chang                    showToast(mContext.getResources().getString(Res.string.loading_new), Toast.LENGTH_LONG);
384d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks                    mWaitingForMediaScanner = false;
3851b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj                    loadMediaSets();
386f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                }
387f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                mLoading = false;
388f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            }
389f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        });
390f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mAlbumSourceThread.setName("MediaSets");
391f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mAlbumSourceThread.start();
392f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
393897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj
3941b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj    private void loadMediaSets() {
3951b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj        if (mDataSource == null)
3961b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj            return;
3971b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj        final ArrayList<MediaSet> sets = mMediaSets;
3981b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj        final int numSets = sets.size();
3991b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj        for (int i = 0; i < numSets; ++i) {
4001b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj            final MediaSet set = sets.get(i);
4011b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj            set.mFlagForDelete = true;
4021b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj        }
403897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj        mDataSource.refresh(MediaFeed.this, mDataSource.getDatabaseUris());
4041b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj        mDataSource.loadMediaSets(MediaFeed.this);
4051b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj        for (int i = 0; i < numSets; ++i) {
4061b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj            final MediaSet set = sets.get(i);
4071b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj            if (set.mFlagForDelete) {
4081b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj                removeMediaSet(set);
4091b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj            }
4101b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj        }
4111b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj        updateListener(false);
4121b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj    }
413f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
414f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private void showToast(final String string, final int duration) {
415f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        showToast(string, duration, false);
416f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
417f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
418f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private void showToast(final String string, final int duration, final boolean centered) {
419d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks        if (mContext != null && !((Gallery) mContext).isPaused()) {
420f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            ((Gallery) mContext).getHandler().post(new Runnable() {
421f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                public void run() {
422f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    if (mContext != null) {
423f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        Toast toast = Toast.makeText(mContext, string, duration);
424f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        if (centered) {
425f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            toast.setGravity(Gravity.CENTER, 0, 0);
426f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        }
427f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        toast.show();
428f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    }
429f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                }
430f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            });
431f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
432f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
433f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
434f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public void run() {
435f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        DataSource dataSource = mDataSource;
436d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks        int sleepMs = 10;
437f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
438f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (dataSource != null) {
439d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks            while (!Thread.interrupted()) {
440f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                if (mListenerNeedsUpdate) {
441f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    mListenerNeedsUpdate = false;
442f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    if (mListener != null)
443f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        mListener.onFeedChanged(this, mListenerNeedsLayout);
444f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    try {
445f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        Thread.sleep(sleepMs);
446f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    } catch (InterruptedException e) {
447f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        return;
448f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    }
449f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                } else {
450f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    try {
451f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        Thread.sleep(sleepMs);
452f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    } catch (InterruptedException e) {
453f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        return;
454f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    }
455f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                }
456d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks                sleepMs = 300;
457d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks                if (!mMediaFeedNeedsToRun)
458d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks                    continue;
4594e3a0e0abe213d46ba6c653c0d118dbea32301e8Venkat Krishnaraj                if (((Gallery) mContext).isPaused())
4604e3a0e0abe213d46ba6c653c0d118dbea32301e8Venkat Krishnaraj                    continue;
461d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks                mMediaFeedNeedsToRun = false;
462f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                ArrayList<MediaSet> mediaSets = mMediaSets;
463f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                synchronized (mediaSets) {
464f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    int expandedSetIndex = mExpandedMediaSetIndex;
465f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    if (expandedSetIndex >= mMediaSets.size()) {
466f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        expandedSetIndex = Shared.INVALID;
467f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    }
468f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    if (expandedSetIndex == Shared.INVALID) {
469f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        // We purge the sets outside this visibleRange.
4702b04f591f758b7af03c43d90e91b939cbd515506Venkat Krishnaraj                        int numSets = mediaSets.size();
471f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        IndexRange visibleRange = mVisibleRange;
472f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        IndexRange bufferedRange = mBufferedRange;
473f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        boolean scanMediaSets = true;
474f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        for (int i = 0; i < numSets; ++i) {
475f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            if (i >= visibleRange.begin && i <= visibleRange.end && scanMediaSets) {
476f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                MediaSet set = mediaSets.get(i);
477f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                int numItemsLoaded = set.mNumItemsLoaded;
478f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                if (numItemsLoaded < set.getNumExpectedItems() && numItemsLoaded < 8) {
479f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                    dataSource.loadItemsForSet(this, set, numItemsLoaded, 8);
480f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                    if (set.getNumExpectedItems() == 0) {
481f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                        mediaSets.remove(set);
482f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                        break;
483f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                    }
484f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                    if (mListener != null) {
485f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                        mListener.onFeedChanged(this, false);
486f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                    }
487f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                    sleepMs = 100;
488f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                    scanMediaSets = false;
489f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                }
490d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks                                if (!set.setContainsValidItems()) {
491d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks                                    mediaSets.remove(set);
492d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks                                    if (mListener != null) {
493d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks                                        mListener.onFeedChanged(this, false);
494d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks                                    }
495d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks                                    break;
496d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks                                }
497f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            }
498f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        }
4992b04f591f758b7af03c43d90e91b939cbd515506Venkat Krishnaraj                        numSets = mediaSets.size();
500f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        for (int i = 0; i < numSets; ++i) {
501f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            MediaSet set = mediaSets.get(i);
502f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            if (i >= bufferedRange.begin && i <= bufferedRange.end) {
503f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                if (scanMediaSets) {
504f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                    int numItemsLoaded = set.mNumItemsLoaded;
505f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                    if (numItemsLoaded < set.getNumExpectedItems() && numItemsLoaded < 8) {
506f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                        dataSource.loadItemsForSet(this, set, numItemsLoaded, 8);
507f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                        if (set.getNumExpectedItems() == 0) {
508f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                            mediaSets.remove(set);
509f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                            break;
510f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                        }
511f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                        if (mListener != null) {
512f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                            mListener.onFeedChanged(this, false);
513f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                        }
514f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                        sleepMs = 100;
515f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                        scanMediaSets = false;
516f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                    }
517f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                }
518897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj                            } else if (!mListenerNeedsUpdate && (i < bufferedRange.begin || i > bufferedRange.end)) {
519f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                // Purge this set to its initial status.
520f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                MediaClustering clustering = mClusterSets.get(set);
521f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                if (clustering != null) {
522f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                    clustering.clear();
523f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                    mClusterSets.remove(set);
524f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                }
525f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                if (set.getNumItems() != 0)
526f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                    set.clear();
527f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            }
528f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        }
529f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    }
530f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    if (expandedSetIndex != Shared.INVALID) {
531f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        int numSets = mMediaSets.size();
532f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        for (int i = 0; i < numSets; ++i) {
533f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            // Purge other sets.
534f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            if (i != expandedSetIndex) {
535f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                MediaSet set = mediaSets.get(i);
536f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                MediaClustering clustering = mClusterSets.get(set);
537f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                if (clustering != null) {
538f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                    clustering.clear();
539f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                    mClusterSets.remove(set);
540f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                }
541897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj                                if (set.mNumItemsLoaded != 0)
542f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                    set.clear();
543f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            }
544f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        }
545f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        // Make sure all the items are loaded for the album.
546f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        int numItemsLoaded = mediaSets.get(expandedSetIndex).mNumItemsLoaded;
547f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        int requestedItems = mVisibleRange.end;
548f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        // requestedItems count changes in clustering mode.
549f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        if (mInClusteringMode && mClusterSets != null) {
550f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            requestedItems = 0;
551f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            MediaClustering clustering = mClusterSets.get(mediaSets.get(expandedSetIndex));
552db87908d640e17ef0946824be158d86c6e2d6836Dave Sparks                            if (clustering != null) {
553db87908d640e17ef0946824be158d86c6e2d6836Dave Sparks                                ArrayList<Cluster> clusters = clustering.getClustersForDisplay();
554db87908d640e17ef0946824be158d86c6e2d6836Dave Sparks                                int numClusters = clusters.size();
555db87908d640e17ef0946824be158d86c6e2d6836Dave Sparks                                for (int i = 0; i < numClusters; i++) {
556db87908d640e17ef0946824be158d86c6e2d6836Dave Sparks                                    requestedItems += clusters.get(i).getNumExpectedItems();
557db87908d640e17ef0946824be158d86c6e2d6836Dave Sparks                                }
558f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            }
559f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        }
560f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        MediaSet set = mediaSets.get(expandedSetIndex);
561f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        if (numItemsLoaded < set.getNumExpectedItems()) {
562897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj                            // We perform calculations for a window that gets
563897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj                            // anchored to a multiple of NUM_ITEMS_LOOKAHEAD.
564897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj                            // The start of the window is 0, x, 2x, 3x ... etc
565897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj                            // where x = NUM_ITEMS_LOOKAHEAD.
566f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            dataSource.loadItemsForSet(this, set, numItemsLoaded, (requestedItems / NUM_ITEMS_LOOKAHEAD)
567f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                    * NUM_ITEMS_LOOKAHEAD + NUM_ITEMS_LOOKAHEAD);
568f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            if (set.getNumExpectedItems() == 0) {
569f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                mediaSets.remove(set);
570f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                mListener.onFeedChanged(this, false);
571f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            }
572f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            if (numItemsLoaded != set.mNumItemsLoaded && mListener != null) {
573f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                mListener.onFeedChanged(this, false);
574f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            }
575f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        }
576f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    }
577f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    MediaFilter filter = mMediaFilter;
578f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    if (filter != null && mMediaFilteredSet == null) {
579f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        if (expandedSetIndex != Shared.INVALID) {
580f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            MediaSet set = mediaSets.get(expandedSetIndex);
581f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            ArrayList<MediaItem> items = set.getItems();
582f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            int numItems = set.getNumItems();
583f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            MediaSet filteredSet = new MediaSet();
584f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            filteredSet.setNumExpectedItems(numItems);
585f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            mMediaFilteredSet = filteredSet;
586f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            for (int i = 0; i < numItems; ++i) {
587f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                MediaItem item = items.get(i);
588f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                if (filter.pass(item)) {
589f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                    filteredSet.addItem(item);
590f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                                }
591f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            }
592f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            filteredSet.updateNumExpectedItems();
593f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                            filteredSet.generateTitle(true);
594f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        }
595f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                        updateListener(true);
596f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    }
597f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                }
598f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            }
599f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
600f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
601f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
602f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public void expandMediaSet(int mediaSetIndex) {
603f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        // We need to check if this slot can be focused or not.
604f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (mListener != null) {
605f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            mListener.onFeedAboutToChange(this);
606f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
607f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (mExpandedMediaSetIndex > 0 && mediaSetIndex == Shared.INVALID) {
608f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            // We are collapsing a previously expanded media set
6091bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks            if (mediaSetIndex < mMediaSets.size() && mExpandedMediaSetIndex >= 0 && mExpandedMediaSetIndex < mMediaSets.size()) {
610f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                MediaSet set = mMediaSets.get(mExpandedMediaSetIndex);
611f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                if (set.getNumItems() == 0) {
612f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    set.clear();
613f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                }
614f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            }
615f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
616f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mExpandedMediaSetIndex = mediaSetIndex;
617f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (mediaSetIndex < mMediaSets.size() && mediaSetIndex >= 0) {
618f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            // Notify Picasa that the user entered the album.
619f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            // MediaSet set = mMediaSets.get(mediaSetIndex);
6201bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks            // PicasaService.requestSync(mContext,
6211bb0c42b2a62f580eea4764d6a4434ffecfbf353Dave Sparks            // PicasaService.TYPE_ALBUM_PHOTOS, set.mPicasaAlbumId);
622f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
623f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        updateListener(true);
624d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks        mMediaFeedNeedsToRun = true;
625f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
626f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
627f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public boolean canExpandSet(int slotIndex) {
628f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        int mediaSetIndex = slotIndex;
629f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (mediaSetIndex < mMediaSets.size() && mediaSetIndex >= 0) {
630f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            MediaSet set = mMediaSets.get(mediaSetIndex);
631f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            if (set.getNumItems() > 0) {
632f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                MediaItem item = set.getItems().get(0);
633f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                if (item.mId == Shared.INVALID) {
634f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    return false;
635f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                }
636f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                return true;
637f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            }
638f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
639f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        return false;
640f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
641f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
642f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public boolean hasExpandedMediaSet() {
643f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        return (mExpandedMediaSetIndex != Shared.INVALID);
644f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
645f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
646f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public boolean restorePreviousClusteringState() {
647f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        boolean retVal = disableClusteringIfNecessary();
648f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (retVal) {
649f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            if (mListener != null) {
650f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                mListener.onFeedAboutToChange(this);
651f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            }
652f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            updateListener(true);
653d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks            mMediaFeedNeedsToRun = true;
654f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
655f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        return retVal;
656f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
657f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
658f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    private boolean disableClusteringIfNecessary() {
659f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (mInClusteringMode) {
660f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            // Disable clustering.
661f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            mInClusteringMode = false;
662d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks            mMediaFeedNeedsToRun = true;
663f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            return true;
664f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
665f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        return false;
666f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
667f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
668f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public boolean isClustered() {
669f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        return mInClusteringMode;
670f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
671f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
672f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public MediaSet getCurrentSet() {
673f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (mExpandedMediaSetIndex != Shared.INVALID && mExpandedMediaSetIndex < mMediaSets.size()) {
674f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            return mMediaSets.get(mExpandedMediaSetIndex);
675f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
676f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        return null;
677f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
678f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
679f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public void performClustering() {
680f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (mListener != null) {
681f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            mListener.onFeedAboutToChange(this);
682f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
683f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        MediaSet setToUse = null;
6842a6f302015b435941369d94f04f3018972558c46Venkat Krishnaraj        if (mExpandedMediaSetIndex != Shared.INVALID && mExpandedMediaSetIndex < mMediaSets.size()) {
685f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            setToUse = mMediaSets.get(mExpandedMediaSetIndex);
686f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
687f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (setToUse != null) {
688f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            MediaClustering clustering = null;
689d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks            synchronized (mClusterSets) {
690f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                // Make sure the computation is completed to the end.
691f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                clustering = mClusterSets.get(setToUse);
692f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                if (clustering != null) {
693f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    clustering.compute(null, true);
694f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                } else {
695f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                    return;
696f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                }
697f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            }
698f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            mInClusteringMode = true;
699f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            updateListener(true);
700f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
701f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
702f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
703f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public void moveSetToFront(MediaSet mediaSet) {
704f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        ArrayList<MediaSet> mediaSets = mMediaSets;
705f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        int numSets = mediaSets.size();
706f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (numSets == 0) {
707f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            mediaSets.add(mediaSet);
708f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            return;
709f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
710f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        MediaSet setToFind = mediaSets.get(0);
711f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (setToFind == mediaSet) {
712f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            return;
713f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
714f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mediaSets.set(0, mediaSet);
715f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        int indexToSwapTill = -1;
716f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        for (int i = 1; i < numSets; ++i) {
717f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            MediaSet set = mediaSets.get(i);
718f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            if (set == mediaSet) {
719f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                mediaSets.set(i, setToFind);
720f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                indexToSwapTill = i;
721f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                break;
722f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            }
723f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
724f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (indexToSwapTill != Shared.INVALID) {
725f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            for (int i = indexToSwapTill; i > 1; --i) {
726f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                MediaSet setEnd = mediaSets.get(i);
727f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                MediaSet setPrev = mediaSets.get(i - 1);
728f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                mediaSets.set(i, setPrev);
729f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks                mediaSets.set(i - 1, setEnd);
730f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            }
731f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        }
732d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks        mMediaFeedNeedsToRun = true;
733f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
734f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
735f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public MediaSet replaceMediaSet(long setId, DataSource dataSource) {
7361b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj        final MediaSet set = getMediaSet(setId);
7371b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj        set.refresh();
7381b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj        return set;
739f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
740d8a6d17db8aaef2ea06c78fe643f06601d8aec5dDave Sparks
741f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public void setSingleImageMode(boolean singleImageMode) {
742f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        mSingleImageMode = singleImageMode;
743f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
744f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
745f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public boolean isSingleImageMode() {
746f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        return mSingleImageMode;
747f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
748f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks
749f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    public MediaSet getExpandedMediaSet() {
750f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (mExpandedMediaSetIndex == Shared.INVALID)
751f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            return null;
752f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        if (mExpandedMediaSetIndex >= mMediaSets.size())
753f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks            return null;
754f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks        return mMediaSets.get(mExpandedMediaSetIndex);
755f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks    }
7565e0474e8e1942c41234eb251f948c2fbb7445b02Venkat Krishnaraj
7575e0474e8e1942c41234eb251f948c2fbb7445b02Venkat Krishnaraj    public void refresh() {
7585e0474e8e1942c41234eb251f948c2fbb7445b02Venkat Krishnaraj        if (mDataSource != null) {
759897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj            refresh(mDataSource.getDatabaseUris());
760897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj        }
761897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj    }
762897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj
763897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj    private void refresh(final String[] databaseUris) {
764897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj        if (mDataSource != null) {
765897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj            mDataSource.refresh(this, databaseUris);
7665e0474e8e1942c41234eb251f948c2fbb7445b02Venkat Krishnaraj        }
7671b329b810c628b43c86a574ec6d4ad4478f02d3cVenkat Krishnaraj        mMediaFeedNeedsToRun = true;
7685e0474e8e1942c41234eb251f948c2fbb7445b02Venkat Krishnaraj        updateListener(false);
7695e0474e8e1942c41234eb251f948c2fbb7445b02Venkat Krishnaraj    }
770897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj
771897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj    public void onPause() {
772897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj        final HashMap<String, ContentObserver> observers = mContentObservers;
773897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj        String[] uris = new String[observers.size()];
774897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj        uris = observers.keySet().toArray(uris);
775897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj        final int numUris = uris.length;
776897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj        final ContentResolver cr = mContext.getContentResolver();
777897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj        for (int i = 0; i < numUris; ++i) {
778897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj            final String uri = uris[i];
779897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj            if (uri != null) {
780897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj                final ContentObserver observer = observers.get(uri);
781897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj                cr.unregisterContentObserver(observer);
782897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj                observers.remove(uri);
783897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj            }
784897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj        }
785897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj        observers.clear();
786897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj    }
787897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj
788897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj    public void onResume() {
789897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj        // We setup the listeners for this datasource
790897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj        final String[] uris = mDataSource.getDatabaseUris();
791897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj        final HashMap<String, ContentObserver> observers = mContentObservers;
792897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj        if (mContext instanceof Gallery) {
793897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj            final Gallery gallery = (Gallery) mContext;
794897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj            final ContentResolver cr = mContext.getContentResolver();
795897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj            if (uris != null) {
796897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj                final int numUris = uris.length;
797897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj                for (int i = 0; i < numUris; ++i) {
798897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj                    final String uri = uris[i];
799897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj                    final ContentObserver presentObserver = observers.get(uri);
800897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj                    if (presentObserver == null) {
801897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj                        final Handler handler = gallery.getHandler();
802897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj                        final ContentObserver observer = new ContentObserver(handler) {
803897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj                            public void onChange(boolean selfChange) {
804897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj                                if (!mWaitingForMediaScanner) {
805897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj                                    MediaFeed.this.refresh(new String[] { uri });
806897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj                                }
807897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj                            }
808897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj                        };
809897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj                        cr.registerContentObserver(Uri.parse(uri), true, observer);
810897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj                        observers.put(uri, observer);
811897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj                    }
812897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj                }
813897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj            }
814897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj        }
815897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj        refresh();
816897ad622181117e8acbdeae2ff0afece68f1332cVenkat Krishnaraj    }
817f99dfe8549fb6c2c06c8cb7ca7d5eb33002c809eDave Sparks}
818