/** * bitmap cache get -> * background thread hand-off -> bitmap cache -> decode -> resize and rotate -> (webp transcode) * -> data fetch. */ private synchronized Producer<CloseableReference<CloseableImage>> getDataFetchSequence() { if (mDataFetchSequence == null) { Producer<EncodedImage> inputProducer = mProducerFactory.newDataFetchProducer(); if (WebpSupportStatus.sIsWebpSupportRequired && (!mWebpSupportEnabled || WebpSupportStatus.sWebpBitmapFactory == null)) { inputProducer = mProducerFactory.newWebpTranscodeProducer(inputProducer); } inputProducer = mProducerFactory.newAddImageTransformMetaDataProducer(inputProducer); inputProducer = mProducerFactory.newResizeAndRotateProducer( inputProducer, true, mUseDownsamplingRatio); mDataFetchSequence = newBitmapCacheGetToDecodeSequence(inputProducer); } return mDataFetchSequence; }
/** Creates a memory-backed encoded image from the stream. The stream is closed. */ protected EncodedImage getByteBufferBackedEncodedImage( InputStream inputStream, int length) throws IOException { CloseableReference<PooledByteBuffer> ref = null; try { if (length <= 0) { ref = CloseableReference.of(mPooledByteBufferFactory.newByteBuffer(inputStream)); } else { ref = CloseableReference.of(mPooledByteBufferFactory.newByteBuffer(inputStream, length)); } return new EncodedImage(ref); } finally { Closeables.closeQuietly(inputStream); CloseableReference.closeSafely(ref); } }
@Test public void testFetchFromBitmapCacheDueToMethodCall() { Producer<CloseableReference<CloseableImage>> bitmapCacheSequence = mock(Producer.class); when(mProducerSequenceFactory.getDecodedImageProducerSequence(mImageRequest)) .thenReturn(bitmapCacheSequence); mImagePipeline.fetchImageFromBitmapCache(mImageRequest, mCallerContext); verify(mRequestListener1).onRequestStart(mImageRequest, mCallerContext, "0", false); verify(mRequestListener2).onRequestStart(mImageRequest, mCallerContext, "0", false); ArgumentCaptor<ProducerContext> producerContextArgumentCaptor = ArgumentCaptor.forClass(ProducerContext.class); verify(bitmapCacheSequence) .produceResults(any(Consumer.class), producerContextArgumentCaptor.capture()); assertTrue(producerContextArgumentCaptor.getValue().isIntermediateResultExpected()); assertEquals(producerContextArgumentCaptor.getValue().getPriority(), Priority.HIGH); assertEquals( producerContextArgumentCaptor.getValue().getLowestPermittedRequestLevel(), ImageRequest.RequestLevel.BITMAP_MEMORY_CACHE); }
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()); }
/** * Decodes a partial jpeg. * * @param encodedImage input image (encoded bytes plus meta data) * @param length amount of currently available data in bytes * @param qualityInfo quality info for the image * @return a CloseableStaticBitmap */ public CloseableStaticBitmap decodeJpeg( final EncodedImage encodedImage, int length, QualityInfo qualityInfo, ImageDecodeOptions options) { CloseableReference<Bitmap> bitmapReference = mPlatformDecoder.decodeJPEGFromEncodedImage( encodedImage, options.bitmapConfig, null, length); try { return new CloseableStaticBitmap( bitmapReference, qualityInfo, encodedImage.getRotationAngle(), encodedImage.getExifOrientation()); } finally { bitmapReference.close(); } }
/** * Verify that stateful image results, both intermediate and final, are never cached. */ @Test public void testDoNotCacheStatefulImage() { when(mCloseableImage1.isStateful()).thenReturn(true); when(mCloseableImage2.isStateful()).thenReturn(true); setupBitmapMemoryCacheGetNotFound(); setupInputProducerStreamingSuccess(); when(mMemoryCache.get(mBitmapMemoryCacheKey)).thenReturn(null); mBitmapMemoryCacheProducer.produceResults(mConsumer, mProducerContext); verify(mConsumer).onNewResult(mIntermediateImageReference, Consumer.NO_FLAGS); verify(mConsumer).onNewResult(mFinalImageReference, Consumer.IS_LAST); verify(mMemoryCache, never()).cache( any(BitmapMemoryCacheKey.class), any(CloseableReference.class)); }
@Override public CloseableReference<Bitmap> process(Bitmap sourceBitmap, PlatformBitmapFactory bitmapFactory) { CloseableReference<Bitmap> bitmapRef; if (isFull) { bitmapRef = bitmapFactory.createBitmap( sourceBitmap.getWidth() / 2, sourceBitmap.getHeight()); } else { bitmapRef = bitmapFactory.createBitmap( sourceBitmap.getWidth(), sourceBitmap.getHeight()); } try { Bitmap destBitmap = bitmapRef.get(); Canvas canvas2d = new Canvas(destBitmap); canvas2d.drawBitmap(sourceBitmap, new Rect(0, 0, sourceBitmap.getWidth() / 2, sourceBitmap.getHeight()), new Rect(0, 0, destBitmap.getWidth(), destBitmap.getHeight()), null); return CloseableReference.cloneOrNull(bitmapRef); } finally { CloseableReference.closeSafely(bitmapRef); } }
@Override public synchronized void onFrameRendered( int frameNumber, CloseableReference<Bitmap> bitmapReference, @BitmapAnimationBackend.FrameType int frameType) { Preconditions.checkNotNull(bitmapReference); // Close up prepared references. removePreparedReference(frameNumber); // Create the new image reference and cache it. CloseableReference<CloseableImage> closableReference = null; try { closableReference = createImageReference(bitmapReference); if (closableReference != null) { CloseableReference.closeSafely(mLastRenderedItem); mLastRenderedItem = mAnimatedFrameCache.cache(frameNumber, closableReference); } } finally { CloseableReference.closeSafely(closableReference); } }
private void verifyState( boolean isFinished, boolean hasResult, CloseableReference<Object> resultRef, boolean hasFailed, Throwable failureCause) { DataSource<CloseableReference<Object>> dataSource = mDataSource; assertEquals("isFinished", isFinished, dataSource.isFinished()); assertEquals("hasResult", hasResult, dataSource.hasResult()); CloseableReference<Object> dataSourceRef = dataSource.getResult(); assertReferencesSame("getResult", resultRef, dataSourceRef); CloseableReference.closeSafely(dataSourceRef); assertEquals("hasFailed", hasFailed, dataSource.hasFailed()); if (failureCause == NPE) { assertNotNull("failure", dataSource.getFailureCause()); assertSame("failure", NullPointerException.class, dataSource.getFailureCause().getClass()); } else { assertSame("failure", failureCause, dataSource.getFailureCause()); } }
public EncodedImage cloneOrNull() { EncodedImage encodedImage; if (mInputStreamSupplier != null) { encodedImage = new EncodedImage(mInputStreamSupplier, mStreamSize); } else { CloseableReference<PooledByteBuffer> pooledByteBufferRef = CloseableReference.cloneOrNull(mPooledByteBufferRef); try { encodedImage = (pooledByteBufferRef == null) ? null : new EncodedImage(pooledByteBufferRef); } finally { // Close the recently created reference since it will be cloned again in the constructor. CloseableReference.closeSafely(pooledByteBufferRef); } } if (encodedImage != null) { encodedImage.copyMetaDataFrom(this); } return encodedImage; }
/** * Creates a bitmap from encoded JPEG bytes. Supports a partial JPEG image. * * @param encodedImage the encoded image with reference to the encoded bytes * @param bitmapConfig the {@link android.graphics.Bitmap.Config} used to create the decoded * Bitmap * @param regionToDecode optional image region to decode. currently not supported. * @param length the number of encoded bytes in the buffer * @return the bitmap * @throws TooManyBitmapsException if the pool is full * @throws java.lang.OutOfMemoryError if the Bitmap cannot be allocated */ @Override public CloseableReference<Bitmap> decodeJPEGFromEncodedImage( final EncodedImage encodedImage, Bitmap.Config bitmapConfig, @Nullable Rect regionToDecode, int length) { BitmapFactory.Options options = getBitmapFactoryOptions( encodedImage.getSampleSize(), bitmapConfig); final CloseableReference<PooledByteBuffer> bytesRef = encodedImage.getByteBufferRef(); Preconditions.checkNotNull(bytesRef); try { Bitmap bitmap = decodeJPEGByteArrayAsPurgeable(bytesRef, length, options); return pinBitmap(bitmap); } finally { CloseableReference.closeSafely(bytesRef); } }
@Test public void testReuseExclusive_CacheSameItem() { CloseableReference<Integer> cachedRef = mCache.cache(KEY, newReference(100), mEntryStateObserver); cachedRef.close(); verify(mEntryStateObserver).onExclusivityChanged(KEY, true); assertTotalSize(1, 100); assertExclusivelyOwnedSize(1, 100); cachedRef = mCache.reuse(KEY); assertNotNull(cachedRef); verify(mEntryStateObserver).onExclusivityChanged(KEY, false); assertTotalSize(0, 0); assertExclusivelyOwnedSize(0, 0); CloseableReference<Integer> newItem = mCache.cache(KEY, cachedRef); cachedRef.close(); assertTotalSize(1, 100); assertExclusivelyOwnedSize(0, 0); newItem.close(); verify(mEntryStateObserver).onExclusivityChanged(KEY, true); assertTotalSize(1, 100); assertExclusivelyOwnedSize(1, 100); }
/** * Decodes a byteArray into a purgeable bitmap * * @param bytesRef the byte buffer that contains the encoded bytes * @return */ @Override protected Bitmap decodeByteArrayAsPurgeable( CloseableReference<PooledByteBuffer> bytesRef, BitmapFactory.Options options) { final PooledByteBuffer pooledByteBuffer = bytesRef.get(); final int length = pooledByteBuffer.size(); final CloseableReference<byte[]> encodedBytesArrayRef = mFlexByteArrayPool.get(length); try { final byte[] encodedBytesArray = encodedBytesArrayRef.get(); pooledByteBuffer.read(0, encodedBytesArray, 0, length); Bitmap bitmap = BitmapFactory.decodeByteArray( encodedBytesArray, 0, length, options); return Preconditions.checkNotNull(bitmap, "BitmapFactory returned null"); } finally { CloseableReference.closeSafely(encodedBytesArrayRef); } }
private void testNewResult( CloseableReference<Object> resultRef, boolean isLast, int numSubscribers) { mInternalConsumer.onNewResult(resultRef, BaseConsumer.simpleStatusForIsLast(isLast)); if (isLast) { verify(mRequestListener).onRequestSuccess( mSettableProducerContext.getImageRequest(), mRequestId, mSettableProducerContext.isPrefetch()); } if (numSubscribers >= 1) { verify(mDataSubscriber1).onNewResult(mDataSource); } if (numSubscribers >= 2) { verify(mDataSubscriber2).onNewResult(mDataSource); } verifyWithResult(resultRef, isLast); }
/** * Submits a request for execution and returns a DataSource representing the pending decoded * image(s). * <p>The returned DataSource must be closed once the client has finished with it. * * @param imageRequest the request to submit * @param callerContext the caller context for image request * @param lowestPermittedRequestLevelOnSubmit the lowest request level permitted for image request * @return a DataSource representing the pending decoded image(s) */ public DataSource<CloseableReference<CloseableImage>> fetchDecodedImage( ImageRequest imageRequest, Object callerContext, ImageRequest.RequestLevel lowestPermittedRequestLevelOnSubmit) { try { Producer<CloseableReference<CloseableImage>> producerSequence = mProducerSequenceFactory.getDecodedImageProducerSequence(imageRequest); return submitFetchRequest( producerSequence, imageRequest, lowestPermittedRequestLevelOnSubmit, callerContext); } catch (Exception exception) { return DataSources.immediateFailedDataSource(exception); } }
/** * Decodes a GIF into a CloseableImage. * @param encodedImage encoded image (native byte array holding the encoded bytes and meta data) * @param options the options for the decode * @param bitmapConfig the Bitmap.Config used to generate the output bitmaps * @return a {@link CloseableImage} for the GIF image */ public CloseableImage decodeGif( final EncodedImage encodedImage, final ImageDecodeOptions options, final Bitmap.Config bitmapConfig) { if (sGifAnimatedImageDecoder == null) { throw new UnsupportedOperationException("To encode animated gif please add the dependency " + "to the animated-gif module"); } final CloseableReference<PooledByteBuffer> bytesRef = encodedImage.getByteBufferRef(); Preconditions.checkNotNull(bytesRef); try { final PooledByteBuffer input = bytesRef.get(); AnimatedImage gifImage = sGifAnimatedImageDecoder.decode(input.getNativePtr(), input.size()); return getCloseableImage(options, gifImage, bitmapConfig); } finally { CloseableReference.closeSafely(bytesRef); } }
/** * Decode a WebP into a CloseableImage. * @param encodedImage encoded image (native byte array holding the encoded bytes and meta data) * @param options the options for the decode * @param bitmapConfig the Bitmap.Config used to generate the output bitmaps * @return a {@link CloseableImage} for the WebP image */ public CloseableImage decodeWebP( final EncodedImage encodedImage, final ImageDecodeOptions options, final Bitmap.Config bitmapConfig) { if (sWebpAnimatedImageDecoder == null) { throw new UnsupportedOperationException("To encode animated webp please add the dependency " + "to the animated-webp module"); } final CloseableReference<PooledByteBuffer> bytesRef = encodedImage.getByteBufferRef(); Preconditions.checkNotNull(bytesRef); try { final PooledByteBuffer input = bytesRef.get(); AnimatedImage webPImage = sWebpAnimatedImageDecoder.decode( input.getNativePtr(), input.size()); return getCloseableImage(options, webPImage, bitmapConfig); } finally { CloseableReference.closeSafely(bytesRef); } }
@Test public void testFetchDecodedImageWithRequestLevel() { Producer<CloseableReference<CloseableImage>> decodedSequence = mock(Producer.class); when(mProducerSequenceFactory.getDecodedImageProducerSequence(mImageRequest)) .thenReturn(decodedSequence); DataSource<CloseableReference<CloseableImage>> dataSource = mImagePipeline.fetchDecodedImage( mImageRequest, mCallerContext, ImageRequest.RequestLevel.DISK_CACHE); assertFalse(dataSource.isFinished()); verify(mRequestListener1).onRequestStart(mImageRequest, mCallerContext, "0", false); verify(mRequestListener2).onRequestStart(mImageRequest, mCallerContext, "0", false); ArgumentCaptor<ProducerContext> producerContextArgumentCaptor = ArgumentCaptor.forClass(ProducerContext.class); verify(decodedSequence) .produceResults(any(Consumer.class), producerContextArgumentCaptor.capture()); assertTrue(producerContextArgumentCaptor.getValue().isIntermediateResultExpected()); assertEquals(producerContextArgumentCaptor.getValue().getPriority(), Priority.HIGH); assertEquals( producerContextArgumentCaptor.getValue().getLowestPermittedRequestLevel(), ImageRequest.RequestLevel.DISK_CACHE); }
@Test public void testExtractAndClose_whenBitmapReferenceInvalid_thenReturnReference() throws Exception { when(mBitmapReference.isValid()).thenReturn(false); CloseableReference<Bitmap> extractedReference = FrescoFrameCache.convertToBitmapReferenceAndClose(mImageReference); // We only detach the reference and do not care if the bitmap reference is valid assertThat(extractedReference).isNotNull(); assertThat(extractedReference.get()).isEqualTo(mUnderlyingBitmap); extractedReference.close(); verify(mImageReference).close(); }
@Test public void testNonStaticBitmapIsPassedOn() { SingleUsePostprocessorConsumer postprocessorConsumer = produceResults(); CloseableAnimatedImage sourceCloseableAnimatedImage = mock(CloseableAnimatedImage.class); CloseableReference<CloseableImage> sourceCloseableImageRef = CloseableReference.<CloseableImage>of(sourceCloseableAnimatedImage); postprocessorConsumer.onNewResult(sourceCloseableImageRef, Consumer.IS_LAST); sourceCloseableImageRef.close(); mTestExecutorService.runUntilIdle(); mInOrder.verify(mConsumer).onNewResult(any(CloseableReference.class), eq(Consumer.IS_LAST)); mInOrder.verifyNoMoreInteractions(); assertEquals(1, mResults.size()); CloseableReference<CloseableImage> res0 = mResults.get(0); assertTrue(CloseableReference.isValid(res0)); assertSame(sourceCloseableAnimatedImage, res0.get()); res0.close(); verify(sourceCloseableAnimatedImage).close(); }
/** * Returns a sequence that can be used for a request for an encoded image from either network or * local files. * * @param imageRequest the request that will be submitted * @return the sequence that should be used to process the request */ public Producer<CloseableReference<PooledByteBuffer>> getEncodedImageProducerSequence( ImageRequest imageRequest) { validateEncodedImageRequest(imageRequest); final Uri uri = imageRequest.getSourceUri(); switch (imageRequest.getSourceUriType()) { case SOURCE_TYPE_NETWORK: return getNetworkFetchEncodedImageProducerSequence(); case SOURCE_TYPE_LOCAL_VIDEO_FILE: case SOURCE_TYPE_LOCAL_IMAGE_FILE: return getLocalFileFetchEncodedImageProducerSequence(); default: throw new IllegalArgumentException( "Unsupported uri scheme for encoded image fetch! Uri is: " + getShortenedUriString(uri)); } }
/** * Returns a DataSource supplier that will on get submit the request for execution and return a * DataSource representing the pending results of the task. * * @param imageRequest the request to submit (what to execute). * @param callerContext the caller context of the caller of data source supplier * @param requestLevel which level to look down until for the image * @return a DataSource representing pending results and completion of the request */ public Supplier<DataSource<CloseableReference<CloseableImage>>> getDataSourceSupplier( final ImageRequest imageRequest, final Object callerContext, final ImageRequest.RequestLevel requestLevel) { return new Supplier<DataSource<CloseableReference<CloseableImage>>>() { @Override public DataSource<CloseableReference<CloseableImage>> get() { return fetchDecodedImage(imageRequest, callerContext, requestLevel); } @Override public String toString() { return Objects.toStringHelper(this) .add("uri", imageRequest.getSourceUri()) .toString(); } }; }
@Before public void setUp() { MockitoAnnotations.initMocks(this); mBitmapMemoryCacheGetProducer = new BitmapMemoryCacheGetProducer(mMemoryCache, mCacheKeyFactory, mInputProducer); mCloseableImage1 = mock(CloseableImage.class); mFinalImageReference = CloseableReference.of(mCloseableImage1); when(mCloseableImage1.getQualityInfo()).thenReturn(ImmutableQualityInfo.FULL_QUALITY); when(mProducerContext.getImageRequest()).thenReturn(mImageRequest); when(mProducerContext.getListener()).thenReturn(mProducerListener); when(mProducerContext.getId()).thenReturn(mRequestId); when(mProducerListener.requiresExtraMap(mRequestId)).thenReturn(true); when(mProducerContext.getLowestPermittedRequestLevel()) .thenReturn(ImageRequest.RequestLevel.FULL_FETCH); when(mProducerContext.getCallerContext()) .thenReturn(PRODUCER_NAME); when(mCacheKeyFactory.getBitmapCacheKey(mImageRequest, PRODUCER_NAME)).thenReturn(mCacheKey); }
public PipelineDraweeController newController( Supplier<DataSource<CloseableReference<CloseableImage>>> dataSourceSupplier, String id, CacheKey cacheKey, Object callerContext) { return newController(dataSourceSupplier, id, cacheKey, callerContext, null); }
/** * swallow result if prefetch -> bitmap cache get -> * background thread hand-off -> multiplex -> bitmap cache -> decode -> multiplex -> * encoded cache -> disk cache -> (webp transcode) -> network fetch. */ private synchronized Producer<CloseableReference<CloseableImage>> getNetworkFetchSequence() { if (mNetworkFetchSequence == null) { mNetworkFetchSequence = newBitmapCacheGetToDecodeSequence(getCommonNetworkFetchToEncodedMemorySequence()); } return mNetworkFetchSequence; }
/** * Initializes this controller with the new data source supplier, id and caller context. This * allows for reusing of the existing controller instead of instantiating a new one. This method * should be called when the controller is in detached state. * * @param dataSourceSupplier data source supplier * @param id unique id for this controller * @param callerContext tag and context for this controller */ public void initialize( Supplier<DataSource<CloseableReference<CloseableImage>>> dataSourceSupplier, String id, CacheKey cacheKey, Object callerContext, @Nullable ImmutableList<DrawableFactory> customDrawableFactories) { super.initialize(id, callerContext); init(dataSourceSupplier); mCacheKey = cacheKey; setCustomDrawableFactories(customDrawableFactories); }
/** * Creates a new instance of a CloseableStaticBitmap from an existing CloseableReference. The * CloseableStaticBitmap will hold a reference to the Bitmap until it's closed. * * @param bitmapReference the bitmap reference. */ public CloseableStaticBitmap( CloseableReference<Bitmap> bitmapReference, QualityInfo qualityInfo, int rotationAngle, int exifOrientation) { mBitmapReference = Preconditions.checkNotNull(bitmapReference.cloneOrNull()); mBitmap = mBitmapReference.get(); mQualityInfo = qualityInfo; mRotationAngle = rotationAngle; mExifOrientation = exifOrientation; }
@Before public void setUp() { MockitoAnnotations.initMocks(this); mSettableDataSource1 = SettableDataSource.create(); mSettableDataSource2 = SettableDataSource.create(); mListDataSource = ListDataSource.create(mSettableDataSource1, mSettableDataSource2); mRef1 = CloseableReference.of(1, mResourceReleaser); mRef2 = CloseableReference.of(2, mResourceReleaser); mRuntimeException = new RuntimeException(); mListDataSource.subscribe(mDataSubscriber, CallerThreadExecutor.getInstance()); }
/** * Try to render the frame to the given target bitmap. If the rendering fails, the target bitmap * reference will be closed and false is returned. If rendering succeeds, the target bitmap * reference can be drawn and has to be manually closed after drawing has been completed. * * @param frameNumber the frame number to render * @param targetBitmap the target bitmap * @return true if rendering successful */ private boolean renderFrameInBitmap( int frameNumber, @Nullable CloseableReference<Bitmap> targetBitmap) { if (!CloseableReference.isValid(targetBitmap)) { return false; } // Render the image boolean frameRendered = mBitmapFrameRenderer.renderFrame(frameNumber, targetBitmap.get()); if (!frameRendered) { CloseableReference.closeSafely(targetBitmap); } return frameRendered; }
/** * Creates a new instance of a CloseableStaticBitmap from an existing CloseableReference. The * CloseableStaticBitmap will hold a reference to the Bitmap until it's closed. * * @param bitmapReference the bitmap reference. */ public CloseableStaticBitmap( CloseableReference<Bitmap> bitmapReference, QualityInfo qualityInfo, int rotationAngle) { this(bitmapReference, qualityInfo, rotationAngle, ExifInterface.ORIENTATION_UNDEFINED); }
@Override protected void onFailureImpl(DataSource<CloseableReference<PooledByteBuffer>> dataSource) { if (!TextUtils.isEmpty(action)) { Intent intent = new Intent(action); intent.putExtra("success", false); intent.putExtra("uri", uri); LocalBroadcastManager.getInstance(ExpressApplication.getApplication()) .sendBroadcast(intent); } }
@Nullable @Override public synchronized CloseableReference<Bitmap> getCachedFrame(int frameNumber) { if (mLastFrameNumber == frameNumber) { return CloseableReference.cloneOrNull(mLastBitmapReference); } return null; }
@Test public void testCloneUnderlyingBitmapReference() { CloseableReference<Bitmap> clonedBitmapReference = mCloseableStaticBitmap.cloneUnderlyingBitmapReference(); assertThat(clonedBitmapReference).isNotNull(); assertThat(clonedBitmapReference.get()).isEqualTo(mBitmap); }
@Before public void setUp() { MockitoAnnotations.initMocks(this); mSwallowResultProducer = new SwallowResultProducer<CloseableReference<CloseableImage>>(mInputProducer); mFinalImageReference = CloseableReference.of(mock(CloseableImage.class)); mIntermediateImageReference = CloseableReference.of(mock(CloseableImage.class)); }
/** * swallow result producer -> inputProducer */ private synchronized Producer<Void> getDecodedImagePrefetchSequence( Producer<CloseableReference<CloseableImage>> inputProducer) { if (!mCloseableImagePrefetchSequences.containsKey(inputProducer)) { SwallowResultProducer<CloseableReference<CloseableImage>> swallowResultProducer = mProducerFactory.newSwallowResultProducer(inputProducer); mCloseableImagePrefetchSequences.put(inputProducer, swallowResultProducer); } return mCloseableImagePrefetchSequences.get(inputProducer); }
@Override public void onCancellation(DataSource<CloseableReference<CloseableImage>> dataSource) { if (mDataSource == dataSource) { mDataSource = null; } dataSource.close(); }
@Test public void testLocalContentUriFullFetch() { PowerMockito.when(mImageRequest.getSourceUriType()) .thenReturn(SOURCE_TYPE_LOCAL_CONTENT); Producer<CloseableReference<CloseableImage>> producer = mProducerSequenceFactory.getDecodedImageProducerSequence(mImageRequest); assertSame(producer, mProducerSequenceFactory.mLocalContentUriFetchSequence); }
@Override public synchronized void clear() { CloseableReference.closeSafely(mLastRenderedItem); mLastRenderedItem = null; for (int i = 0; i < mPreparedPendingFrames.size(); i++) { CloseableReference.closeSafely(mPreparedPendingFrames.valueAt(i)); } mPreparedPendingFrames.clear(); // The frame cache will free items when needed }
private void internalPrepareBitmap(CloseableReference<CloseableImage> newResult) { if (newResult == null || !newResult.isValid()) { return; } final CloseableImage closeableImage = newResult.get(); if (closeableImage == null || closeableImage.isClosed()) { return; } if (closeableImage instanceof CloseableStaticBitmap) { final CloseableStaticBitmap staticBitmap = (CloseableStaticBitmap) closeableImage; final Bitmap bitmap = staticBitmap.getUnderlyingBitmap(); if (bitmap == null) { return; } final int bitmapByteCount = bitmap.getRowBytes() * bitmap.getHeight(); if (bitmapByteCount < mMinBitmapSizeBytes) { return; } if (bitmapByteCount > mMaxBitmapSizeBytes) { return; } bitmap.prepareToDraw(); } }
@Override public CloseableReference<V> get(K key) { CloseableReference<V> result = mDelegate.get(key); if (result == null) { mTracker.onCacheMiss(); } else { mTracker.onCacheHit(key); } return result; }