Merge tag android-5.1.0_r1 into AOSP_5.1_MERGE
Change-Id: I74440e1db5ecfc0c63d0dde16112a4206bd55993
diff --git a/library/src/main/java/com/bumptech/glide/GenericRequestBuilder.java b/library/src/main/java/com/bumptech/glide/GenericRequestBuilder.java
index ba25c8d..a16469e 100644
--- a/library/src/main/java/com/bumptech/glide/GenericRequestBuilder.java
+++ b/library/src/main/java/com/bumptech/glide/GenericRequestBuilder.java
@@ -550,47 +550,6 @@
return into(glide.buildImageViewTarget(view, transcodeClass));
}
- private Request buildRequest(Target<TranscodeType> target) {
- final Request result;
-
- if (priority == null) {
- priority = Priority.NORMAL;
- }
-
- if (thumbnailRequestBuilder != null) {
- ThumbnailRequestCoordinator requestCoordinator = new ThumbnailRequestCoordinator();
- Request fullRequest = buildRequest(target, sizeMultiplier, priority, requestCoordinator);
-
- if (thumbnailRequestBuilder.animationFactory.equals(NoAnimation.getFactory())) {
- thumbnailRequestBuilder.animationFactory = animationFactory;
- }
-
- if (thumbnailRequestBuilder.requestListener == null && requestListener != null) {
- thumbnailRequestBuilder.requestListener = requestListener;
- }
-
- if (thumbnailRequestBuilder.priority == null) {
- thumbnailRequestBuilder.priority = getThumbnailPriority();
- }
-
- Request thumbnailRequest = thumbnailRequestBuilder.buildRequest(target,
- thumbnailRequestBuilder.sizeMultiplier, thumbnailRequestBuilder.priority, requestCoordinator);
-
- requestCoordinator.setRequests(fullRequest, thumbnailRequest);
- result = requestCoordinator;
- } else if (thumbSizeMultiplier != null) {
- ThumbnailRequestCoordinator requestCoordinator = new ThumbnailRequestCoordinator();
- Request fullRequest = buildRequest(target, sizeMultiplier, priority, requestCoordinator);
- Request thumbnailRequest = buildRequest(target, thumbSizeMultiplier, getThumbnailPriority(),
- requestCoordinator);
- requestCoordinator.setRequests(fullRequest, thumbnailRequest);
- result = requestCoordinator;
- } else {
- result = buildRequest(target, sizeMultiplier, priority, null);
- }
- return result;
- }
-
private Priority getThumbnailPriority() {
final Priority result;
if (priority == Priority.LOW) {
@@ -603,18 +562,53 @@
return result;
}
- private Request buildRequest(Target<TranscodeType> target, float sizeMultiplier, Priority priority,
- RequestCoordinator requestCoordinator) {
- if (model == null) {
- return buildRequestForDataType(target, loadProvider, sizeMultiplier, priority, null);
+ private Request buildRequest(Target<TranscodeType> target) {
+ if (priority == null) {
+ priority = Priority.NORMAL;
+ }
+ return buildRequestRecursive(target, null);
+ }
+
+ private Request buildRequestRecursive(Target<TranscodeType> target, ThumbnailRequestCoordinator parentCoordinator) {
+ if (thumbnailRequestBuilder != null) {
+ // Recursive case: contains a potentially recursive thumbnail request builder.
+ if (thumbnailRequestBuilder.animationFactory.equals(NoAnimation.getFactory())) {
+ thumbnailRequestBuilder.animationFactory = animationFactory;
+ }
+
+ if (thumbnailRequestBuilder.requestListener == null && requestListener != null) {
+ thumbnailRequestBuilder.requestListener = requestListener;
+ }
+
+ if (thumbnailRequestBuilder.priority == null) {
+ thumbnailRequestBuilder.priority = getThumbnailPriority();
+ }
+
+ ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
+ Request fullRequest = obtainRequest(target, sizeMultiplier, priority, coordinator);
+ // Recursively generate thumbnail requests.
+ Request thumbRequest = thumbnailRequestBuilder.buildRequestRecursive(target, coordinator);
+ coordinator.setRequests(fullRequest, thumbRequest);
+ return coordinator;
+ } else if (thumbSizeMultiplier != null) {
+ // Base case: thumbnail multiplier generates a thumbnail request, but cannot recurse.
+ ThumbnailRequestCoordinator coordinator = new ThumbnailRequestCoordinator(parentCoordinator);
+ Request fullRequest = obtainRequest(target, sizeMultiplier, priority, coordinator);
+ Request thumbnailRequest = obtainRequest(target, thumbSizeMultiplier, getThumbnailPriority(), coordinator);
+ coordinator.setRequests(fullRequest, thumbnailRequest);
+ return coordinator;
} else {
- return buildRequestForDataType(target, loadProvider, sizeMultiplier, priority, requestCoordinator);
+ // Base case: no thumbnail.
+ return obtainRequest(target, sizeMultiplier, priority, parentCoordinator);
}
}
- private <Z> Request buildRequestForDataType(Target<TranscodeType> target,
- LoadProvider<ModelType, Z, ResourceType, TranscodeType> loadProvider, float sizeMultiplier,
- Priority priority, RequestCoordinator requestCoordinator) {
+ private <Z> Request obtainRequest(Target<TranscodeType> target, float sizeMultiplier, Priority priority,
+ RequestCoordinator requestCoordinator) {
+ if (model == null) {
+ requestCoordinator = null;
+ }
+
return GenericRequest.obtain(
loadProvider,
model,
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/TransformationUtils.java b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/TransformationUtils.java
index 2714b6a..9cffbd8 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/bitmap/TransformationUtils.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/bitmap/TransformationUtils.java
@@ -79,20 +79,41 @@
*/
public static Bitmap fitCenter(Bitmap toFit, BitmapPool pool, int width, int height) {
if (toFit.getWidth() == width && toFit.getHeight() == height) {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "requested target size matches input, returning input");
+ }
return toFit;
}
final float widthPercentage = width / (float) toFit.getWidth();
final float heightPercentage = height / (float) toFit.getHeight();
final float minPercentage = Math.min(widthPercentage, heightPercentage);
- final int targetWidth = Math.round(minPercentage * toFit.getWidth());
- final int targetHeight = Math.round(minPercentage * toFit.getHeight());
+ // take the floor of the target width/height, not round. If the matrix
+ // passed into drawBitmap rounds differently, we want to slightly
+ // overdraw, not underdraw, to avoid artifacts from bitmap reuse.
+ final int targetWidth = (int) (minPercentage * toFit.getWidth());
+ final int targetHeight = (int) (minPercentage * toFit.getHeight());
+
+ if (toFit.getWidth() == targetWidth && toFit.getHeight() == targetHeight) {
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "adjusted target size matches input, returning input");
+ }
+ return toFit;
+ }
Bitmap.Config config = toFit.getConfig() != null ? toFit.getConfig() : Bitmap.Config.ARGB_8888;
Bitmap toReuse = pool.get(targetWidth, targetHeight, config);
if (toReuse == null) {
toReuse = Bitmap.createBitmap(targetWidth, targetHeight, config);
}
+
+ if (Log.isLoggable(TAG, Log.VERBOSE)) {
+ Log.v(TAG, "request: " + width + "x" + height);
+ Log.v(TAG, "toFit: " + toFit.getWidth() + "x" + toFit.getHeight());
+ Log.v(TAG, "toReuse: " + toReuse.getWidth() + "x" + toReuse.getHeight());
+ Log.v(TAG, "minPct: " + minPercentage);
+ }
+
Canvas canvas = new Canvas(toReuse);
Matrix matrix = new Matrix();
matrix.setScale(minPercentage, minPercentage);
diff --git a/library/src/main/java/com/bumptech/glide/load/resource/transcode/TranscoderFactory.java b/library/src/main/java/com/bumptech/glide/load/resource/transcode/TranscoderFactory.java
index 4dd76e3..83acb5c 100644
--- a/library/src/main/java/com/bumptech/glide/load/resource/transcode/TranscoderFactory.java
+++ b/library/src/main/java/com/bumptech/glide/load/resource/transcode/TranscoderFactory.java
@@ -70,8 +70,11 @@
if (decodedClass.equals(transcodedClass)) {
return UnitTranscoder.get();
}
- GET_KEY.set(decodedClass, transcodedClass);
- ResourceTranscoder<Z, R> result = factories.get(GET_KEY);
+ ResourceTranscoder<Z, R> result;
+ synchronized (GET_KEY) {
+ GET_KEY.set(decodedClass, transcodedClass);
+ result = factories.get(GET_KEY);
+ }
if (result == null) {
throw new IllegalArgumentException("No transcoder registered for " + decodedClass + " and "
+ transcodedClass);
diff --git a/library/src/main/java/com/bumptech/glide/manager/RequestManagerFragment.java b/library/src/main/java/com/bumptech/glide/manager/RequestManagerFragment.java
index c2260a7..21bd4b4 100644
--- a/library/src/main/java/com/bumptech/glide/manager/RequestManagerFragment.java
+++ b/library/src/main/java/com/bumptech/glide/manager/RequestManagerFragment.java
@@ -2,11 +2,14 @@
import android.annotation.TargetApi;
import android.app.Fragment;
+import android.util.Log;
+
import com.bumptech.glide.RequestManager;
@TargetApi(11)
public class RequestManagerFragment extends Fragment {
private RequestManager requestManager;
+ private static String TAG = "RequestManagerFragment";
public void setRequestManager(RequestManager requestManager) {
this.requestManager = requestManager;
@@ -28,7 +31,11 @@
public void onStop() {
super.onStop();
if (requestManager != null) {
- requestManager.onStop();
+ try {
+ requestManager.onStop();
+ } catch (RuntimeException e) {
+ Log.e(TAG, "exception during onStop", e);
+ }
}
}
@@ -36,7 +43,11 @@
public void onDestroy() {
super.onDestroy();
if (requestManager != null) {
- requestManager.onDestroy();
+ try {
+ requestManager.onDestroy();
+ } catch (RuntimeException e) {
+ Log.e(TAG, "exception during onDestroy", e);
+ }
}
}
}
diff --git a/library/src/main/java/com/bumptech/glide/provider/DataLoadProviderFactory.java b/library/src/main/java/com/bumptech/glide/provider/DataLoadProviderFactory.java
index 019b397..63d22a3 100644
--- a/library/src/main/java/com/bumptech/glide/provider/DataLoadProviderFactory.java
+++ b/library/src/main/java/com/bumptech/glide/provider/DataLoadProviderFactory.java
@@ -69,8 +69,11 @@
@SuppressWarnings("unchecked")
public <T, Z> DataLoadProvider<T, Z> get(Class<T> dataClass, Class<Z> resourceClass) {
- GET_KEY.set(dataClass, resourceClass);
- DataLoadProvider<T, Z> result = providers.get(GET_KEY);
+ DataLoadProvider<T, Z> result;
+ synchronized (GET_KEY) {
+ GET_KEY.set(dataClass, resourceClass);
+ result = providers.get(GET_KEY);
+ }
if (result == null) {
result = EmptyDataLoadProvider.get();
}
diff --git a/library/src/main/java/com/bumptech/glide/request/ThumbnailRequestCoordinator.java b/library/src/main/java/com/bumptech/glide/request/ThumbnailRequestCoordinator.java
index 319211b..d5ec86c 100644
--- a/library/src/main/java/com/bumptech/glide/request/ThumbnailRequestCoordinator.java
+++ b/library/src/main/java/com/bumptech/glide/request/ThumbnailRequestCoordinator.java
@@ -7,6 +7,15 @@
public class ThumbnailRequestCoordinator implements RequestCoordinator, Request {
private Request full;
private Request thumb;
+ private RequestCoordinator coordinator;
+
+ public ThumbnailRequestCoordinator() {
+ this(null);
+ }
+
+ public ThumbnailRequestCoordinator(RequestCoordinator coordinator) {
+ this.coordinator = coordinator;
+ }
public void setRequests(Request full, Request thumb) {
this.full = full;
@@ -15,17 +24,29 @@
@Override
public boolean canSetImage(Request request) {
- return request == full || !full.isComplete();
+ return parentCanSetImage() && (request == full || !full.isComplete());
+ }
+
+ private boolean parentCanSetImage() {
+ return coordinator == null || coordinator.canSetImage(this);
}
@Override
public boolean canSetPlaceholder(Request request) {
- return request == full && !isAnyRequestComplete();
+ return parentCanSetPlaceholder() && (request == full && !isAnyRequestComplete());
+ }
+
+ private boolean parentCanSetPlaceholder() {
+ return coordinator == null || coordinator.canSetPlaceholder(this);
}
@Override
public boolean isAnyRequestComplete() {
- return full.isComplete() || thumb.isComplete();
+ return parentIsAnyRequestComplete() || full.isComplete() || thumb.isComplete();
+ }
+
+ private boolean parentIsAnyRequestComplete() {
+ return coordinator != null && coordinator.isAnyRequestComplete();
}
@Override
@@ -51,7 +72,9 @@
@Override
public boolean isComplete() {
- return full.isComplete();
+ // TODO: this is a little strange, but we often want to avoid restarting the request or
+ // setting placeholders even if only the thumb is complete.
+ return full.isComplete() || thumb.isComplete();
}
@Override