package com.bumptech.glide.load.engine.bitmap_recycle; import static android.content.ComponentCallbacks2.TRIM_MEMORY_BACKGROUND; import static android.content.ComponentCallbacks2.TRIM_MEMORY_COMPLETE; import static android.content.ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import android.annotation.TargetApi; import android.os.Build; import java.util.Arrays; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; @RunWith(RobolectricTestRunner.class) @Config(manifest = Config.NONE, sdk = 18) @TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH) public class LruArrayPoolTest { private static final int MAX_SIZE = 10; private static final Class<byte[]> ARRAY_CLASS = byte[].class; private static final ArrayAdapterInterface<byte[]> ADAPTER = new ByteArrayAdapter(); private LruArrayPool pool; @Before public void setUp() throws Exception { pool = new LruArrayPool(MAX_SIZE); } @Test public void testNewPoolIsEmpty() { assertEquals(pool.getCurrentSize(), 0); } @Test public void testICanAddAndGetValidArray() { int size = 758; int value = 564; fillPool(pool, size - 1, value); pool.put(createArray(ARRAY_CLASS, size, value), ARRAY_CLASS); Object array = pool.get(size, ARRAY_CLASS); assertNotNull(array); assertTrue(array.getClass() == ARRAY_CLASS); assertTrue(ADAPTER.getArrayLength((byte[]) array) >= size); assertTrue(((byte[]) array)[0] == (byte) 0); } @Test public void testItIsSizeLimited() { fillPool(pool, MAX_SIZE / ADAPTER.getElementSizeInBytes() + 1, 1); assertTrue(pool.getCurrentSize() <= MAX_SIZE); } @Test public void testArrayLargerThanPoolIsNotAdded() { pool = new LruArrayPool(MAX_SIZE); pool.put(createArray(ARRAY_CLASS, MAX_SIZE / ADAPTER.getElementSizeInBytes() + 1, 0), ARRAY_CLASS); assertEquals(0, pool.getCurrentSize()); } @Test public void testClearMemoryRemovesAllArrays() { fillPool(pool, MAX_SIZE / ADAPTER.getElementSizeInBytes() + 1, 0); pool.clearMemory(); assertEquals(0, pool.getCurrentSize()); } @Test public void testTrimMemoryUiHiddenOrLessRemovesHalfOfArrays() { testTrimMemory(MAX_SIZE, TRIM_MEMORY_UI_HIDDEN, MAX_SIZE / 2); } @Test public void testTrimMemoryUiHiddenOrLessRemovesNoArraysIfPoolLessThanHalfFull() { testTrimMemory(MAX_SIZE / 2, TRIM_MEMORY_UI_HIDDEN, MAX_SIZE / 2); } @Test public void testTrimMemoryBackgroundOrGreaterRemovesAllArrays() { for (int trimLevel : new int[] {TRIM_MEMORY_BACKGROUND, TRIM_MEMORY_COMPLETE}) { testTrimMemory(MAX_SIZE, trimLevel, 0); } } private void testTrimMemory(int fillSize, int trimLevel, int expectedSize) { pool = new LruArrayPool(MAX_SIZE); fillPool(pool, fillSize / ADAPTER.getElementSizeInBytes(), 1); pool.trimMemory(trimLevel); assertEquals("Failed level=" + trimLevel, expectedSize, pool.getCurrentSize()); } private void fillPool(LruArrayPool pool, int arrayCount, int arrayLength) { for (int i = 0; i < arrayCount; i++) { pool.put(createArray(ARRAY_CLASS, arrayLength, 10), ARRAY_CLASS); } } @SuppressWarnings("unchecked") private static <T> T createArray(Class<T> type, int size, int value) { Object array = null; if (type.equals(int[].class)) { array = new int[size]; Arrays.fill((int[]) array, value); } else if (type.equals(byte[].class)) { array = new byte[size]; Arrays.fill((byte[]) array, (byte) value); } return (T) array; } }