Support animated notification icon snapshots
This commit is contained in:
@@ -11,6 +11,7 @@ import android.graphics.Path;
|
|||||||
import android.graphics.PorterDuff;
|
import android.graphics.PorterDuff;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.RectF;
|
import android.graphics.RectF;
|
||||||
|
import android.graphics.drawable.AnimationDrawable;
|
||||||
import android.graphics.drawable.BitmapDrawable;
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
import android.graphics.drawable.Drawable;
|
import android.graphics.drawable.Drawable;
|
||||||
import android.os.BatteryManager;
|
import android.os.BatteryManager;
|
||||||
@@ -239,9 +240,24 @@ final class SnapshotRenderer {
|
|||||||
proxy.setTag(key);
|
proxy.setTag(key);
|
||||||
proxyChanged = true;
|
proxyChanged = true;
|
||||||
}
|
}
|
||||||
|
SnapshotRenderState desiredState = renderStateFor(placement);
|
||||||
|
Drawable animatedDrawable = animatedNotificationDrawable(placement);
|
||||||
|
if (animatedDrawable != null) {
|
||||||
|
SnapshotRenderState currentState = statesByProxy.get(proxy);
|
||||||
|
boolean drawableChanged = !(proxy.getDrawable() instanceof AnimationDrawable)
|
||||||
|
|| !canReuseAnimatedProxy(currentState, desiredState);
|
||||||
|
if (drawableChanged) {
|
||||||
|
Drawable proxyDrawable = newDrawableInstance(animatedDrawable);
|
||||||
|
proxy.setImageDrawable(proxyDrawable);
|
||||||
|
proxyChanged = true;
|
||||||
|
}
|
||||||
|
startAnimationIfNeeded(proxy.getDrawable());
|
||||||
|
if (!desiredState.equals(currentState)) {
|
||||||
|
statesByProxy.put(proxy, desiredState);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
BitmapResult bitmapResult = bitmapFor(proxy, bounds);
|
BitmapResult bitmapResult = bitmapFor(proxy, bounds);
|
||||||
Bitmap bitmap = bitmapResult.bitmap();
|
Bitmap bitmap = bitmapResult.bitmap();
|
||||||
SnapshotRenderState desiredState = renderStateFor(placement);
|
|
||||||
boolean bitmapChanged = bitmapResult.created()
|
boolean bitmapChanged = bitmapResult.created()
|
||||||
|| !desiredState.equals(statesByProxy.get(proxy));
|
|| !desiredState.equals(statesByProxy.get(proxy));
|
||||||
if (bitmapChanged) {
|
if (bitmapChanged) {
|
||||||
@@ -269,6 +285,7 @@ final class SnapshotRenderer {
|
|||||||
proxy.setImageBitmap(bitmap);
|
proxy.setImageBitmap(bitmap);
|
||||||
proxyChanged = true;
|
proxyChanged = true;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (proxy.getAlpha() != 1f) {
|
if (proxy.getAlpha() != 1f) {
|
||||||
proxy.setAlpha(1f);
|
proxy.setAlpha(1f);
|
||||||
proxyChanged = true;
|
proxyChanged = true;
|
||||||
@@ -305,6 +322,52 @@ final class SnapshotRenderer {
|
|||||||
return renderedBounds;
|
return renderedBounds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean canReuseAnimatedProxy(
|
||||||
|
SnapshotRenderState currentState,
|
||||||
|
SnapshotRenderState desiredState
|
||||||
|
) {
|
||||||
|
return currentState != null
|
||||||
|
&& desiredState != null
|
||||||
|
&& Objects.equals(currentState.key(), desiredState.key())
|
||||||
|
&& currentState.width() == desiredState.width()
|
||||||
|
&& currentState.height() == desiredState.height()
|
||||||
|
&& currentState.signal() == desiredState.signal()
|
||||||
|
&& currentState.overflowDot() == desiredState.overflowDot()
|
||||||
|
&& currentState.overflowDotColor() == desiredState.overflowDotColor()
|
||||||
|
&& currentState.sourceOffsetX() == desiredState.sourceOffsetX()
|
||||||
|
&& currentState.sourceRenderBoundsSignature() == desiredState.sourceRenderBoundsSignature()
|
||||||
|
&& Objects.equals(currentState.heldSignalKey(), desiredState.heldSignalKey())
|
||||||
|
&& currentState.heldBitmapId() == desiredState.heldBitmapId()
|
||||||
|
&& currentState.sourceMode() == desiredState.sourceMode()
|
||||||
|
&& currentState.tintSignature() == desiredState.tintSignature();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Drawable animatedNotificationDrawable(SnapshotPlacement placement) {
|
||||||
|
if (placement == null
|
||||||
|
|| placement.source() == null
|
||||||
|
|| placement.source().mode() != SnapshotMode.NOTIFICATION_DRAWABLE
|
||||||
|
|| !(placement.source().view() instanceof ImageView imageView)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Drawable drawable = imageView.getDrawable();
|
||||||
|
return drawable instanceof AnimationDrawable ? drawable : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Drawable newDrawableInstance(Drawable drawable) {
|
||||||
|
Drawable.ConstantState constantState = drawable != null ? drawable.getConstantState() : null;
|
||||||
|
if (constantState != null) {
|
||||||
|
return constantState.newDrawable().mutate();
|
||||||
|
}
|
||||||
|
return drawable != null ? drawable.mutate() : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startAnimationIfNeeded(Drawable drawable) {
|
||||||
|
if (drawable instanceof AnimationDrawable animationDrawable && !animationDrawable.isRunning()) {
|
||||||
|
animationDrawable.setVisible(true, true);
|
||||||
|
animationDrawable.start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void clear(ViewGroup host) {
|
void clear(ViewGroup host) {
|
||||||
LinkedHashMap<String, ImageView> proxies = proxiesByHost.remove(host);
|
LinkedHashMap<String, ImageView> proxies = proxiesByHost.remove(host);
|
||||||
if (proxies == null) {
|
if (proxies == null) {
|
||||||
|
|||||||
Reference in New Issue
Block a user