1f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin/*
2f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Copyright (C) 2010 The Android Open Source Project
3f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
4f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Licensed under the Apache License, Version 2.0 (the "License");
5f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * you may not use this file except in compliance with the License.
6f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * You may obtain a copy of the License at
7f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
8f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *      http://www.apache.org/licenses/LICENSE-2.0
9f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin *
10f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * Unless required by applicable law or agreed to in writing, software
11f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * distributed under the License is distributed on an "AS IS" BASIS,
12f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * See the License for the specific language governing permissions and
14f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin * limitations under the License.
15f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin */
16f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
17f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpackage com.android.gallery3d.data;
18f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
19f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.content.ContentProvider;
20f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.content.ContentResolver;
21f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.database.Cursor;
22f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.database.sqlite.SQLiteDatabase;
23f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.database.sqlite.SQLiteQueryBuilder;
24f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.net.Uri;
25f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.os.Looper;
26f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.test.AndroidTestCase;
27f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.test.mock.MockContentProvider;
28f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.test.mock.MockContentResolver;
29f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.test.suitebuilder.annotation.MediumTest;
30f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport android.util.Log;
31f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
32f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.util.concurrent.CountDownLatch;
33f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linimport java.util.concurrent.TimeUnit;
34f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
35f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linpublic class LocalDataTest extends AndroidTestCase {
36f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @SuppressWarnings("unused")
37f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final String TAG = "LocalDataTest";
38f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final long DEFAULT_TIMEOUT = 1000; // one second
39f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
40f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @MediumTest
41f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public void testLocalAlbum() throws Exception {
42f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        new TestZeroImage().run();
43f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        new TestOneImage().run();
44f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        new TestMoreImages().run();
45f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        new TestZeroVideo().run();
46f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        new TestOneVideo().run();
47f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        new TestMoreVideos().run();
48f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        new TestDeleteOneImage().run();
49f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        new TestDeleteOneAlbum().run();
50f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
51f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
52f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    abstract class TestLocalAlbumBase {
53f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        private boolean mIsImage;
54f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        protected GalleryAppStub mApp;
55f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        protected LocalAlbumSet mAlbumSet;
56f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
57f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        TestLocalAlbumBase(boolean isImage) {
58f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mIsImage = isImage;
59f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
60f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
61f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public void run() throws Exception {
62f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            SQLiteDatabase db = SQLiteDatabase.create(null);
63f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            prepareData(db);
64f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mApp = newGalleryContext(db, Looper.getMainLooper());
65f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            Path.clearAll();
66f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            Path path = Path.fromString(
67f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    mIsImage ? "/local/image" : "/local/video");
68f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mAlbumSet = new LocalAlbumSet(path, mApp);
69f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mAlbumSet.reload();
70f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            verifyResult();
71f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
72f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
73f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        abstract void prepareData(SQLiteDatabase db);
74f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        abstract void verifyResult() throws Exception;
75f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
76f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
77f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    abstract class TestLocalImageAlbum extends TestLocalAlbumBase {
78f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        TestLocalImageAlbum() {
79f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            super(true);
80f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
81f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
82f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
83f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    abstract class TestLocalVideoAlbum extends TestLocalAlbumBase {
84f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        TestLocalVideoAlbum() {
85f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            super(false);
86f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
87f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
88f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
89f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    class TestZeroImage extends TestLocalImageAlbum {
90f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        @Override
91f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public void prepareData(SQLiteDatabase db) {
92f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            createImageTable(db);
93f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
94f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
95f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        @Override
96f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public void verifyResult() {
97f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(0, mAlbumSet.getMediaItemCount());
98f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(0, mAlbumSet.getSubMediaSetCount());
99f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(0, mAlbumSet.getTotalMediaItemCount());
100f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin         }
101f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
102f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
103f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    class TestOneImage extends TestLocalImageAlbum {
104f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        @Override
105f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public void prepareData(SQLiteDatabase db) {
106f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            createImageTable(db);
107f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            insertImageData(db);
108f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
109f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
110f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        @Override
111f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public void verifyResult() {
112f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(0, mAlbumSet.getMediaItemCount());
113f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(1, mAlbumSet.getSubMediaSetCount());
114f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(1, mAlbumSet.getTotalMediaItemCount());
115f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            MediaSet sub = mAlbumSet.getSubMediaSet(0);
116f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(1, sub.getMediaItemCount());
117f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(0, sub.getSubMediaSetCount());
118f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            LocalMediaItem item = (LocalMediaItem) sub.getMediaItem(0, 1).get(0);
119f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(1, item.id);
120f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals("IMG_0072", item.caption);
121f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals("image/jpeg", item.mimeType);
122f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(12.0, item.latitude);
123f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(34.0, item.longitude);
124f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(0xD000, item.dateTakenInMs);
125f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(1280395646L, item.dateAddedInSec);
126f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(1275934796L, item.dateModifiedInSec);
127f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals("/mnt/sdcard/DCIM/100CANON/IMG_0072.JPG", item.filePath);
128f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
129f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
130f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
131f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    class TestMoreImages extends TestLocalImageAlbum {
132f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        @Override
133f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public void prepareData(SQLiteDatabase db) {
134f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            // Albums are sorted by names, and items are sorted by
135f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            // dateTimeTaken (descending)
136f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            createImageTable(db);
137f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            // bucket 0xB000
138f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            insertImageData(db, 1000, 0xB000, "second");  // id 1
139f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            insertImageData(db, 2000, 0xB000, "second");  // id 2
140f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            // bucket 0xB001
141f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            insertImageData(db, 3000, 0xB001, "first");   // id 3
142f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
143f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
144f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        @Override
145f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public void verifyResult() {
146f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(0, mAlbumSet.getMediaItemCount());
147f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(2, mAlbumSet.getSubMediaSetCount());
148f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(3, mAlbumSet.getTotalMediaItemCount());
149f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
150f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            MediaSet first = mAlbumSet.getSubMediaSet(0);
151f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(1, first.getMediaItemCount());
152f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            LocalMediaItem item = (LocalMediaItem) first.getMediaItem(0, 1).get(0);
153f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(3, item.id);
154f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(3000L, item.dateTakenInMs);
155f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
156f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            MediaSet second = mAlbumSet.getSubMediaSet(1);
157f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(2, second.getMediaItemCount());
158f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            item = (LocalMediaItem) second.getMediaItem(0, 1).get(0);
159f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(2, item.id);
160f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(2000L, item.dateTakenInMs);
161f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            item = (LocalMediaItem) second.getMediaItem(1, 1).get(0);
162f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(1, item.id);
163f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(1000L, item.dateTakenInMs);
164f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
165f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
166f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
167f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    class OnContentDirtyLatch implements ContentListener {
168f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        private CountDownLatch mLatch = new CountDownLatch(1);
169f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
170f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public void onContentDirty() {
171f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mLatch.countDown();
172f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
173f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
174f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public boolean isOnContentDirtyBeCalled(long timeout)
175f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                throws InterruptedException {
176f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            return mLatch.await(timeout, TimeUnit.MILLISECONDS);
177f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
178f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
179f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
180f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    class TestDeleteOneAlbum extends TestLocalImageAlbum {
181f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        @Override
182f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public void prepareData(SQLiteDatabase db) {
183f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            // Albums are sorted by names, and items are sorted by
184f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            // dateTimeTaken (descending)
185f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            createImageTable(db);
186f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            // bucket 0xB000
187f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            insertImageData(db, 1000, 0xB000, "second");  // id 1
188f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            insertImageData(db, 2000, 0xB000, "second");  // id 2
189f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            // bucket 0xB001
190f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            insertImageData(db, 3000, 0xB001, "first");   // id 3
191f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
192f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
193f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        @Override
194f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public void verifyResult() throws Exception {
195f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            MediaSet sub = mAlbumSet.getSubMediaSet(1);  // "second"
196f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(2, mAlbumSet.getSubMediaSetCount());
197f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            OnContentDirtyLatch latch = new OnContentDirtyLatch();
198f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            sub.addContentListener(latch);
199f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertTrue((sub.getSupportedOperations() & MediaSet.SUPPORT_DELETE) != 0);
200f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            sub.delete();
201f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mAlbumSet.fakeChange();
202f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            latch.isOnContentDirtyBeCalled(DEFAULT_TIMEOUT);
203f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            mAlbumSet.reload();
204f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(1, mAlbumSet.getSubMediaSetCount());
205f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
206f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
207f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
208f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    class TestDeleteOneImage extends TestLocalImageAlbum {
209f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
210f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        @Override
211f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public void prepareData(SQLiteDatabase db) {
212f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            createImageTable(db);
213f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            insertImageData(db);
214f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
215f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
216f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        @Override
217f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public void verifyResult() {
218f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            MediaSet sub = mAlbumSet.getSubMediaSet(0);
219f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            LocalMediaItem item = (LocalMediaItem) sub.getMediaItem(0, 1).get(0);
220f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(1, sub.getMediaItemCount());
221f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertTrue((sub.getSupportedOperations() & MediaSet.SUPPORT_DELETE) != 0);
222f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            sub.delete();
223f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            sub.reload();
224f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(0, sub.getMediaItemCount());
225f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
226f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
227f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
228f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    static void createImageTable(SQLiteDatabase db) {
229f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        // This is copied from MediaProvider
230f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        db.execSQL("CREATE TABLE IF NOT EXISTS images (" +
231f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                "_id INTEGER PRIMARY KEY," +
232f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                "_data TEXT," +
233f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                "_size INTEGER," +
234f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                "_display_name TEXT," +
235f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                "mime_type TEXT," +
236f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                "title TEXT," +
237f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                "date_added INTEGER," +
238f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                "date_modified INTEGER," +
239f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                "description TEXT," +
240f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                "picasa_id TEXT," +
241f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                "isprivate INTEGER," +
242f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                "latitude DOUBLE," +
243f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                "longitude DOUBLE," +
244f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                "datetaken INTEGER," +
245f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                "orientation INTEGER," +
246f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                "mini_thumb_magic INTEGER," +
247f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                "bucket_id TEXT," +
248f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                "bucket_display_name TEXT" +
249f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin               ");");
250f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
251f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
252f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    static void insertImageData(SQLiteDatabase db) {
253f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        insertImageData(db, 0xD000, 0xB000, "name");
254f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
255f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
256f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    static void insertImageData(SQLiteDatabase db, long dateTaken,
257f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            int bucketId, String bucketName) {
258f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        db.execSQL("INSERT INTO images (title, mime_type, latitude, longitude, "
259f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                + "datetaken, date_added, date_modified, bucket_id, "
260f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                + "bucket_display_name, _data, orientation) "
261f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                + "VALUES ('IMG_0072', 'image/jpeg', 12, 34, "
262f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                + dateTaken + ", 1280395646, 1275934796, '" + bucketId + "', "
263f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                + "'" + bucketName + "', "
264f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                + "'/mnt/sdcard/DCIM/100CANON/IMG_0072.JPG', 0)");
265f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
266f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
267f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    class TestZeroVideo extends TestLocalVideoAlbum {
268f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        @Override
269f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public void prepareData(SQLiteDatabase db) {
270f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            createVideoTable(db);
271f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
272f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
273f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        @Override
274f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public void verifyResult() {
275f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(0, mAlbumSet.getMediaItemCount());
276f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(0, mAlbumSet.getSubMediaSetCount());
277f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(0, mAlbumSet.getTotalMediaItemCount());
278f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
279f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
280f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
281f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    class TestOneVideo extends TestLocalVideoAlbum {
282f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        @Override
283f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public void prepareData(SQLiteDatabase db) {
284f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            createVideoTable(db);
285f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            insertVideoData(db);
286f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
287f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
288f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        @Override
289f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public void verifyResult() {
290f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(0, mAlbumSet.getMediaItemCount());
291f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(1, mAlbumSet.getSubMediaSetCount());
292f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(1, mAlbumSet.getTotalMediaItemCount());
293f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            MediaSet sub = mAlbumSet.getSubMediaSet(0);
294f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(1, sub.getMediaItemCount());
295f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(0, sub.getSubMediaSetCount());
296f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            LocalMediaItem item = (LocalMediaItem) sub.getMediaItem(0, 1).get(0);
297f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(1, item.id);
298f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals("VID_20100811_051413", item.caption);
299f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals("video/mp4", item.mimeType);
300f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(11.0, item.latitude);
301f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(22.0, item.longitude);
302f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(0xD000, item.dateTakenInMs);
303f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(1281503663L, item.dateAddedInSec);
304f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(1281503662L, item.dateModifiedInSec);
305f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals("/mnt/sdcard/DCIM/Camera/VID_20100811_051413.3gp",
306f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                    item.filePath);
307f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
308f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
309f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
310f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    class TestMoreVideos extends TestLocalVideoAlbum {
311f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        @Override
312f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public void prepareData(SQLiteDatabase db) {
313f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            // Albums are sorted by names, and items are sorted by
314f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            // dateTimeTaken (descending)
315f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            createVideoTable(db);
316f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            // bucket 0xB002
317f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            insertVideoData(db, 1000, 0xB000, "second");  // id 1
318f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            insertVideoData(db, 2000, 0xB000, "second");  // id 2
319f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            // bucket 0xB001
320f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            insertVideoData(db, 3000, 0xB001, "first");   // id 3
321f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
322f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
323f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        @Override
324f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        public void verifyResult() {
325f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(0, mAlbumSet.getMediaItemCount());
326f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(2, mAlbumSet.getSubMediaSetCount());
327f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(3, mAlbumSet.getTotalMediaItemCount());
328f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
329f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            MediaSet first = mAlbumSet.getSubMediaSet(0);
330f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(1, first.getMediaItemCount());
331f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            LocalMediaItem item = (LocalMediaItem) first.getMediaItem(0, 1).get(0);
332f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(3, item.id);
333f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(3000L, item.dateTakenInMs);
334f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
335f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            MediaSet second = mAlbumSet.getSubMediaSet(1);
336f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(2, second.getMediaItemCount());
337f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            item = (LocalMediaItem) second.getMediaItem(0, 1).get(0);
338f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(2, item.id);
339f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(2000L, item.dateTakenInMs);
340f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            item = (LocalMediaItem) second.getMediaItem(1, 1).get(0);
341f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(1, item.id);
342f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            assertEquals(1000L, item.dateTakenInMs);
343f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
344f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
345f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
346f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    static void createVideoTable(SQLiteDatabase db) {
347f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        db.execSQL("CREATE TABLE IF NOT EXISTS video (" +
348f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                   "_id INTEGER PRIMARY KEY," +
349f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                   "_data TEXT NOT NULL," +
350f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                   "_display_name TEXT," +
351f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                   "_size INTEGER," +
352f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                   "mime_type TEXT," +
353f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                   "date_added INTEGER," +
354f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                   "date_modified INTEGER," +
355f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                   "title TEXT," +
356f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                   "duration INTEGER," +
357f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                   "artist TEXT," +
358f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                   "album TEXT," +
359f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                   "resolution TEXT," +
360f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                   "description TEXT," +
361f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                   "isprivate INTEGER," +   // for YouTube videos
362f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                   "tags TEXT," +           // for YouTube videos
363f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                   "category TEXT," +       // for YouTube videos
364f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                   "language TEXT," +       // for YouTube videos
365f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                   "mini_thumb_data TEXT," +
366f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                   "latitude DOUBLE," +
367f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                   "longitude DOUBLE," +
368f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                   "datetaken INTEGER," +
369f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                   "mini_thumb_magic INTEGER" +
370f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                   ");");
371f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        db.execSQL("ALTER TABLE video ADD COLUMN bucket_id TEXT;");
372f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        db.execSQL("ALTER TABLE video ADD COLUMN bucket_display_name TEXT");
373f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
374f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
375f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    static void insertVideoData(SQLiteDatabase db) {
376f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        insertVideoData(db, 0xD000, 0xB000, "name");
377f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
378f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
379f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    static void insertVideoData(SQLiteDatabase db, long dateTaken,
380f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            int bucketId, String bucketName) {
381f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        db.execSQL("INSERT INTO video (title, mime_type, latitude, longitude, "
382f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                + "datetaken, date_added, date_modified, bucket_id, "
383f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                + "bucket_display_name, _data, duration) "
384f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                + "VALUES ('VID_20100811_051413', 'video/mp4', 11, 22, "
385f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                + dateTaken + ", 1281503663, 1281503662, '" + bucketId + "', "
386f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                + "'" + bucketName + "', "
387f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                + "'/mnt/sdcard/DCIM/Camera/VID_20100811_051413.3gp', 2964)");
388f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
389f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
390f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    static GalleryAppStub newGalleryContext(SQLiteDatabase db, Looper mainLooper) {
391f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        MockContentResolver cr = new MockContentResolver();
392f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        ContentProvider cp = new DbContentProvider(db, cr);
393f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        cr.addProvider("media", cp);
394f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return new GalleryAppMock(null, cr, mainLooper);
395f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
396f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin}
397f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
398f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Linclass DbContentProvider extends MockContentProvider {
399f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private static final String TAG = "DbContentProvider";
400f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private SQLiteDatabase mDatabase;
401f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private ContentResolver mContentResolver;
402f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
403f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    DbContentProvider(SQLiteDatabase db, ContentResolver cr) {
404f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mDatabase = db;
405f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mContentResolver = cr;
406f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
407f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
408f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
409f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public Cursor query(Uri uri, String[] projection,
410f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            String selection, String[] selectionArgs, String sortOrder) {
411f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        // This is a simplified version extracted from MediaProvider.
412f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
413f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        String tableName = getTableName(uri);
414f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (tableName == null) return null;
415f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
416f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
417f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        qb.setTables(tableName);
418f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
419f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        String groupBy = null;
420f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        String limit = uri.getQueryParameter("limit");
421f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
422f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (uri.getQueryParameter("distinct") != null) {
423f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            qb.setDistinct(true);
424f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
425f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
426f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Log.v(TAG, "query = " + qb.buildQuery(projection, selection,
427f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                selectionArgs, groupBy, null, sortOrder, limit));
428f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
429f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (selectionArgs != null) {
430f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            for (String s : selectionArgs) {
431f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                Log.v(TAG, "  selectionArgs = " + s);
432f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            }
433f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
434f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
435f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Cursor c = qb.query(mDatabase, projection, selection,
436f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin                selectionArgs, groupBy, null, sortOrder, limit);
437f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
438f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return c;
439f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
440f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
441f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    @Override
442f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    public int delete(Uri uri, String whereClause, String[] whereArgs) {
443f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        Log.v(TAG, "delete " + uri + "," + whereClause + "," + whereArgs[0]);
444f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        String tableName = getTableName(uri);
445f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (tableName == null) return 0;
446f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        int count = mDatabase.delete(tableName, whereClause, whereArgs);
447f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        mContentResolver.notifyChange(uri, null);
448f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        return count;
449f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
450f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin
451f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    private String getTableName(Uri uri) {
452f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        String uriString = uri.toString();
453f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        if (uriString.startsWith("content://media/external/images/media")) {
454f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            return "images";
455f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } else if (uriString.startsWith("content://media/external/video/media")) {
456f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            return "video";
457f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        } else {
458f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin            return null;
459f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin        }
460f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin    }
461f9a0a4306d589b4a4e20554fed512a603426bfa1Owen Lin}
462