summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Leon Scroggins III <scroggo@google.com> 2018-03-19 10:51:44 -0400
committer Leon Scroggins III <scroggo@google.com> 2018-03-20 10:30:32 -0400
commit8290eaba47b99398fbe0bd59138f902bde558ecb (patch)
treea303264bcb7d5bc1df0e11929b7638e0bcbd701c
parent121ef98bfb0e34a2726dd0fb9112915017bfcde4 (diff)
Scale up in ImageDecoder based on API level
Bug: 74061412 Bug: 73893665 Test: Manual, I5669a97c70d726826c5c00bc1413c2f97d95d88c ImageDecoder typically does not scale a Bitmap up to handle density. This saves memory, and we already handle the density by scaling at draw time. But some apps rely on the size of the Bitmap without taking density into account. For backwards compatibility, on apps that are built for a pre-P version of Android, scale up in ImageDecoder. Change-Id: I9991d1286e386b47fc57bcfbf0c6652beb1a53ef
-rw-r--r--core/java/android/app/ActivityThread.java8
-rw-r--r--graphics/java/android/graphics/ImageDecoder.java22
2 files changed, 22 insertions, 8 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index afcd51572d51..2b7391d2a957 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -64,6 +64,7 @@ import android.database.sqlite.SQLiteDebug;
import android.database.sqlite.SQLiteDebug.DbStats;
import android.graphics.Bitmap;
import android.graphics.Canvas;
+import android.graphics.ImageDecoder;
import android.hardware.display.DisplayManagerGlobal;
import android.net.ConnectivityManager;
import android.net.IConnectivityManager;
@@ -5551,6 +5552,13 @@ public final class ActivityThread extends ClientTransactionHandler {
Message.updateCheckRecycle(data.appInfo.targetSdkVersion);
+ // Prior to P, internal calls to decode Bitmaps used BitmapFactory,
+ // which may scale up to account for density. In P, we switched to
+ // ImageDecoder, which skips the upscale to save memory. ImageDecoder
+ // needs to still scale up in older apps, in case they rely on the
+ // size of the Bitmap without considering its density.
+ ImageDecoder.sApiLevel = data.appInfo.targetSdkVersion;
+
/*
* Before spawning a new process, reset the time zone to be the system time zone.
* This needs to be done because the system time zone could have changed after the
diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java
index 5e81c377d41d..2f09c65a9bf7 100644
--- a/graphics/java/android/graphics/ImageDecoder.java
+++ b/graphics/java/android/graphics/ImageDecoder.java
@@ -34,6 +34,7 @@ import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.net.Uri;
+import android.os.Build;
import android.system.ErrnoException;
import android.system.Os;
import android.util.DisplayMetrics;
@@ -58,6 +59,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
* Class for decoding images as {@link Bitmap}s or {@link Drawable}s.
*/
public final class ImageDecoder implements AutoCloseable {
+ /** @hide **/
+ public static int sApiLevel;
+
/**
* Source of the encoded image data.
*/
@@ -1262,17 +1266,19 @@ public final class ImageDecoder implements AutoCloseable {
return srcDensity;
}
- // downscale the bitmap if the asset has a higher density than the default
+ // For P and above, only resize if it would be a downscale. Scale up prior
+ // to P in case the app relies on the Bitmap's size without considering density.
final int dstDensity = src.computeDstDensity();
- if (srcDensity != Bitmap.DENSITY_NONE && srcDensity > dstDensity) {
- float scale = (float) dstDensity / srcDensity;
- int scaledWidth = (int) (decoder.mWidth * scale + 0.5f);
- int scaledHeight = (int) (decoder.mHeight * scale + 0.5f);
- decoder.setResize(scaledWidth, scaledHeight);
- return dstDensity;
+ if (srcDensity == Bitmap.DENSITY_NONE || srcDensity == dstDensity
+ || (srcDensity < dstDensity && sApiLevel >= Build.VERSION_CODES.P)) {
+ return srcDensity;
}
- return srcDensity;
+ float scale = (float) dstDensity / srcDensity;
+ int scaledWidth = (int) (decoder.mWidth * scale + 0.5f);
+ int scaledHeight = (int) (decoder.mHeight * scale + 0.5f);
+ decoder.setResize(scaledWidth, scaledHeight);
+ return dstDensity;
}
@NonNull