Messaging: FrameSequence -> ImageDecoder
fixes playing / displaying gifs replaces old deprecated FrameSequence & FrameSequenceDrawable libs Change-Id: Id65fff90bdd09af86480636a8a0e404aeb39580f
This commit is contained in:
committed by
Michael Bestas
parent
b11039ed8c
commit
d8a0bf022d
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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<BitmapResult>
|
||||
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<BitmapResult>
|
||||
@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<BitmapResult>
|
||||
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<BitmapResult>
|
||||
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<BitmapResult>
|
||||
}
|
||||
mImageResource = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user