From ac9c8f7c1e4cc608ff78217b7849351d7f77d90c Mon Sep 17 00:00:00 2001 From: Leon Scroggins III Date: Mon, 12 Feb 2018 11:45:01 -0500 Subject: Revert "Use ImageDecoder for NinePatchDrawable and BitmapDrawable" Test: CTS tests This reverts commit 5aec67ca1baaa5ce7af5062cec0437a72969d2f9. Reason for revert: b/73166619 Bug: 73166619 Change-Id: Ic8b2a83abf5567119c8b6af1ec00445a5a6a9cc2 --- core/java/android/view/PointerIcon.java | 37 +--------- graphics/java/android/graphics/ImageDecoder.java | 28 +------ .../android/graphics/drawable/BitmapDrawable.java | 85 +++++++--------------- .../java/android/graphics/drawable/Drawable.java | 44 ++--------- .../graphics/drawable/NinePatchDrawable.java | 21 ++---- 5 files changed, 43 insertions(+), 172 deletions(-) diff --git a/core/java/android/view/PointerIcon.java b/core/java/android/view/PointerIcon.java index 8cb46b704c18..3fd469630db0 100644 --- a/core/java/android/view/PointerIcon.java +++ b/core/java/android/view/PointerIcon.java @@ -23,10 +23,6 @@ import android.content.res.Resources; import android.content.res.TypedArray; import android.content.res.XmlResourceParser; import android.graphics.Bitmap; -import android.graphics.Canvas; -import android.graphics.Paint; -import android.graphics.Rect; -import android.graphics.RectF; import android.graphics.drawable.AnimationDrawable; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; @@ -400,33 +396,6 @@ public final class PointerIcon implements Parcelable { return true; } - /** - * Get the Bitmap from the Drawable. - * - * If the Bitmap needed to be scaled up to account for density, BitmapDrawable - * handles this at draw time. But this class doesn't actually draw the Bitmap; - * it is just a holder for native code to access its SkBitmap. So this needs to - * get a version that is scaled to account for density. - */ - private Bitmap getBitmapFromDrawable(BitmapDrawable bitmapDrawable) { - Bitmap bitmap = bitmapDrawable.getBitmap(); - final int scaledWidth = bitmapDrawable.getIntrinsicWidth(); - final int scaledHeight = bitmapDrawable.getIntrinsicHeight(); - if (scaledWidth == bitmap.getWidth() && scaledHeight == bitmap.getHeight()) { - return bitmap; - } - - Rect src = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); - RectF dst = new RectF(0, 0, scaledWidth, scaledHeight); - - Bitmap scaled = Bitmap.createBitmap(scaledWidth, scaledHeight, bitmap.getConfig()); - Canvas canvas = new Canvas(scaled); - Paint paint = new Paint(); - paint.setFilterBitmap(true); - canvas.drawBitmap(bitmap, src, dst, paint); - return scaled; - } - private void loadResource(Context context, Resources resources, @XmlRes int resourceId) { final XmlResourceParser parser = resources.getXml(resourceId); final int bitmapRes; @@ -483,8 +452,7 @@ public final class PointerIcon implements Parcelable { + "is different. All frames should have the exact same size and " + "share the same hotspot."); } - BitmapDrawable bitmapDrawableFrame = (BitmapDrawable) drawableFrame; - mBitmapFrames[i - 1] = getBitmapFromDrawable(bitmapDrawableFrame); + mBitmapFrames[i - 1] = ((BitmapDrawable)drawableFrame).getBitmap(); } } } @@ -493,8 +461,7 @@ public final class PointerIcon implements Parcelable { + "refer to a bitmap drawable."); } - BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable; - final Bitmap bitmap = getBitmapFromDrawable(bitmapDrawable); + final Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap(); validateHotSpot(bitmap, hotSpotX, hotSpotY); // Set the properties now that we have successfully loaded the icon. mBitmap = bitmap; diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java index acefead785c4..ee7abc5bd254 100644 --- a/graphics/java/android/graphics/ImageDecoder.java +++ b/graphics/java/android/graphics/ImageDecoder.java @@ -444,7 +444,6 @@ public final class ImageDecoder implements AutoCloseable { private boolean mPreferRamOverQuality = false; private boolean mAsAlphaMask = false; private Rect mCropRect; - private Rect mOutPaddingRect; private Source mSource; private PostProcessor mPostProcessor; @@ -782,18 +781,6 @@ public final class ImageDecoder implements AutoCloseable { mCropRect = subset; } - /** - * Set a Rect for retrieving nine patch padding. - * - * If the image is a nine patch, this Rect will be set to the padding - * rectangle during decode. Otherwise it will not be modified. - * - * @hide - */ - public void setOutPaddingRect(@NonNull Rect outPadding) { - mOutPaddingRect = outPadding; - } - /** * Specify whether the {@link Bitmap} should be mutable. * @@ -905,6 +892,7 @@ public final class ImageDecoder implements AutoCloseable { postProcessPtr, mDesiredWidth, mDesiredHeight, mCropRect, mMutable, mAllocator, mRequireUnpremultiplied, mPreferRamOverQuality, mAsAlphaMask); + } private void callHeaderDecoded(@Nullable OnHeaderDecodedListener listener, @@ -977,10 +965,7 @@ public final class ImageDecoder implements AutoCloseable { if (np != null && NinePatch.isNinePatchChunk(np)) { Rect opticalInsets = new Rect(); bm.getOpticalInsets(opticalInsets); - Rect padding = decoder.mOutPaddingRect; - if (padding == null) { - padding = new Rect(); - } + Rect padding = new Rect(); nGetPadding(decoder.mNativePtr, padding); return new NinePatchDrawable(res, bm, np, padding, opticalInsets, null); @@ -1023,15 +1008,6 @@ public final class ImageDecoder implements AutoCloseable { final int srcDensity = computeDensity(src, decoder); Bitmap bm = decoder.decodeBitmap(); bm.setDensity(srcDensity); - - Rect padding = decoder.mOutPaddingRect; - if (padding != null) { - byte[] np = bm.getNinePatchChunk(); - if (np != null && NinePatch.isNinePatchChunk(np)) { - nGetPadding(decoder.mNativePtr, padding); - } - } - return bm; } } diff --git a/graphics/java/android/graphics/drawable/BitmapDrawable.java b/graphics/java/android/graphics/drawable/BitmapDrawable.java index 44b783bb6e63..7ad062a6f6f9 100644 --- a/graphics/java/android/graphics/drawable/BitmapDrawable.java +++ b/graphics/java/android/graphics/drawable/BitmapDrawable.java @@ -27,7 +27,6 @@ import android.graphics.BitmapFactory; import android.graphics.BitmapShader; import android.graphics.Canvas; import android.graphics.ColorFilter; -import android.graphics.ImageDecoder; import android.graphics.Insets; import android.graphics.Matrix; import android.graphics.Outline; @@ -50,7 +49,6 @@ import com.android.internal.R; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; -import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; @@ -113,7 +111,7 @@ public class BitmapDrawable extends Drawable { */ @Deprecated public BitmapDrawable() { - init(new BitmapState((Bitmap) null), null); + mBitmapState = new BitmapState((Bitmap) null); } /** @@ -126,7 +124,8 @@ public class BitmapDrawable extends Drawable { @SuppressWarnings("unused") @Deprecated public BitmapDrawable(Resources res) { - init(new BitmapState((Bitmap) null), res); + mBitmapState = new BitmapState((Bitmap) null); + mBitmapState.mTargetDensity = mTargetDensity; } /** @@ -136,7 +135,7 @@ public class BitmapDrawable extends Drawable { */ @Deprecated public BitmapDrawable(Bitmap bitmap) { - init(new BitmapState(bitmap), null); + this(new BitmapState(bitmap), null); } /** @@ -144,7 +143,8 @@ public class BitmapDrawable extends Drawable { * the display metrics of the resources. */ public BitmapDrawable(Resources res, Bitmap bitmap) { - init(new BitmapState(bitmap), res); + this(new BitmapState(bitmap), res); + mBitmapState.mTargetDensity = mTargetDensity; } /** @@ -154,7 +154,10 @@ public class BitmapDrawable extends Drawable { */ @Deprecated public BitmapDrawable(String filepath) { - this(null, filepath); + this(new BitmapState(BitmapFactory.decodeFile(filepath)), null); + if (mBitmapState.mBitmap == null) { + android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + filepath); + } } /** @@ -162,21 +165,10 @@ public class BitmapDrawable extends Drawable { */ @SuppressWarnings({ "unused", "ChainingConstructorIgnoresParameter" }) public BitmapDrawable(Resources res, String filepath) { - Bitmap bitmap = null; - try (FileInputStream stream = new FileInputStream(filepath)) { - bitmap = ImageDecoder.decodeBitmap(ImageDecoder.createSource(res, stream), - (decoder, info, src) -> { - decoder.setAllocator(ImageDecoder.ALLOCATOR_SOFTWARE); - }); - } catch (Exception e) { - /* do nothing. This matches the behavior of BitmapFactory.decodeFile() - If the exception happened on decode, mBitmapState.mBitmap will be null. - */ - } finally { - init(new BitmapState(bitmap), res); - if (mBitmapState.mBitmap == null) { - android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + filepath); - } + this(new BitmapState(BitmapFactory.decodeFile(filepath)), null); + mBitmapState.mTargetDensity = mTargetDensity; + if (mBitmapState.mBitmap == null) { + android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + filepath); } } @@ -187,7 +179,10 @@ public class BitmapDrawable extends Drawable { */ @Deprecated public BitmapDrawable(java.io.InputStream is) { - this(null, is); + this(new BitmapState(BitmapFactory.decodeStream(is)), null); + if (mBitmapState.mBitmap == null) { + android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + is); + } } /** @@ -195,21 +190,10 @@ public class BitmapDrawable extends Drawable { */ @SuppressWarnings({ "unused", "ChainingConstructorIgnoresParameter" }) public BitmapDrawable(Resources res, java.io.InputStream is) { - Bitmap bitmap = null; - try { - bitmap = ImageDecoder.decodeBitmap(ImageDecoder.createSource(res, is), - (decoder, info, src) -> { - decoder.setAllocator(ImageDecoder.ALLOCATOR_SOFTWARE); - }); - } catch (Exception e) { - /* do nothing. This matches the behavior of BitmapFactory.decodeStream() - If the exception happened on decode, mBitmapState.mBitmap will be null. - */ - } finally { - init(new BitmapState(bitmap), res); - if (mBitmapState.mBitmap == null) { - android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + is); - } + this(new BitmapState(BitmapFactory.decodeStream(is)), null); + mBitmapState.mTargetDensity = mTargetDensity; + if (mBitmapState.mBitmap == null) { + android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + is); } } @@ -828,19 +812,9 @@ public class BitmapDrawable extends Drawable { } } - int density = Bitmap.DENSITY_NONE; - if (value.density == TypedValue.DENSITY_DEFAULT) { - density = DisplayMetrics.DENSITY_DEFAULT; - } else if (value.density != TypedValue.DENSITY_NONE) { - density = value.density; - } - Bitmap bitmap = null; try (InputStream is = r.openRawResource(srcResId, value)) { - ImageDecoder.Source source = ImageDecoder.createSource(r, is, density); - bitmap = ImageDecoder.decodeBitmap(source, (decoder, info, src) -> { - decoder.setAllocator(ImageDecoder.ALLOCATOR_SOFTWARE); - }); + bitmap = BitmapFactory.decodeResourceStream(r, value, is, null, null); } catch (Exception e) { // Do nothing and pick up the error below. } @@ -1039,21 +1013,14 @@ public class BitmapDrawable extends Drawable { } } - private BitmapDrawable(BitmapState state, Resources res) { - init(state, res); - } - /** - * The one helper to rule them all. This is called by all public & private + * The one constructor to rule them all. This is called by all public * constructors to set the state and initialize local properties. */ - private void init(BitmapState state, Resources res) { + private BitmapDrawable(BitmapState state, Resources res) { mBitmapState = state; - updateLocalState(res); - if (mBitmapState != null && res != null) { - mBitmapState.mTargetDensity = mTargetDensity; - } + updateLocalState(res); } /** diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java index 8af2fd8bbb5e..05533d787aa1 100644 --- a/graphics/java/android/graphics/drawable/Drawable.java +++ b/graphics/java/android/graphics/drawable/Drawable.java @@ -37,7 +37,6 @@ import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.ColorFilter; -import android.graphics.ImageDecoder; import android.graphics.Insets; import android.graphics.NinePatch; import android.graphics.Outline; @@ -51,13 +50,11 @@ import android.graphics.Xfermode; import android.os.Trace; import android.util.AttributeSet; import android.util.DisplayMetrics; -import android.util.Log; import android.util.StateSet; import android.util.TypedValue; import android.util.Xml; import android.view.View; -import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.ref.WeakReference; @@ -1182,10 +1179,6 @@ public abstract class Drawable { return null; } - if (opts == null) { - return getBitmapDrawable(res, value, is); - } - /* ugh. The decodeStream contract is that we have already allocated the pad rect, but if the bitmap does not had a ninepatch chunk, then the pad will be ignored. If we could change this to lazily @@ -1201,6 +1194,7 @@ public abstract class Drawable { // an application in compatibility mode, without scaling those down // to the compatibility density only to have them scaled back up when // drawn to the screen. + if (opts == null) opts = new BitmapFactory.Options(); opts.inScreenDensity = Drawable.resolveDensity(res, 0); Bitmap bm = BitmapFactory.decodeResourceStream(res, value, is, pad, opts); if (bm != null) { @@ -1217,33 +1211,6 @@ public abstract class Drawable { return null; } - private static Drawable getBitmapDrawable(Resources res, TypedValue value, InputStream is) { - try { - ImageDecoder.Source source = null; - if (value != null) { - int density = Bitmap.DENSITY_NONE; - if (value.density == TypedValue.DENSITY_DEFAULT) { - density = DisplayMetrics.DENSITY_DEFAULT; - } else if (value.density != TypedValue.DENSITY_NONE) { - density = value.density; - } - source = ImageDecoder.createSource(res, is, density); - } else { - source = ImageDecoder.createSource(res, is); - } - - return ImageDecoder.decodeDrawable(source, (decoder, info, src) -> { - decoder.setAllocator(ImageDecoder.ALLOCATOR_SOFTWARE); - }); - } catch (IOException e) { - /* do nothing. - If the exception happened on decode, the drawable will be null. - */ - Log.e("Drawable", "Unable to decode stream: " + e); - } - return null; - } - /** * Create a drawable from an XML document. For more information on how to * create resources in XML, see @@ -1343,10 +1310,11 @@ public abstract class Drawable { } Trace.traceBegin(Trace.TRACE_TAG_RESOURCES, pathName); - try (FileInputStream stream = new FileInputStream(pathName)) { - return getBitmapDrawable(null, null, stream); - } catch(IOException e) { - // Do nothing; we will just return null if the FileInputStream had an error + try { + Bitmap bm = BitmapFactory.decodeFile(pathName); + if (bm != null) { + return drawableFromBitmap(null, bm, null, null, null, pathName); + } } finally { Trace.traceEnd(Trace.TRACE_TAG_RESOURCES); } diff --git a/graphics/java/android/graphics/drawable/NinePatchDrawable.java b/graphics/java/android/graphics/drawable/NinePatchDrawable.java index a56e8d1b25ed..17900204fa22 100644 --- a/graphics/java/android/graphics/drawable/NinePatchDrawable.java +++ b/graphics/java/android/graphics/drawable/NinePatchDrawable.java @@ -24,9 +24,9 @@ import android.content.res.Resources; import android.content.res.Resources.Theme; import android.content.res.TypedArray; import android.graphics.Bitmap; +import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.ColorFilter; -import android.graphics.ImageDecoder; import android.graphics.Insets; import android.graphics.NinePatch; import android.graphics.Outline; @@ -211,8 +211,7 @@ public class NinePatchDrawable extends Drawable { restoreAlpha = -1; } - final boolean needsDensityScaling = canvas.getDensity() == 0 - && Bitmap.DENSITY_NONE != state.mNinePatch.getDensity(); + final boolean needsDensityScaling = canvas.getDensity() == 0; if (needsDensityScaling) { restoreToCount = restoreToCount >= 0 ? restoreToCount : canvas.save(); @@ -422,6 +421,10 @@ public class NinePatchDrawable extends Drawable { final int srcResId = a.getResourceId(R.styleable.NinePatchDrawable_src, 0); if (srcResId != 0) { + final BitmapFactory.Options options = new BitmapFactory.Options(); + options.inDither = !state.mDither; + options.inScreenDensity = r.getDisplayMetrics().noncompatDensityDpi; + final Rect padding = new Rect(); final Rect opticalInsets = new Rect(); Bitmap bitmap = null; @@ -430,17 +433,7 @@ public class NinePatchDrawable extends Drawable { final TypedValue value = new TypedValue(); final InputStream is = r.openRawResource(srcResId, value); - int density = Bitmap.DENSITY_NONE; - if (value.density == TypedValue.DENSITY_DEFAULT) { - density = DisplayMetrics.DENSITY_DEFAULT; - } else if (value.density != TypedValue.DENSITY_NONE) { - density = value.density; - } - ImageDecoder.Source source = ImageDecoder.createSource(r, is, density); - bitmap = ImageDecoder.decodeBitmap(source, (decoder, info, src) -> { - decoder.setOutPaddingRect(padding); - decoder.setAllocator(ImageDecoder.ALLOCATOR_SOFTWARE); - }); + bitmap = BitmapFactory.decodeResourceStream(r, value, is, padding, options); is.close(); } catch (IOException e) { -- cgit v1.2.3-59-g8ed1b