1f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro/*
2f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro * Copyright (C) 2011 The Android Open Source Project
3f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro *
4f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro * Licensed under the Apache License, Version 2.0 (the "License");
5f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro * you may not use this file except in compliance with the License.
6f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro * You may obtain a copy of the License at
7f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro *
8f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro *      http://www.apache.org/licenses/LICENSE-2.0
9f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro *
10f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro * Unless required by applicable law or agreed to in writing, software
11f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro * distributed under the License is distributed on an "AS IS" BASIS,
12f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro * See the License for the specific language governing permissions and
14f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro * limitations under the License.
15f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro */
16f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
17f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoropackage com.android.providers.contacts;
18f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
191422d81607669bdc2ebd51c1b71f6640293d85cdMakoto Onukiimport static com.android.providers.contacts.ContactsActor.PACKAGE_GREY;
20f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
21f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport android.database.Cursor;
22f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport android.database.sqlite.SQLiteDatabase;
23f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport android.provider.ContactsContract;
24f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport android.provider.ContactsContract.PhotoFiles;
25583b1364980fd46a5012825886af3160752ff19cMakoto Onukiimport android.test.suitebuilder.annotation.MediumTest;
26f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
271422d81607669bdc2ebd51c1b71f6640293d85cdMakoto Onukiimport com.android.providers.contacts.ContactsDatabaseHelper.Tables;
281422d81607669bdc2ebd51c1b71f6640293d85cdMakoto Onukiimport com.android.providers.contacts.tests.R;
291422d81607669bdc2ebd51c1b71f6640293d85cdMakoto Onuki
30f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport java.io.File;
31f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport java.io.FileInputStream;
32f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport java.io.IOException;
33f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport java.util.HashMap;
34f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport java.util.HashSet;
35f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport java.util.Map;
36f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoroimport java.util.Set;
37f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
38f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro/**
39f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro * Tests for {@link PhotoStore}.
40f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro */
41583b1364980fd46a5012825886af3160752ff19cMakoto Onuki@MediumTest
42f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoropublic class PhotoStoreTest extends PhotoLoadingTestCase {
43f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
44f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    private ContactsActor mActor;
45f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    private SynchronousContactsProvider2 mProvider;
46f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    private SQLiteDatabase mDb;
47f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
48f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    // The object under test.
49f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    private PhotoStore mPhotoStore;
50f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
51f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    @Override
52f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    protected void setUp() throws Exception {
53f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        super.setUp();
54f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        mActor = new ContactsActor(getContext(), PACKAGE_GREY, SynchronousContactsProvider2.class,
55f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                ContactsContract.AUTHORITY);
56f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        mProvider = ((SynchronousContactsProvider2) mActor.provider);
57f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        mPhotoStore = mProvider.getPhotoStore();
58f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        mProvider.wipeData();
59f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        mDb = mProvider.getDatabaseHelper(getContext()).getReadableDatabase();
60f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
61f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
62f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    @Override
63f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    protected void tearDown() throws Exception {
64f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        super.tearDown();
65f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        mPhotoStore.clear();
66f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
67f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
68f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testStoreThumbnailPhoto() throws IOException {
69f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        byte[] photo = loadPhotoFromResource(R.drawable.earth_small, PhotoSize.ORIGINAL);
70f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
71f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Since the photo is already thumbnail-sized, no file will be stored.
72c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        assertEquals(0, mPhotoStore.insert(newPhotoProcessor(photo, false)));
73f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
74f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
75645d517ecec398862b33a5ae1bfa0766467eb4c2Daniel Lehmann    public void testStore200Photo() throws IOException {
76645d517ecec398862b33a5ae1bfa0766467eb4c2Daniel Lehmann        // As 200 is below the full photo size, we don't want to see it upscaled
77b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann        runStorageTestForResource(R.drawable.earth_200, 200, 200);
78b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann    }
79b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann
80b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann    public void testStoreNonSquare300x200Photo() throws IOException {
81b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann        // The longer side should be downscaled to the target size
821422d81607669bdc2ebd51c1b71f6640293d85cdMakoto Onuki        runStorageTestForResource(R.drawable.earth_300x200, 256, 170);
83b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann    }
84b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann
85b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann    public void testStoreNonSquare300x200PhotoWithCrop() throws IOException {
86b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann        // As 300x200 is below the full photo size, we don't want to see it upscaled
87b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann        // This one is not square, so we expect the longer side to be cropped
88b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann        runStorageTestForResourceWithCrop(R.drawable.earth_300x200, 200, 200);
89b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann    }
90b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann
91b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann    public void testStoreNonSquare600x400PhotoWithCrop() throws IOException {
92b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann        // As 600x400 is above the full photo size, we expect the picture to be cropped and then
93b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann        // scaled
94b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann        runStorageTestForResourceWithCrop(R.drawable.earth_600x400, 256, 256);
95645d517ecec398862b33a5ae1bfa0766467eb4c2Daniel Lehmann    }
96645d517ecec398862b33a5ae1bfa0766467eb4c2Daniel Lehmann
97f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testStoreMediumPhoto() throws IOException {
98c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        // Source Image is 256x256
99b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann        runStorageTestForResource(R.drawable.earth_normal, 256, 256);
100f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
101f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
102f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testStoreLargePhoto() throws IOException {
103c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        // Source image is 512x512
104b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann        runStorageTestForResource(R.drawable.earth_large, 256, 256);
105f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
106f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
107f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testStoreHugePhoto() throws IOException {
108c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        // Source image is 1024x1024
109b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann        runStorageTestForResource(R.drawable.earth_huge, 256, 256);
110f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
111f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
112f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    /**
113f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro     * Runs the following steps:
114f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro     * - Loads the given photo resource.
115f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro     * - Inserts it into the photo store.
116f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro     * - Checks that the photo has a photo file ID.
117f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro     * - Loads the expected display photo for the resource.
118f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro     * - Gets the photo entry from the photo store.
119f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro     * - Loads the photo entry's file content from disk.
120f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro     * - Compares the expected photo content to the disk content.
121f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro     * - Queries the contacts provider for the photo file entry, checks for its
122f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro     *   existence, and matches it up against the expected metadata.
123f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro     * - Checks that the total storage taken up by the photo store is equal to
124f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro     *   the size of the photo.
125f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro     * @param resourceId The resource ID of the photo file to test.
126f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro     */
127b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann    public void runStorageTestForResource(int resourceId, int expectedWidth,
128b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann            int expectedHeight) throws IOException {
129f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        byte[] photo = loadPhotoFromResource(resourceId, PhotoSize.ORIGINAL);
130c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        long photoFileId = mPhotoStore.insert(newPhotoProcessor(photo, false));
131f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertTrue(photoFileId != 0);
132f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
133f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        File storedFile = new File(mPhotoStore.get(photoFileId).path);
134f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertTrue(storedFile.exists());
135c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        byte[] actualStoredVersion = readInputStreamFully(new FileInputStream(storedFile));
136c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki
137c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        byte[] expectedStoredVersion = loadPhotoFromResource(resourceId, PhotoSize.DISPLAY_PHOTO);
138c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki
13987426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki        EvenMoreAsserts.assertImageRawData(getContext(),
14087426833d4c2c626e032f5d0b84a08b58024daf6Makoto Onuki                expectedStoredVersion, actualStoredVersion);
141f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
142f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Cursor c = mDb.query(Tables.PHOTO_FILES,
143b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann                new String[]{PhotoFiles.WIDTH, PhotoFiles.HEIGHT, PhotoFiles.FILESIZE},
144f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                PhotoFiles._ID + "=?", new String[]{String.valueOf(photoFileId)}, null, null, null);
145f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        try {
146f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro            assertEquals(1, c.getCount());
147f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro            c.moveToFirst();
148b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann            assertEquals(expectedWidth + "/" + expectedHeight, c.getInt(0) + "/" + c.getInt(1));
149f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro            assertEquals(expectedStoredVersion.length, c.getInt(2));
150f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        } finally {
151f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro            c.close();
152f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        }
153f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
154f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(expectedStoredVersion.length, mPhotoStore.getTotalSize());
155f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
156f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
157b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann    public void runStorageTestForResourceWithCrop(int resourceId, int expectedWidth,
158b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann            int expectedHeight) throws IOException {
159b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann        byte[] photo = loadPhotoFromResource(resourceId, PhotoSize.ORIGINAL);
160c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        long photoFileId = mPhotoStore.insert(newPhotoProcessor(photo, true));
161b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann        assertTrue(photoFileId != 0);
162b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann
163b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann        Cursor c = mDb.query(Tables.PHOTO_FILES,
164b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann                new String[]{PhotoFiles.HEIGHT, PhotoFiles.WIDTH, PhotoFiles.FILESIZE},
165b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann                PhotoFiles._ID + "=?", new String[]{String.valueOf(photoFileId)}, null, null, null);
166b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann        try {
167b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann            assertEquals(1, c.getCount());
168b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann            c.moveToFirst();
169b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann            assertEquals(expectedWidth + "/" + expectedHeight, c.getInt(0) + "/" + c.getInt(1));
170b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann        } finally {
171b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann            c.close();
172b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann        }
173b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann    }
174b0208fcd1c296f3eb2b8dfaa55e4fb4972b3d198Daniel Lehmann
175f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testRemoveEntry() throws IOException {
176f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        byte[] photo = loadPhotoFromResource(R.drawable.earth_normal, PhotoSize.ORIGINAL);
177c23a30e0510cf56d1dafddc79d1ab99ae9297a3fMakoto Onuki        long photoFileId = mPhotoStore.insert(newPhotoProcessor(photo, false));
178f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        PhotoStore.Entry entry = mPhotoStore.get(photoFileId);
179f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertTrue(new File(entry.path).exists());
180f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
181f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        mPhotoStore.remove(photoFileId);
182f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
183f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the file has been deleted.
184f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(new File(entry.path).exists());
185f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
186f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the database record has also been removed.
187f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Cursor c = mDb.query(Tables.PHOTO_FILES, new String[]{PhotoFiles._ID},
188f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                PhotoFiles._ID + "=?", new String[]{String.valueOf(photoFileId)}, null, null, null);
189f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        try {
190f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro            assertEquals(0, c.getCount());
191f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        } finally {
192f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro            c.close();
193f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        }
194f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
195f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
196f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    public void testCleanup() throws IOException {
197f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Load some photos into the store.
198f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Set<Long> photoFileIds = new HashSet<Long>();
199f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Map<Integer, Long> resourceIdToPhotoMap = new HashMap<Integer, Long>();
200f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        int[] resourceIds = new int[] {
201f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                R.drawable.earth_normal, R.drawable.earth_large, R.drawable.earth_huge
202f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        };
203f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        for (int resourceId : resourceIds) {
204f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro            long photoFileId = mPhotoStore.insert(
205f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                    new PhotoProcessor(loadPhotoFromResource(resourceId, PhotoSize.ORIGINAL),
206f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                            256, 96));
207f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro            resourceIdToPhotoMap.put(resourceId, photoFileId);
208f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro            photoFileIds.add(photoFileId);
209f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        }
210f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertFalse(photoFileIds.contains(0L));
211f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(3, photoFileIds.size());
212f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
213f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Run cleanup with the indication that only the large and huge photos are in use, along
214f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // with a bogus photo file ID that isn't in the photo store.
21549ed71913609193a00059df944f6259e9397b0bdMakoto Onuki        long bogusPhotoFileId = 123456789;
216f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Set<Long> photoFileIdsInUse = new HashSet<Long>();
217f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        photoFileIdsInUse.add(resourceIdToPhotoMap.get(R.drawable.earth_large));
218f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        photoFileIdsInUse.add(resourceIdToPhotoMap.get(R.drawable.earth_huge));
219f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        photoFileIdsInUse.add(bogusPhotoFileId);
220f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
221f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Set<Long> photoIdsToCleanup = mPhotoStore.cleanup(photoFileIdsInUse);
222f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
223f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // The set of photo IDs to clean up should consist of the bogus photo file ID.
224f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertEquals(1, photoIdsToCleanup.size());
225f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertTrue(photoIdsToCleanup.contains(bogusPhotoFileId));
226f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
227f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // The entry for the normal-sized photo should have been cleaned up, since it isn't being
228f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // used.
229f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        long normalPhotoId = resourceIdToPhotoMap.get(R.drawable.earth_normal);
230f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        assertNull(mPhotoStore.get(normalPhotoId));
231f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro
232f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        // Check that the database record has also been removed.
233f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        Cursor c = mDb.query(Tables.PHOTO_FILES, new String[]{PhotoFiles._ID},
234f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                PhotoFiles._ID + "=?", new String[]{String.valueOf(normalPhotoId)},
235f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro                null, null, null);
236f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        try {
237f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro            assertEquals(0, c.getCount());
238f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        } finally {
239f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro            c.close();
240f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro        }
241f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro    }
242f547fd54d7933e1c03af4a8dc10560c71c38f6b8Dave Santoro}
243