summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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