Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e7addfc9 authored by Leon Scroggins III's avatar Leon Scroggins III Committed by Derek Sollenberger
Browse files

Revert "Use ImageDecoder for BitmapDrawable"

Bug: 72381918
Test: Covered by existing tests

This CL seems to have broken the theme tests. In addition, it changes
the behavior of a couple of cases of passing InputStreams to the
framework. Previously, the framework used BitmapFactory, which did not
close the InputStreams, but ImageDecoder does.

Planning to reland along with the fix for closing in ag/3497523 and the
fix for the theme tests.

This reverts commit 66c6d789.

Change-Id: I4ac6d0f2e1e2bb0925ae71c141bfe8a0d37e6a16
parent d66cfdfc
Loading
Loading
Loading
Loading
+26 −59
Original line number Diff line number Diff line
@@ -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,23 +165,12 @@ public class BitmapDrawable extends Drawable {
     */
    @SuppressWarnings("unused")
    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);
        this(new BitmapState(BitmapFactory.decodeFile(filepath)), null);
        mBitmapState.mTargetDensity = mTargetDensity;
        if (mBitmapState.mBitmap == null) {
            android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + filepath);
        }
    }
    }

    /**
     * Create a drawable by decoding a bitmap from the given input stream.
@@ -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,23 +190,12 @@ public class BitmapDrawable extends Drawable {
     */
    @SuppressWarnings("unused")
    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);
        this(new BitmapState(BitmapFactory.decodeStream(is)), null);
        mBitmapState.mTargetDensity = mTargetDensity;
        if (mBitmapState.mBitmap == null) {
            android.util.Log.w("BitmapDrawable", "BitmapDrawable cannot decode " + is);
        }
    }
    }

    /**
     * Returns the paint used to render this drawable.
@@ -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);
    }

    /**
+5 −38
Original line number Diff line number Diff line
@@ -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;
@@ -1178,10 +1175,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
@@ -1214,33 +1207,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
@@ -1340,10 +1306,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);
        }