diff options
| author | 2018-03-19 10:51:44 -0400 | |
|---|---|---|
| committer | 2018-03-20 10:30:32 -0400 | |
| commit | 8290eaba47b99398fbe0bd59138f902bde558ecb (patch) | |
| tree | a303264bcb7d5bc1df0e11929b7638e0bcbd701c | |
| parent | 121ef98bfb0e34a2726dd0fb9112915017bfcde4 (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.java | 8 | ||||
| -rw-r--r-- | graphics/java/android/graphics/ImageDecoder.java | 22 |
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 |