1 /* 2 * Copyright (C) 2016 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.documentsui; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertSame; 22 import static org.junit.Assert.assertTrue; 23 24 import android.content.ComponentCallbacks2; 25 import android.graphics.Bitmap; 26 import android.graphics.Point; 27 import android.net.Uri; 28 import android.support.test.filters.SmallTest; 29 import android.support.test.runner.AndroidJUnit4; 30 31 import com.android.documentsui.ThumbnailCache.Result; 32 import com.android.documentsui.testing.Bitmaps; 33 34 import org.junit.Before; 35 import org.junit.Test; 36 import org.junit.runner.RunWith; 37 38 @RunWith(AndroidJUnit4.class) 39 @SmallTest 40 public class ThumbnailCacheTest { 41 42 private static final Uri URI_0 = Uri.parse("content://authority/document/0"); 43 private static final Uri URI_1 = Uri.parse("content://authority/document/1"); 44 45 private static final Point SMALL_SIZE = new Point(1, 1); 46 private static final Point MID_SIZE = new Point(2, 2); 47 private static final Point LARGE_SIZE = new Point(3, 3); 48 49 private static final Bitmap SMALL_BITMAP = Bitmaps.createTestBitmap(1, 1); 50 private static final Bitmap MIDSIZE_BITMAP = Bitmaps.createTestBitmap(2, 2); 51 private static final Bitmap LARGE_BITMAP = Bitmaps.createTestBitmap(3, 3); 52 53 private static final long LAST_MODIFIED = 100; 54 55 private static final int CACHE_SIZE_LIMIT = 56 MIDSIZE_BITMAP.getByteCount() + LARGE_BITMAP.getByteCount(); 57 58 private ThumbnailCache mCache; 59 60 @Before setUp()61 public void setUp() { 62 mCache = new ThumbnailCache(CACHE_SIZE_LIMIT); 63 } 64 65 @Test testMiss()66 public void testMiss() { 67 mCache.putThumbnail(URI_0, MID_SIZE, MIDSIZE_BITMAP, LAST_MODIFIED); 68 69 Result result = mCache.getThumbnail(URI_1, MID_SIZE); 70 71 assertMiss(result); 72 } 73 74 @Test testHit_Exact()75 public void testHit_Exact() { 76 mCache.putThumbnail(URI_0, MID_SIZE, MIDSIZE_BITMAP, LAST_MODIFIED); 77 78 Result result = mCache.getThumbnail(URI_0, MID_SIZE); 79 80 assertHitExact(result); 81 assertSame(MIDSIZE_BITMAP, result.getThumbnail()); 82 } 83 84 @Test testHit_Smaller()85 public void testHit_Smaller() { 86 mCache.putThumbnail(URI_0, MID_SIZE, MIDSIZE_BITMAP, LAST_MODIFIED); 87 88 Result result = mCache.getThumbnail(URI_0, LARGE_SIZE); 89 90 assertHitSmaller(result); 91 assertSame(MIDSIZE_BITMAP, result.getThumbnail()); 92 } 93 94 @Test testHit_Larger()95 public void testHit_Larger() { 96 mCache.putThumbnail(URI_0, MID_SIZE, MIDSIZE_BITMAP, LAST_MODIFIED); 97 98 Result result = mCache.getThumbnail(URI_0, SMALL_SIZE); 99 100 assertHitLarger(result); 101 assertSame(MIDSIZE_BITMAP, result.getThumbnail()); 102 } 103 104 @Test testHit_Larger_HasBothSize()105 public void testHit_Larger_HasBothSize() { 106 mCache.putThumbnail(URI_0, LARGE_SIZE, LARGE_BITMAP, LAST_MODIFIED); 107 mCache.putThumbnail(URI_0, SMALL_SIZE, SMALL_BITMAP, LAST_MODIFIED); 108 109 Result result = mCache.getThumbnail(URI_0, MID_SIZE); 110 111 assertHitLarger(result); 112 assertSame(LARGE_BITMAP, result.getThumbnail()); 113 } 114 115 @Test testHit_Exact_MultiplePut()116 public void testHit_Exact_MultiplePut() { 117 mCache.putThumbnail(URI_0, MID_SIZE, MIDSIZE_BITMAP, LAST_MODIFIED); 118 119 Bitmap localBitmap = Bitmaps.createTestBitmap(MID_SIZE.x, MID_SIZE.y); 120 long localLastModified = LAST_MODIFIED + 100; 121 mCache.putThumbnail(URI_0, MID_SIZE, localBitmap, localLastModified); 122 123 Result result = mCache.getThumbnail(URI_0, MID_SIZE); 124 125 assertHitExact(result); 126 assertSame(localBitmap, result.getThumbnail()); 127 } 128 129 @Test testHit_EqualLastModified()130 public void testHit_EqualLastModified() { 131 mCache.putThumbnail(URI_0, MID_SIZE, MIDSIZE_BITMAP, LAST_MODIFIED); 132 133 Result result = mCache.getThumbnail(URI_0, MID_SIZE); 134 135 assertEquals(LAST_MODIFIED, result.getLastModified()); 136 } 137 138 @Test testEvictOldest_SizeExceeded()139 public void testEvictOldest_SizeExceeded() { 140 mCache.putThumbnail(URI_0, MID_SIZE, MIDSIZE_BITMAP, LAST_MODIFIED); 141 mCache.putThumbnail(URI_1, SMALL_SIZE, SMALL_BITMAP, LAST_MODIFIED); 142 mCache.putThumbnail(URI_1, LARGE_SIZE, LARGE_BITMAP, LAST_MODIFIED); 143 144 Result result = mCache.getThumbnail(URI_0, MID_SIZE); 145 146 assertMiss(result); 147 } 148 149 @Test testCacheShrink_OnTrimMemory_Moderate()150 public void testCacheShrink_OnTrimMemory_Moderate() { 151 mCache.putThumbnail(URI_0, MID_SIZE, MIDSIZE_BITMAP, LAST_MODIFIED); 152 mCache.putThumbnail(URI_0, SMALL_SIZE, SMALL_BITMAP, LAST_MODIFIED); 153 mCache.putThumbnail(URI_0, LARGE_SIZE, LARGE_BITMAP, LAST_MODIFIED); 154 155 mCache.onTrimMemory(ComponentCallbacks2.TRIM_MEMORY_MODERATE); 156 157 Result result = mCache.getThumbnail(URI_0, MID_SIZE); 158 assertMiss(result); 159 } 160 161 @Test testCacheShrink_OnTrimMemory_Background()162 public void testCacheShrink_OnTrimMemory_Background() { 163 mCache.putThumbnail(URI_0, LARGE_SIZE, LARGE_BITMAP, LAST_MODIFIED); 164 mCache.putThumbnail(URI_0, SMALL_SIZE, SMALL_BITMAP, LAST_MODIFIED); 165 166 mCache.onTrimMemory(ComponentCallbacks2.TRIM_MEMORY_BACKGROUND); 167 168 // Math here (size of each pixel omitted): 169 // Limit = midSize + largeSize = 2 * 2 + 3 * 3 = 13, so after all putThumbnail the cache is 170 // full. 171 // 172 // HalfLimit = Limit / 2 = 5. After evicting largeSize bitmap, cache size decreases to 4, 173 // which is smaller than 5. Then smallSize bitmap remains. 174 Result result = mCache.getThumbnail(URI_0, MID_SIZE); 175 assertHitSmaller(result); 176 assertSame(SMALL_BITMAP, result.getThumbnail()); 177 } 178 179 @Test testRemoveUri()180 public void testRemoveUri() { 181 mCache.putThumbnail(URI_0, MID_SIZE, MIDSIZE_BITMAP, LAST_MODIFIED); 182 mCache.putThumbnail(URI_0, SMALL_SIZE, SMALL_BITMAP, LAST_MODIFIED); 183 mCache.putThumbnail(URI_1, MID_SIZE, MIDSIZE_BITMAP, LAST_MODIFIED); 184 185 mCache.removeUri(URI_0); 186 187 assertMiss(mCache.getThumbnail(URI_0, MID_SIZE)); 188 assertHitExact(mCache.getThumbnail(URI_1, MID_SIZE)); 189 } 190 assertMiss(Result result)191 private static void assertMiss(Result result) { 192 assertEquals(Result.CACHE_MISS, result.getStatus()); 193 assertFalse(result.isExactHit()); 194 assertFalse(result.isHit()); 195 } 196 assertHitExact(Result result)197 private static void assertHitExact(Result result) { 198 assertEquals(Result.CACHE_HIT_EXACT, result.getStatus()); 199 assertTrue(result.isExactHit()); 200 assertTrue(result.isHit()); 201 } 202 assertHitSmaller(Result result)203 private static void assertHitSmaller(Result result) { 204 assertEquals(Result.CACHE_HIT_SMALLER, result.getStatus()); 205 assertFalse(result.isExactHit()); 206 assertTrue(result.isHit()); 207 } 208 assertHitLarger(Result result)209 private static void assertHitLarger(Result result) { 210 assertEquals(Result.CACHE_HIT_LARGER, result.getStatus()); 211 assertFalse(result.isExactHit()); 212 assertTrue(result.isHit()); 213 } 214 } 215