log(OWNER_HUNTER, VERB_DECODED, data.logId(), "from cache"); return new Result(bitmap, MEMORY); Bitmap bitmap = result.getBitmap(); if (bitmap != null) { if (picasso.loggingEnabled) { if (data.needsMatrixTransform() || result.getExifRotation() != 0) { transformations.add(new MatrixTransformation(data)); bitmap = result.getBitmap(); if (bitmap != null) { stats.dispatchBitmapTransformed(bitmap);
/** * Create or update the drawable on the target {@link ImageView} to display the supplied bitmap * image. */ static void setResult(ImageView target, Context context, RequestHandler.Result result, boolean noFade, boolean debugging) { Drawable placeholder = target.getDrawable(); if (placeholder instanceof Animatable) { ((Animatable) placeholder).stop(); } Bitmap bitmap = result.getBitmap(); if (bitmap != null) { Picasso.LoadedFrom loadedFrom = result.getLoadedFrom(); PicassoDrawable drawable = new PicassoDrawable(context, bitmap, placeholder, loadedFrom, noFade, debugging); target.setImageDrawable(drawable); return; } Drawable drawable = result.getDrawable(); if (drawable != null) { target.setImageDrawable(drawable); if (drawable instanceof Animatable) { ((Animatable) drawable).start(); } } }
if (bitmap != null) { picasso.cancelRequest(target); RequestHandler.Result result = new RequestHandler.Result(bitmap, MEMORY); setResult(target, picasso.context, result, noFade, picasso.indicatorsEnabled); if (picasso.loggingEnabled) {
Bitmap bitmap = decodeStream(source, request); signaledCallback = true; callback.onSuccess(new Result(bitmap, DISK, exifOrientation)); return; callback.onSuccess(new Result(bitmap, DISK, exifOrientation)); return; Bitmap bitmap = decodeStream(source, request); signaledCallback = true; callback.onSuccess(new Result(bitmap, DISK, exifOrientation)); } catch (Exception e) { if (!signaledCallback) {
if (result.getBitmap() == null && result.getDrawable() == null) { dispatcher.dispatchFailed(this); } else {
@Override public void onResponse(Call call, Response response) { if (!response.isSuccessful()) { callback.onError(new ResponseException(response.code(), request.networkPolicy)); return; } // Cache response is only null when the response comes fully from the network. Both // completely cached and conditionally cached responses will have a non-null cache response. Picasso.LoadedFrom loadedFrom = response.cacheResponse() == null ? NETWORK : DISK; // Sometimes response content length is zero when requests are being replayed. Haven't found // root cause to this but retrying the request seems safe to do so. ResponseBody body = response.body(); if (loadedFrom == DISK && body.contentLength() == 0) { body.close(); callback.onError( new ContentLengthException("Received response with 0 content-length header.")); return; } if (loadedFrom == NETWORK && body.contentLength() > 0) { stats.dispatchDownloadFinished(body.contentLength()); } try { Bitmap bitmap = decodeStream(body.source(), request); callback.onSuccess(new Result(bitmap, loadedFrom)); } catch (IOException e) { body.close(); callback.onError(e); } }
@Test public void recycledOriginalTransformationThrows() { Transformation badTransformation = new Transformation() { @Override public RequestHandler.Result transform(RequestHandler.Result source) { source.getBitmap().recycle(); return source; } @Override public String key() { return "test"; } }; List<Transformation> transformations = Collections.singletonList(badTransformation); Bitmap original = Bitmap.createBitmap(10, 10, ARGB_8888); RequestHandler.Result result = new RequestHandler.Result(original, MEMORY, 0); Request data = new Request.Builder(URI_1).build(); try { BitmapHunter.applyTransformations(picasso, data, transformations, result); fail("Expected exception to be thrown."); } catch (RuntimeException e) { assertThat(e).hasMessageThat().isEqualTo("Transformation " + badTransformation.key() + " returned input Bitmap but recycled it."); } }
/** * Synchronously fulfill this request. Must not be called from the main thread. */ @Nullable // TODO make non-null and always throw? public Bitmap get() throws IOException { long started = System.nanoTime(); checkNotMain(); if (deferred) { throw new IllegalStateException("Fit cannot be used with get."); } if (!data.hasImage()) { return null; } Request request = createRequest(started); Action action = new GetAction(picasso, request); RequestHandler.Result result = forRequest(picasso, picasso.dispatcher, picasso.cache, picasso.stats, action).hunt(); Bitmap bitmap = result.getBitmap(); if (bitmap != null && shouldWriteToMemoryCache(request.memoryPolicy)) { picasso.cache.set(request.key, bitmap); } return bitmap; }
@Override public RequestHandler.Result transform(RequestHandler.Result source) { Bitmap bitmap = source.getBitmap(); if (bitmap == null) { return source; } Bitmap result = createBitmap(bitmap.getWidth(), bitmap.getHeight(), bitmap.getConfig()); Bitmap noise; try { noise = picasso.load(R.drawable.noise).get(); } catch (IOException e) { throw new RuntimeException("Failed to apply transformation! Missing resource."); } BitmapShader shader = new BitmapShader(noise, REPEAT, REPEAT); ColorMatrix colorMatrix = new ColorMatrix(); colorMatrix.setSaturation(0); ColorMatrixColorFilter filter = new ColorMatrixColorFilter(colorMatrix); Paint paint = new Paint(ANTI_ALIAS_FLAG); paint.setColorFilter(filter); Canvas canvas = new Canvas(result); canvas.drawBitmap(bitmap, 0, 0, paint); paint.setColorFilter(null); paint.setShader(shader); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.MULTIPLY)); canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), paint); bitmap.recycle(); noise.recycle(); return new RequestHandler.Result(result, source.getLoadedFrom(), source.getExifRotation()); }
@Test public void doesNotRecycleOriginalTransformationThrows() { Transformation badTransformation = new Transformation() { @Override public RequestHandler.Result transform(RequestHandler.Result source) { // Should recycle source. return new RequestHandler.Result(Bitmap.createBitmap(10, 10, ARGB_8888), MEMORY, 0); } @Override public String key() { return "test"; } }; List<Transformation> transformations = Collections.singletonList(badTransformation); Bitmap original = Bitmap.createBitmap(10, 10, ARGB_8888); RequestHandler.Result result = new RequestHandler.Result(original, MEMORY, 0); Request data = new Request.Builder(URI_1).build(); try { BitmapHunter.applyTransformations(picasso, data, transformations, result); fail("Expected exception to be thrown."); } catch (RuntimeException e) { assertThat(e).hasMessageThat().isEqualTo("Transformation " + badTransformation.key() + " mutated input Bitmap but failed to recycle the original."); } }
@Test public void recyclingInSuccessThrowsException() { BitmapTarget bad = new BitmapTarget() { @Override public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) { bitmap.recycle(); } @Override public void onBitmapFailed(Exception e, Drawable errorDrawable) { throw new AssertionError(); } @Override public void onPrepareLoad(Drawable placeHolderDrawable) { throw new AssertionError(); } }; Picasso picasso = mock(Picasso.class); Bitmap bitmap = makeBitmap(); BitmapTargetAction tr = new BitmapTargetAction(picasso, bad, null, null, 0); try { tr.complete(new RequestHandler.Result(bitmap, MEMORY)); fail(); } catch (IllegalStateException ignored) { } } }
@Override public void load(@NonNull Picasso picasso, @NonNull Request request, @NonNull Callback callback) { initializeIfFirstTime(); boolean signaledCallback = false; try { Source source = Okio.source(assetManager.open(getFilePath(request))); try { Bitmap bitmap = decodeStream(source, request); signaledCallback = true; callback.onSuccess(new Result(bitmap, DISK)); } finally { try { source.close(); } catch (IOException ignored) { } } } catch (Exception e) { if (!signaledCallback) { callback.onError(e); } } }
@Test public void nullResultFromTransformationThrows() { Transformation badTransformation = new Transformation() { @Override public RequestHandler.Result transform(RequestHandler.Result source) { return null; } @Override public String key() { return "test"; } }; List<Transformation> transformations = Collections.singletonList(badTransformation); Bitmap original = Bitmap.createBitmap(10, 10, ARGB_8888); RequestHandler.Result result = new RequestHandler.Result(original, MEMORY, 0); Request data = new Request.Builder(URI_1).build(); try { BitmapHunter.applyTransformations(picasso, data, transformations, result); fail("Expected exception to be thrown."); } catch (RuntimeException e) { assertThat(e).hasMessageThat().contains( "Transformation " + badTransformation.key() + " returned null"); } }
private void deliverAction(@Nullable RequestHandler.Result result, Action action, @Nullable Exception e) { if (action.cancelled) { return; } if (!action.willReplay) { targetToAction.remove(action.getTarget()); } if (result != null) { action.complete(result); if (loggingEnabled) { log(OWNER_MAIN, VERB_COMPLETED, action.request.logId(), "from " + result.getLoadedFrom()); } } else { Exception exception = checkNotNull(e, "e == null"); action.error(exception); if (loggingEnabled) { log(OWNER_MAIN, VERB_ERRORED, action.request.logId(), exception.getMessage()); } } }
void resumeAction(Action action) { Bitmap bitmap = null; if (shouldReadFromMemoryCache(action.request.memoryPolicy)) { bitmap = quickMemoryCacheCheck(action.request.key); } if (bitmap != null) { // Resumed action is cached, complete immediately. deliverAction(new RequestHandler.Result(bitmap, MEMORY), action, null); if (loggingEnabled) { log(OWNER_MAIN, VERB_COMPLETED, action.request.logId(), "from " + MEMORY); } } else { // Re-submit the action to the executor. enqueueAndSubmit(action); if (loggingEnabled) { log(OWNER_MAIN, VERB_RESUMED, action.request.logId()); } } }
@Test public void crashingOnTransformationThrows() { Transformation badTransformation = new Transformation() { @Override public RequestHandler.Result transform(RequestHandler.Result source) { throw new NullPointerException("hello"); } @Override public String key() { return "test"; } }; List<Transformation> transformations = Collections.singletonList(badTransformation); Bitmap original = Bitmap.createBitmap(10, 10, ARGB_8888); RequestHandler.Result result = new RequestHandler.Result(original, MEMORY, 0); Request data = new Request.Builder(URI_1).build(); try { BitmapHunter.applyTransformations(picasso, data, transformations, result); fail("Expected exception to be thrown."); } catch (RuntimeException e) { assertThat(e).hasMessageThat().isEqualTo("Transformation " + badTransformation.key() + " crashed with exception."); } }
@Test public void invokesTargetAndCallbackSuccessIfTargetIsNotNull() { Bitmap bitmap = makeBitmap(); Dispatcher dispatcher = mock(Dispatcher.class); PlatformLruCache cache = new PlatformLruCache(0); Picasso picasso = new Picasso(RuntimeEnvironment.application, dispatcher, UNUSED_CALL_FACTORY, null, cache, null, NO_TRANSFORMERS, NO_HANDLERS, mock(Stats.class), Bitmap.Config.ARGB_8888, false, false); ImageView target = mockImageViewTarget(); Callback callback = mockCallback(); ImageViewAction request = new ImageViewAction(picasso, target, null, null, 0, false, callback); request.complete(new RequestHandler.Result(bitmap, MEMORY)); verify(target).setImageDrawable(any(PicassoDrawable.class)); verify(callback).onSuccess(); }
@Override public void load(@NonNull Picasso picasso, @NonNull Request request, @NonNull Callback callback) { boolean signaledCallback = false; try { Uri requestUri = checkNotNull(request.uri, "request.uri == null"); Source source = getSource(requestUri); Bitmap bitmap = decodeStream(source, request); int exifRotation = getExifOrientation(requestUri); signaledCallback = true; callback.onSuccess(new Result(bitmap, DISK, exifRotation)); } catch (Exception e) { if (!signaledCallback) { callback.onError(e); } } }
@Override public void load(@NonNull Picasso picasso, @NonNull Request request, @NonNull Callback callback) { boolean signaledCallback = false; try { Uri requestUri = checkNotNull(request.uri, "request.uri == null"); Source source = getSource(requestUri); Bitmap bitmap = decodeStream(source, request); int exifRotation = getExifOrientation(requestUri); signaledCallback = true; callback.onSuccess(new Result(bitmap, DISK, exifRotation)); } catch (Exception e) { if (!signaledCallback) { callback.onError(e); } } }