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