diff options
| -rw-r--r-- | core/java/android/content/res/ResourcesImpl.java | 11 | ||||
| -rw-r--r-- | graphics/java/android/graphics/ImageDecoder.java | 65 |
2 files changed, 68 insertions, 8 deletions
diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java index 97cb78bc4243..00e4841044cd 100644 --- a/core/java/android/content/res/ResourcesImpl.java +++ b/core/java/android/content/res/ResourcesImpl.java @@ -27,9 +27,11 @@ import android.annotation.StyleRes; import android.annotation.StyleableRes; import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo.Config; +import android.content.res.AssetManager.AssetInputStream; import android.content.res.Configuration.NativeConfig; import android.content.res.Resources.NotFoundException; import android.graphics.Bitmap; +import android.graphics.ImageDecoder; import android.graphics.Typeface; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; @@ -809,8 +811,13 @@ public class ResourcesImpl { } else { final InputStream is = mAssets.openNonAsset( value.assetCookie, file, AssetManager.ACCESS_STREAMING); - dr = Drawable.createFromResourceStream(wrapper, value, is, file, null); - is.close(); + AssetInputStream ais = (AssetInputStream) is; + // ImageDecoder will close the input stream. + ImageDecoder.Source src = new ImageDecoder.AssetInputStreamSource(ais, + wrapper, value); + dr = ImageDecoder.decodeDrawable(src, (decoder, info, s) -> { + decoder.setAllocator(ImageDecoder.ALLOCATOR_SOFTWARE); + }); } } finally { stack.pop(); diff --git a/graphics/java/android/graphics/ImageDecoder.java b/graphics/java/android/graphics/ImageDecoder.java index acefead785c4..3cca47b47a59 100644 --- a/graphics/java/android/graphics/ImageDecoder.java +++ b/graphics/java/android/graphics/ImageDecoder.java @@ -25,7 +25,7 @@ import android.annotation.Nullable; import android.annotation.RawRes; import android.content.ContentResolver; import android.content.res.AssetFileDescriptor; -import android.content.res.AssetManager; +import android.content.res.AssetManager.AssetInputStream; import android.content.res.Resources; import android.graphics.drawable.AnimatedImageDrawable; import android.graphics.drawable.Drawable; @@ -263,6 +263,63 @@ public final class ImageDecoder implements AutoCloseable { } } + /** + * Takes ownership of the AssetInputStream. + * + * @hide + */ + public static class AssetInputStreamSource extends Source { + public AssetInputStreamSource(@NonNull AssetInputStream ais, + @NonNull Resources res, @NonNull TypedValue value) { + mAssetInputStream = ais; + mResources = res; + + if (value.density == TypedValue.DENSITY_DEFAULT) { + mDensity = DisplayMetrics.DENSITY_DEFAULT; + } else if (value.density != TypedValue.DENSITY_NONE) { + mDensity = value.density; + } else { + mDensity = Bitmap.DENSITY_NONE; + } + } + + private AssetInputStream mAssetInputStream; + private final Resources mResources; + private final int mDensity; + + @Override + public Resources getResources() { return mResources; } + + @Override + public int getDensity() { + return mDensity; + } + + @Override + public ImageDecoder createImageDecoder() throws IOException { + ImageDecoder decoder = null; + synchronized (this) { + if (mAssetInputStream == null) { + throw new IOException("Cannot reuse AssetInputStreamSource"); + } + AssetInputStream ais = mAssetInputStream; + mAssetInputStream = null; + try { + long asset = ais.getNativeAsset(); + decoder = nCreate(asset); + } finally { + if (decoder == null) { + IoUtils.closeQuietly(ais); + } else { + decoder.mInputStream = ais; + decoder.mOwnsInputStream = true; + } + } + return decoder; + } + } + } + private static class ResourceSource extends Source { ResourceSource(@NonNull Resources res, int resId) { mResources = res; @@ -296,11 +353,7 @@ public final class ImageDecoder implements AutoCloseable { mResDensity = value.density; } - if (!(is instanceof AssetManager.AssetInputStream)) { - // This should never happen. - throw new RuntimeException("Resource is not an asset?"); - } - long asset = ((AssetManager.AssetInputStream) is).getNativeAsset(); + long asset = ((AssetInputStream) is).getNativeAsset(); decoder = nCreate(asset); } finally { if (decoder == null) { |