@VisibleForTesting static Map<String, String> getExtraMap( final ProducerListener listener, final String requestId, final boolean valueFound, final int sizeInBytes) { if (!listener.requiresExtraMap(requestId)) { return null; } if (valueFound) { return ImmutableMap.of( EXTRA_CACHED_VALUE_FOUND, String.valueOf(valueFound), ENCODED_IMAGE_SIZE, String.valueOf(sizeInBytes)); } else { return ImmutableMap.of( EXTRA_CACHED_VALUE_FOUND, String.valueOf(valueFound)); } }
@Nullable @VisibleForTesting static Map<String, String> getExtraMap( final ProducerListener listener, final String requestId, final boolean valueFound, final int sizeInBytes) { if (!listener.requiresExtraMap(requestId)) { return null; } if (valueFound) { return ImmutableMap.of( EXTRA_CACHED_VALUE_FOUND, String.valueOf(valueFound), ENCODED_IMAGE_SIZE, String.valueOf(sizeInBytes)); } else { return ImmutableMap.of( EXTRA_CACHED_VALUE_FOUND, String.valueOf(valueFound)); } }
@Test public void testRelease() throws Exception { // get a buffer - causes an alloc byte[] b1 = mPool.get(1); // release this buffer mPool.release(b1); // verify stats mStats.refresh(); Assert.assertEquals( ImmutableMap.of(2, new IntPair(0, 1)), mStats.mBucketStats); Assert.assertEquals(2, mStats.mFreeBytes); Assert.assertEquals(0, mStats.mUsedBytes); Assert.assertEquals(1, mStats.mFreeCount); Assert.assertEquals(0, mStats.mUsedCount); }
@Test public void testRelease_Free() throws Exception { // get a set of buffers that bump up above the max size mPool.get(6); // get and release another buffer. this should cause a free byte[] b3 = mPool.get(6); mPool.release(b3); mStats.refresh(); Assert.assertEquals( ImmutableMap.of(6, new IntPair(1, 0)), mStats.mBucketStats); Assert.assertEquals(0, mStats.mFreeBytes); Assert.assertEquals(6, mStats.mUsedBytes); Assert.assertEquals(0, mStats.mFreeCount); Assert.assertEquals(1, mStats.mUsedCount); }
@Test public void testRelease_Free2() throws Exception { // create a new pool with a max size cap of zero. mPool = new TestPool(0, 10); mStats.setPool(mPool); // get a buffer and release it - this should trigger the soft cap byte[] b1 = mPool.get(4); mPool.release(b1); mStats.refresh(); Assert.assertEquals( ImmutableMap.of( 4, new IntPair(0, 0)), mStats.mBucketStats); Assert.assertEquals(0, mStats.mFreeBytes); Assert.assertEquals(0, mStats.mUsedBytes); Assert.assertEquals(0, mStats.mFreeCount); Assert.assertEquals(0, mStats.mUsedCount); }
@Test public void testRelease_UnknownValue() throws Exception { // get a buffer from the pool mPool.get(1); // allocate a buffer outside the pool byte[] b2 = new byte[2]; // try to release this buffer to the pool mPool.release(b2); // verify stats mStats.refresh(); Assert.assertEquals( ImmutableMap.of(2, new IntPair(1, 0)), mStats.mBucketStats); Assert.assertEquals(0, mStats.mFreeBytes); Assert.assertEquals(2, mStats.mUsedBytes); Assert.assertEquals(0, mStats.mFreeCount); Assert.assertEquals(1, mStats.mUsedCount); }
@Test public void testRelease_NonReusable() throws Exception { TestPool pool = new TestPool(100, 100, makeBucketSizeArray(2, 3)); mPool.mIsReusable = false; mStats.setPool(pool); // get a buffer, and then release it byte[] b1 = mPool.get(2); mPool.release(b1); // verify stats mStats.refresh(); Assert.assertEquals( ImmutableMap.of(2, new IntPair(0, 0)), mStats.mBucketStats); Assert.assertEquals(0, mStats.mFreeBytes); Assert.assertEquals(0, mStats.mUsedBytes); Assert.assertEquals(0, mStats.mFreeCount); Assert.assertEquals(0, mStats.mUsedCount); }
@Test public void testNewByteBuf_5() { NativePooledByteBuffer sb5 = mFactory.newByteBuffer(5); Assert.assertEquals(8, sb5.mBufRef.get().getSize()); Assert.assertEquals(1, sb5.mBufRef.getUnderlyingReferenceTestOnly().getRefCountTestOnly()); mStats.refresh(); Assert.assertEquals( ImmutableMap.of( 32, new IntPair(0, 0), 16, new IntPair(0, 0), 8, new IntPair(1, 0), 4, new IntPair(0, 0)), mStats.mBucketStats); sb5.close(); mStats.refresh(); Assert.assertEquals( ImmutableMap.of( 32, new IntPair(0, 0), 16, new IntPair(0, 0), 8, new IntPair(0, 1), 4, new IntPair(0, 0)), mStats.mBucketStats); }
@Test public void testCacheIntermediateImageAsNoImagePresent() { setupBitmapMemoryCacheGetNotFound(); setupInputProducerStreamingSuccess(); when(mMemoryCache.get(mBitmapMemoryCacheKey)).thenReturn(null); mBitmapMemoryCacheProducer.produceResults(mConsumer, mProducerContext); verify(mMemoryCache).cache(mBitmapMemoryCacheKey, mIntermediateImageReference); verify(mMemoryCache).cache(mBitmapMemoryCacheKey, mFinalImageReference); verify(mConsumer).onNewResult(mIntermediateImageReferenceClone, Consumer.NO_FLAGS); verify(mConsumer).onNewResult(mFinalImageReferenceClone, Consumer.IS_LAST); Assert.assertTrue(!mIntermediateImageReferenceClone.isValid()); Assert.assertTrue(!mFinalImageReferenceClone.isValid()); verify(mProducerListener).onProducerStart(mRequestId, PRODUCER_NAME); Map<String, String> extraMap = ImmutableMap.of(BitmapMemoryCacheProducer.EXTRA_CACHED_VALUE_FOUND, "false"); verify(mProducerListener).onProducerFinishWithSuccess(mRequestId, PRODUCER_NAME, extraMap); verify(mProducerListener, never()) .onUltimateProducerReached(anyString(), anyString(), anyBoolean()); }
@Test public void testCacheIntermediateImageAsBetterScan() { setupInputProducerStreamingSuccess(); CloseableImage closeableImage = mock(CloseableImage.class); when(closeableImage.getQualityInfo()) .thenReturn(ImmutableQualityInfo.of(INTERMEDIATE_SCAN_1, false, false)); CloseableReference<CloseableImage> closeableImageRef = CloseableReference.of(closeableImage); setupBitmapMemoryCacheGetSuccessOnSecondRead(closeableImageRef); mBitmapMemoryCacheProducer.produceResults(mConsumer, mProducerContext); verify(mMemoryCache).cache(mBitmapMemoryCacheKey, mIntermediateImageReference); verify(mMemoryCache).cache(mBitmapMemoryCacheKey, mFinalImageReference); verify(mConsumer).onNewResult(mIntermediateImageReferenceClone, Consumer.NO_FLAGS); verify(mConsumer).onNewResult(mFinalImageReferenceClone, Consumer.IS_LAST); Assert.assertTrue(!mIntermediateImageReferenceClone.isValid()); Assert.assertTrue(!mFinalImageReferenceClone.isValid()); Assert.assertEquals( 0, closeableImageRef.getUnderlyingReferenceTestOnly().getRefCountTestOnly()); verify(mProducerListener).onProducerStart(mRequestId, PRODUCER_NAME); Map<String, String> extraMap = ImmutableMap.of(BitmapMemoryCacheProducer.EXTRA_CACHED_VALUE_FOUND, "false"); verify(mProducerListener).onProducerFinishWithSuccess(mRequestId, PRODUCER_NAME, extraMap); verify(mProducerListener, never()) .onUltimateProducerReached(anyString(), anyString(), anyBoolean()); }
@Test public void testDontCacheIntermediateImageAsAlreadyHaveSameQuality() { setupInputProducerStreamingSuccess(); CloseableImage closeableImage = mock(CloseableImage.class); when(closeableImage.getQualityInfo()) .thenReturn(ImmutableQualityInfo.of(INTERMEDIATE_SCAN_2, true, false)); CloseableReference<CloseableImage> closeableImageRef = CloseableReference.of(closeableImage); setupBitmapMemoryCacheGetSuccessOnSecondRead(closeableImageRef); mBitmapMemoryCacheProducer.produceResults(mConsumer, mProducerContext); verify(mMemoryCache, never()).cache(mBitmapMemoryCacheKey, mIntermediateImageReference); verify(mMemoryCache).cache(mBitmapMemoryCacheKey, mFinalImageReference); verify(mConsumer).onNewResult(closeableImageRef, Consumer.NO_FLAGS); verify(mConsumer).onNewResult(mFinalImageReferenceClone, Consumer.IS_LAST); Assert.assertTrue(!mFinalImageReferenceClone.isValid()); Assert.assertEquals( 0, closeableImageRef.getUnderlyingReferenceTestOnly().getRefCountTestOnly()); verify(mProducerListener).onProducerStart(mRequestId, PRODUCER_NAME); Map<String, String> extraMap = ImmutableMap.of(BitmapMemoryCacheProducer.EXTRA_CACHED_VALUE_FOUND, "false"); verify(mProducerListener).onProducerFinishWithSuccess(mRequestId, PRODUCER_NAME, extraMap); verify(mProducerListener, never()) .onUltimateProducerReached(anyString(), anyString(), anyBoolean()); }
@Test public void testDontCacheIntermediateImageAsAlreadyHaveFullQuality() { setupBitmapMemoryCacheGetNotFound(); setupInputProducerStreamingSuccess(); CloseableImage closeableImage = mock(CloseableImage.class); when(closeableImage.getQualityInfo()).thenReturn(ImmutableQualityInfo.FULL_QUALITY); CloseableReference<CloseableImage> closeableImageRef = CloseableReference.of(closeableImage); setupBitmapMemoryCacheGetSuccessOnSecondRead(closeableImageRef); mBitmapMemoryCacheProducer.produceResults(mConsumer, mProducerContext); verify(mMemoryCache, never()).cache(mBitmapMemoryCacheKey, mIntermediateImageReference); verify(mMemoryCache).cache(mBitmapMemoryCacheKey, mFinalImageReference); verify(mConsumer).onNewResult(closeableImageRef, Consumer.NO_FLAGS); verify(mConsumer).onNewResult(mFinalImageReferenceClone, Consumer.IS_LAST); Assert.assertTrue(!mFinalImageReferenceClone.isValid()); Assert.assertEquals( 0, closeableImageRef.getUnderlyingReferenceTestOnly().getRefCountTestOnly()); verify(mProducerListener).onProducerStart(mRequestId, PRODUCER_NAME); Map<String, String> extraMap = ImmutableMap.of(BitmapMemoryCacheProducer.EXTRA_CACHED_VALUE_FOUND, "false"); verify(mProducerListener).onProducerFinishWithSuccess(mRequestId, PRODUCER_NAME, extraMap); verify(mProducerListener, never()) .onUltimateProducerReached(anyString(), anyString(), anyBoolean()); }
@Test public void testBitmapMemoryCacheGetIntermediateImageLowestLevelReached() { setupBitmapMemoryCacheGetIntermediateImage(); when(mProducerContext.getLowestPermittedRequestLevel()) .thenReturn(ImageRequest.RequestLevel.BITMAP_MEMORY_CACHE); mBitmapMemoryCacheProducer.produceResults(mConsumer, mProducerContext); verify(mConsumer).onNewResult(mIntermediateImageReference, Consumer.NO_FLAGS); verify(mConsumer).onNewResult(null, Consumer.IS_LAST); verify(mProducerListener).onProducerStart(mRequestId, PRODUCER_NAME); Map<String, String> extraMap = ImmutableMap.of(BitmapMemoryCacheProducer.EXTRA_CACHED_VALUE_FOUND, "false"); verify(mProducerListener).onProducerFinishWithSuccess(mRequestId, PRODUCER_NAME, extraMap); verify(mProducerListener).onUltimateProducerReached(mRequestId, PRODUCER_NAME, false); Assert.assertTrue(!mIntermediateImageReference.isValid()); verifyNoMoreInteractions(mInputProducer); }
@Test public void testLocalVideoMicroThumbnailReturnsNull() throws Exception { when(mProducerListener.requiresExtraMap(mRequestId)).thenReturn(true); when( android.media.ThumbnailUtils.createVideoThumbnail( mFile.getPath(), MediaStore.Images.Thumbnails.MICRO_KIND)) .thenReturn(null); mLocalVideoThumbnailProducer.produceResults(mConsumer, mProducerContext); mExecutor.runUntilIdle(); verify(mConsumer).onNewResult(null, Consumer.IS_LAST); verify(mProducerListener).onProducerStart(mRequestId, PRODUCER_NAME); Map<String, String> thumbnailNotFoundMap = ImmutableMap.of(LocalVideoThumbnailProducer.CREATED_THUMBNAIL, "false"); verify(mProducerListener).onProducerFinishWithSuccess( mRequestId, PRODUCER_NAME, thumbnailNotFoundMap); verify(mProducerListener).onUltimateProducerReached(mRequestId, PRODUCER_NAME, false); }
@Test public void testGetExtraMap() { final Map<String, String> trueValue = ImmutableMap.of( DiskCacheReadProducer.EXTRA_CACHED_VALUE_FOUND, "true", DiskCacheReadProducer.ENCODED_IMAGE_SIZE, "123"); assertEquals( trueValue, DiskCacheReadProducer.getExtraMap(mProducerListener, mRequestId, true, 123)); final Map<String, String> falseValue = ImmutableMap.of( DiskCacheReadProducer.EXTRA_CACHED_VALUE_FOUND, "false"); assertEquals( falseValue, DiskCacheReadProducer.getExtraMap(mProducerListener, mRequestId, false, 0)); }
@Test public void testEncodedMemoryCacheGetSuccessful() { setupEncodedMemoryCacheGetSuccess(); when(mProducerContext.getLowestPermittedRequestLevel()) .thenReturn(ImageRequest.RequestLevel.ENCODED_MEMORY_CACHE); mEncodedMemoryCacheProducer.produceResults(mConsumer, mProducerContext); ArgumentCaptor<EncodedImage> argumentCaptor = ArgumentCaptor.forClass(EncodedImage.class); verify(mConsumer).onNewResult(argumentCaptor.capture(), eq(Consumer.IS_LAST)); EncodedImage encodedImage = argumentCaptor.getValue(); Assert.assertSame( mFinalEncodedImage.getUnderlyingReferenceTestOnly(), encodedImage.getUnderlyingReferenceTestOnly()); verify(mProducerListener).onProducerStart(mRequestId, PRODUCER_NAME); Map<String, String> extraMap = ImmutableMap.of(EncodedMemoryCacheProducer.EXTRA_CACHED_VALUE_FOUND, "true"); verify(mProducerListener).onProducerFinishWithSuccess(mRequestId, PRODUCER_NAME, extraMap); verify(mProducerListener).onUltimateProducerReached(mRequestId, PRODUCER_NAME, true); Assert.assertFalse(mFinalImageReference.isValid()); }
@Test public void testEncodedMemoryCacheGetNotFoundInputProducerSuccess() { setupEncodedMemoryCacheGetNotFound(); setupInputProducerStreamingSuccess(); mEncodedMemoryCacheProducer.produceResults(mConsumer, mProducerContext); verify(mMemoryCache, never()).cache(mCacheKey, mIntermediateImageReference); ArgumentCaptor<CloseableReference> argumentCaptor = ArgumentCaptor.forClass(CloseableReference.class); verify(mMemoryCache).cache(eq(mCacheKey), argumentCaptor.capture()); CloseableReference<PooledByteBuffer> capturedRef = (CloseableReference<PooledByteBuffer>) argumentCaptor.getValue(); Assert.assertSame( mFinalImageReference.getUnderlyingReferenceTestOnly(), capturedRef.getUnderlyingReferenceTestOnly()); verify(mConsumer).onNewResult(mIntermediateEncodedImage, Consumer.NO_FLAGS); verify(mConsumer).onNewResult(mFinalEncodedImage, Consumer.IS_LAST); Assert.assertTrue(EncodedImage.isValid(mFinalEncodedImageClone)); verify(mProducerListener).onProducerStart(mRequestId, PRODUCER_NAME); Map<String, String> extraMap = ImmutableMap.of(EncodedMemoryCacheProducer.EXTRA_CACHED_VALUE_FOUND, "false"); verify(mProducerListener).onProducerFinishWithSuccess(mRequestId, PRODUCER_NAME, extraMap); verify(mProducerListener, never()) .onUltimateProducerReached(anyString(), anyString(), anyBoolean()); }
private void testInputProducerSuccessButResultNotCacheableDueToStatusFlags( final @Consumer.Status int statusFlags) { setupInputProducerStreamingSuccessWithStatusFlags(statusFlags); mEncodedMemoryCacheProducer.produceResults(mConsumer, mProducerContext); verify(mMemoryCache, never()).cache(any(CacheKey.class), any(CloseableReference.class)); verify(mConsumer) .onNewResult(mIntermediateEncodedImage, statusFlags); verify(mConsumer) .onNewResult(mFinalEncodedImage, Consumer.IS_LAST | statusFlags); Assert.assertTrue(EncodedImage.isValid(mFinalEncodedImageClone)); verify(mProducerListener).onProducerStart(mRequestId, PRODUCER_NAME); Map<String, String> extraMap = ImmutableMap.of(EncodedMemoryCacheProducer.EXTRA_CACHED_VALUE_FOUND, "false"); verify(mProducerListener).onProducerFinishWithSuccess(mRequestId, PRODUCER_NAME, extraMap); verify(mProducerListener, never()) .onUltimateProducerReached(anyString(), anyString(), anyBoolean()); }
private Map<String, String> getExtraMap( EncodedImage encodedImage, ImageRequest imageRequest, int numerator, int downsampleNumerator, int softwareNumerator, int rotationAngle) { if (!mProducerContext.getListener().requiresExtraMap(mProducerContext.getId())) { return null; } String originalSize = encodedImage.getWidth() + "x" + encodedImage.getHeight(); String requestedSize; if (imageRequest.getResizeOptions() != null) { requestedSize = imageRequest.getResizeOptions().width + "x" + imageRequest.getResizeOptions().height; } else { requestedSize = "Unspecified"; } String fraction = numerator > 0 ? numerator + "/8" : ""; final Map<String, String> map = new HashMap<>(); map.put(ORIGINAL_SIZE_KEY, originalSize); map.put(REQUESTED_SIZE_KEY, requestedSize); map.put(FRACTION_KEY, fraction); map.put(JobScheduler.QUEUE_TIME_KEY, String.valueOf(mJobScheduler.getQueuedTime())); map.put(DOWNSAMPLE_ENUMERATOR_KEY, Integer.toString(downsampleNumerator)); map.put(SOFTWARE_ENUMERATOR_KEY, Integer.toString(softwareNumerator)); map.put(ROTATION_ANGLE_KEY, Integer.toString(rotationAngle)); return ImmutableMap.copyOf(map); }
private Map<String, String> getExtraMap( ProducerListener listener, String requestId, Postprocessor postprocessor) { if (!listener.requiresExtraMap(requestId)) { return null; } return ImmutableMap.of(POSTPROCESSOR, postprocessor.getName()); }
@VisibleForTesting static Map<String, String> getExtraMap( final ProducerListener listener, final String requestId, final boolean valueFound, final int variantsCount, final String variantsSource, boolean useAsLastResult) { if (!listener.requiresExtraMap(requestId)) { return null; } if (valueFound) { return ImmutableMap.of( EXTRA_CACHED_VALUE_FOUND, String.valueOf(true), EXTRA_CACHED_VALUE_USED_AS_LAST, String.valueOf(useAsLastResult), EXTRA_VARIANTS_COUNT, String.valueOf(variantsCount), EXTRA_VARIANTS_SOURCE, variantsSource); } else { return ImmutableMap.of( EXTRA_CACHED_VALUE_FOUND, String.valueOf(false), EXTRA_VARIANTS_COUNT, String.valueOf(variantsCount), EXTRA_VARIANTS_SOURCE, variantsSource); } }
@Test public void testGet_Alloc() throws Exception { // get a buffer - causes an alloc byte[] b1 = mPool.get(1); Assert.assertNotNull(b1); Assert.assertEquals(2, b1.length); Assert.assertTrue(mPool.mInUseValues.contains(b1)); mStats.refresh(); Assert.assertEquals( ImmutableMap.of(2, new IntPair(1, 0)), mStats.mBucketStats); Assert.assertEquals(0, mStats.mFreeBytes); Assert.assertEquals(2, mStats.mUsedBytes); Assert.assertEquals(0, mStats.mFreeCount); Assert.assertEquals(1, mStats.mUsedCount); // release this buffer mPool.release(b1); Assert.assertFalse(mPool.mInUseValues.contains(b1)); // get another buffer, but of a different size. No reuse possible byte[] b2 = mPool.get(3); Assert.assertNotNull(b2); Assert.assertEquals(4, b2.length); Assert.assertTrue(mPool.mInUseValues.contains(b2)); mStats.refresh(); Assert.assertEquals( ImmutableMap.of( 2, new IntPair(0, 1), 4, new IntPair(1, 0)), mStats.mBucketStats); Assert.assertEquals(2, mStats.mFreeBytes); Assert.assertEquals(4, mStats.mUsedBytes); Assert.assertEquals(1, mStats.mFreeCount); Assert.assertEquals(1, mStats.mUsedCount); }