diff --git a/src/com/android/messaging/datamodel/media/GifImageResource.java b/src/com/android/messaging/datamodel/media/GifImageResource.java index cbea1ee..ef43833 100644 --- a/src/com/android/messaging/datamodel/media/GifImageResource.java +++ b/src/com/android/messaging/datamodel/media/GifImageResource.java @@ -17,47 +17,47 @@ package com.android.messaging.datamodel.media; import android.content.res.Resources; import android.graphics.Bitmap; +import android.graphics.ImageDecoder; +import android.graphics.drawable.AnimatedImageDrawable; import android.graphics.drawable.Drawable; import android.media.ExifInterface; -import android.support.rastermill.FrameSequence; -import android.support.rastermill.FrameSequenceDrawable; import com.android.messaging.util.Assert; import com.android.messaging.util.LogUtil; -import java.io.IOException; import java.io.InputStream; public class GifImageResource extends ImageResource { - private FrameSequence mFrameSequence; + private ImageDecoder.Source mImageDecoderSource; - public GifImageResource(String key, FrameSequence frameSequence) { + public GifImageResource(String key, ImageDecoder.Source imageDecoderSource) { // GIF does not support exif tags super(key, ExifInterface.ORIENTATION_NORMAL); - mFrameSequence = frameSequence; + mImageDecoderSource = imageDecoderSource; } public static GifImageResource createGifImageResource(String key, InputStream inputStream) { - final FrameSequence frameSequence; + final byte[] bytes; try { - frameSequence = FrameSequence.decodeStream(inputStream); - } finally { - try { - inputStream.close(); - } catch (IOException e) { - // Nothing to do if we fail closing the stream - } - } - if (frameSequence == null) { + bytes = inputStream.readAllBytes(); + } catch (Exception e) { + e.printStackTrace(); return null; } - return new GifImageResource(key, frameSequence); + + // prepare mImageDecoderSource + final ImageDecoder imageDecoder; + ImageDecoder.Source source = ImageDecoder.createSource(bytes); + if (source == null) { + return null; + } + return new GifImageResource(key, source); } @Override public Drawable getDrawable(Resources resources) { try { - return new FrameSequenceDrawable(mFrameSequence); + return (AnimatedImageDrawable) ImageDecoder.decodeDrawable(mImageDecoderSource); } catch (final Throwable t) { // Malicious gif images can make the platform throw different kind of throwables, such // as OutOfMemoryError and NullPointerException. Catch them all. @@ -85,9 +85,6 @@ public class GifImageResource extends ImageResource { @Override public boolean supportsBitmapReuse() { - // FrameSequenceDrawable a.) takes two bitmaps and thus does not fit into the current - // bitmap pool architecture b.) will rarely use bitmaps from one FrameSequenceDrawable to - // the next that are the same sizes since they are used by attachments. return false; } @@ -107,12 +104,11 @@ public class GifImageResource extends ImageResource { protected void close() { acquireLock(); try { - if (mFrameSequence != null) { - mFrameSequence = null; + if (mImageDecoderSource != null) { + mImageDecoderSource = null; } } finally { releaseLock(); } } - } diff --git a/src/com/android/messaging/ui/AsyncImageView.java b/src/com/android/messaging/ui/AsyncImageView.java index 7d057b3..0d3fd16 100644 --- a/src/com/android/messaging/ui/AsyncImageView.java +++ b/src/com/android/messaging/ui/AsyncImageView.java @@ -22,10 +22,10 @@ import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Path; import android.graphics.RectF; +import android.graphics.drawable.AnimatedImageDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import androidx.annotation.Nullable; -import android.support.rastermill.FrameSequenceDrawable; import android.text.TextUtils; import android.util.AttributeSet; import android.widget.ImageView; @@ -194,8 +194,8 @@ public class AsyncImageView extends ImageView implements MediaResourceLoadListen mImageResource = resource; mImageResource.addRef(); setImageDrawable(drawable); - if (drawable instanceof FrameSequenceDrawable) { - ((FrameSequenceDrawable) drawable).start(); + if (drawable instanceof AnimatedImageDrawable) { + ((AnimatedImageDrawable) drawable).start(); } if (getVisibility() == VISIBLE) { @@ -249,9 +249,8 @@ public class AsyncImageView extends ImageView implements MediaResourceLoadListen private void releaseImageResource() { final Drawable drawable = getDrawable(); - if (drawable instanceof FrameSequenceDrawable) { - ((FrameSequenceDrawable) drawable).stop(); - ((FrameSequenceDrawable) drawable).destroy(); + if (drawable instanceof AnimatedImageDrawable) { + ((AnimatedImageDrawable) drawable).stop(); } if (mImageResource != null) { mImageResource.release(); diff --git a/src/com/android/messaging/ui/photoviewer/BuglePhotoBitmapLoader.java b/src/com/android/messaging/ui/photoviewer/BuglePhotoBitmapLoader.java index 9911456..2116b1e 100644 --- a/src/com/android/messaging/ui/photoviewer/BuglePhotoBitmapLoader.java +++ b/src/com/android/messaging/ui/photoviewer/BuglePhotoBitmapLoader.java @@ -18,7 +18,6 @@ package com.android.messaging.ui.photoviewer; import android.content.Context; import android.graphics.drawable.Drawable; import android.net.Uri; -import android.support.rastermill.FrameSequenceDrawable; import androidx.loader.content.AsyncTaskLoader; import com.android.ex.photo.PhotoViewController; @@ -91,7 +90,6 @@ public class BuglePhotoBitmapLoader extends AsyncTaskLoader final Drawable drawable = result != null ? result.drawable : null; if (isReset()) { // An async query came in while the loader is stopped. We don't need the result. - releaseDrawable(drawable); return; } @@ -140,11 +138,6 @@ public class BuglePhotoBitmapLoader extends AsyncTaskLoader @Override public void onCanceled(BitmapResult result) { super.onCanceled(result); - - // At this point we can release the resources associated with 'drawable' if needed. - if (result != null) { - releaseDrawable(result.drawable); - } } /** @@ -160,14 +153,6 @@ public class BuglePhotoBitmapLoader extends AsyncTaskLoader releaseImageResource(); } - private void releaseDrawable(Drawable drawable) { - if (drawable != null && drawable instanceof FrameSequenceDrawable - && !((FrameSequenceDrawable) drawable).isDestroyed()) { - ((FrameSequenceDrawable) drawable).destroy(); - } - - } - private void setImageResource(final ImageResource resource) { if (mImageResource != resource) { // Clear out any information for what is currently used @@ -181,7 +166,6 @@ public class BuglePhotoBitmapLoader extends AsyncTaskLoader private void releaseImageResource() { // If we are getting rid of the imageResource backing the drawable, we must also // destroy the drawable before releasing it. - releaseDrawable(mDrawable); mDrawable = null; if (mImageResource != null) { @@ -189,4 +173,4 @@ public class BuglePhotoBitmapLoader extends AsyncTaskLoader } mImageResource = null; } -} \ No newline at end of file +} diff --git a/src/com/android/messaging/ui/photoviewer/BuglePhotoViewFragment.java b/src/com/android/messaging/ui/photoviewer/BuglePhotoViewFragment.java index a6293dc..de05855 100644 --- a/src/com/android/messaging/ui/photoviewer/BuglePhotoViewFragment.java +++ b/src/com/android/messaging/ui/photoviewer/BuglePhotoViewFragment.java @@ -16,8 +16,8 @@ package com.android.messaging.ui.photoviewer; import android.content.Intent; +import android.graphics.drawable.AnimatedImageDrawable; import android.graphics.drawable.Drawable; -import android.support.rastermill.FrameSequenceDrawable; import androidx.loader.content.Loader; import com.android.ex.photo.PhotoViewCallbacks; @@ -75,15 +75,15 @@ public class BuglePhotoViewFragment extends PhotoViewFragment { private void stopGif() { final Drawable drawable = getDrawable(); - if (drawable != null && drawable instanceof FrameSequenceDrawable) { - ((FrameSequenceDrawable) drawable).stop(); + if (drawable != null && drawable instanceof AnimatedImageDrawable) { + ((AnimatedImageDrawable) drawable).stop(); } } private void startGif() { final Drawable drawable = getDrawable(); - if (drawable != null && drawable instanceof FrameSequenceDrawable) { - ((FrameSequenceDrawable) drawable).start(); + if (drawable != null && drawable instanceof AnimatedImageDrawable) { + ((AnimatedImageDrawable) drawable).start(); } } }