Merge "Transition a second time if background doesn't arrive on time" into tm-dev am: 9f3f150ff3 am: b145225c2d

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17943722

Change-Id: I60a7a1226fcb872ba7b3f711c2f62c04b4f8497c
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
TreeHugger Robot
2022-04-27 17:27:47 +00:00
committed by Automerger Merge Worker
2 changed files with 77 additions and 8 deletions

View File

@@ -30,10 +30,12 @@ import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo; import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.res.ColorStateList; import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.ColorMatrix; import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter; import android.graphics.ColorMatrixColorFilter;
import android.graphics.Rect; import android.graphics.Rect;
import android.graphics.drawable.Animatable; import android.graphics.drawable.Animatable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.graphics.drawable.Icon; import android.graphics.drawable.Icon;
import android.graphics.drawable.TransitionDrawable; import android.graphics.drawable.TransitionDrawable;
@@ -159,6 +161,7 @@ public class MediaControlPanel {
private MetadataAnimationHandler mMetadataAnimationHandler; private MetadataAnimationHandler mMetadataAnimationHandler;
private ColorSchemeTransition mColorSchemeTransition; private ColorSchemeTransition mColorSchemeTransition;
private Drawable mPrevArtwork = null; private Drawable mPrevArtwork = null;
private boolean mIsArtworkBound = false;
private int mArtworkBoundId = 0; private int mArtworkBoundId = 0;
private int mArtworkNextBindRequestId = 0; private int mArtworkNextBindRequestId = 0;
@@ -586,6 +589,9 @@ public class MediaControlPanel {
private void bindArtworkAndColors(MediaData data, boolean updateBackground) { private void bindArtworkAndColors(MediaData data, boolean updateBackground) {
final int reqId = mArtworkNextBindRequestId++; final int reqId = mArtworkNextBindRequestId++;
if (updateBackground) {
mIsArtworkBound = false;
}
// Capture width & height from views in foreground for artwork scaling in background // Capture width & height from views in foreground for artwork scaling in background
int width = mMediaViewHolder.getPlayer().getWidth(); int width = mMediaViewHolder.getPlayer().getWidth();
@@ -597,15 +603,18 @@ public class MediaControlPanel {
// Album art // Album art
ColorScheme mutableColorScheme = null; ColorScheme mutableColorScheme = null;
Drawable artwork; Drawable artwork;
boolean isArtworkBound;
Icon artworkIcon = data.getArtwork(); Icon artworkIcon = data.getArtwork();
if (artworkIcon != null) { if (artworkIcon != null) {
WallpaperColors wallpaperColors = WallpaperColors WallpaperColors wallpaperColors = WallpaperColors
.fromBitmap(artworkIcon.getBitmap()); .fromBitmap(artworkIcon.getBitmap());
mutableColorScheme = new ColorScheme(wallpaperColors, true); mutableColorScheme = new ColorScheme(wallpaperColors, true);
artwork = getScaledBackground(artworkIcon, width, height); artwork = getScaledBackground(artworkIcon, width, height);
isArtworkBound = true;
} else { } else {
// If there's no artwork, use colors from the app icon // If there's no artwork, use colors from the app icon
artwork = null; artwork = new ColorDrawable(Color.TRANSPARENT);
isArtworkBound = false;
try { try {
Drawable icon = mContext.getPackageManager() Drawable icon = mContext.getPackageManager()
.getApplicationIcon(data.getPackageName()); .getApplicationIcon(data.getPackageName());
@@ -625,16 +634,20 @@ public class MediaControlPanel {
ImageView albumView = mMediaViewHolder.getAlbumView(); ImageView albumView = mMediaViewHolder.getAlbumView();
albumView.setPadding(0, 0, 0, 0); albumView.setPadding(0, 0, 0, 0);
albumView.setClipToOutline(true); albumView.setClipToOutline(true);
if (updateBackground) { if (updateBackground || (!mIsArtworkBound && isArtworkBound)) {
if (mPrevArtwork == null || artwork == null) { if (mPrevArtwork == null) {
albumView.setImageDrawable(artwork); albumView.setImageDrawable(artwork);
} else { } else {
// Since we throw away the last transition, this'll pop if you backgrounds
// are cycled too fast (or the correct background arrives very soon after
// the metadata changes).
TransitionDrawable transitionDrawable = new TransitionDrawable( TransitionDrawable transitionDrawable = new TransitionDrawable(
new Drawable[] { mPrevArtwork, artwork }); new Drawable[]{mPrevArtwork, artwork});
albumView.setImageDrawable(transitionDrawable); albumView.setImageDrawable(transitionDrawable);
transitionDrawable.startTransition(333); transitionDrawable.startTransition(isArtworkBound ? 333 : 80);
} }
mPrevArtwork = artwork; mPrevArtwork = artwork;
mIsArtworkBound = isArtworkBound;
} }
// Transition Colors to current color scheme // Transition Colors to current color scheme

View File

@@ -25,8 +25,12 @@ import org.mockito.Mockito.`when` as whenever
import android.content.Intent import android.content.Intent
import android.content.pm.ApplicationInfo import android.content.pm.ApplicationInfo
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.drawable.Animatable2 import android.graphics.drawable.Animatable2
import android.graphics.drawable.AnimatedVectorDrawable import android.graphics.drawable.AnimatedVectorDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.GradientDrawable import android.graphics.drawable.GradientDrawable
import android.graphics.drawable.Icon import android.graphics.drawable.Icon
import android.graphics.drawable.RippleDrawable import android.graphics.drawable.RippleDrawable
@@ -124,7 +128,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Mock private lateinit var falsingManager: FalsingManager @Mock private lateinit var falsingManager: FalsingManager
@Mock private lateinit var transitionParent: ViewGroup @Mock private lateinit var transitionParent: ViewGroup
private lateinit var appIcon: ImageView private lateinit var appIcon: ImageView
private lateinit var albumView: ImageView @Mock private lateinit var albumView: ImageView
private lateinit var titleText: TextView private lateinit var titleText: TextView
private lateinit var artistText: TextView private lateinit var artistText: TextView
private lateinit var seamless: ViewGroup private lateinit var seamless: ViewGroup
@@ -296,7 +300,6 @@ public class MediaControlPanelTest : SysuiTestCase() {
// Set up mock views for the players // Set up mock views for the players
appIcon = ImageView(context) appIcon = ImageView(context)
albumView = ImageView(context)
titleText = TextView(context) titleText = TextView(context)
artistText = TextView(context) artistText = TextView(context)
seamless = FrameLayout(context) seamless = FrameLayout(context)
@@ -416,7 +419,6 @@ public class MediaControlPanelTest : SysuiTestCase() {
whenever(coverContainer1.context).thenReturn(mockContext) whenever(coverContainer1.context).thenReturn(mockContext)
whenever(coverContainer2.context).thenReturn(mockContext) whenever(coverContainer2.context).thenReturn(mockContext)
whenever(coverContainer3.context).thenReturn(mockContext) whenever(coverContainer3.context).thenReturn(mockContext)
} }
@After @After
@@ -536,6 +538,60 @@ public class MediaControlPanelTest : SysuiTestCase() {
verify(expandedSet).setVisibility(R.id.actionNext, ConstraintSet.INVISIBLE) verify(expandedSet).setVisibility(R.id.actionNext, ConstraintSet.INVISIBLE)
} }
@Test
fun bindAlbumView_setAfterExecutors() {
val bmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bmp)
canvas.drawColor(Color.RED)
val albumArt = Icon.createWithBitmap(bmp)
val state = mediaData.copy(artwork = albumArt)
player.attachPlayer(viewHolder)
player.bindPlayer(state, PACKAGE)
bgExecutor.runAllReady()
mainExecutor.runAllReady()
verify(albumView).setImageDrawable(any(Drawable::class.java))
}
@Test
fun bindAlbumView_bitmapInLaterStates_setAfterExecutors() {
val bmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bmp)
canvas.drawColor(Color.RED)
val albumArt = Icon.createWithBitmap(bmp)
val state0 = mediaData.copy(artwork = null)
val state1 = mediaData.copy(artwork = albumArt)
val state2 = mediaData.copy(artwork = albumArt)
player.attachPlayer(viewHolder)
// First binding sets (empty) drawable
player.bindPlayer(state0, PACKAGE)
bgExecutor.runAllReady()
mainExecutor.runAllReady()
verify(albumView).setImageDrawable(any(Drawable::class.java))
// Run Metadata update so that later states don't update
val captor = argumentCaptor<Animator.AnimatorListener>()
verify(mockAnimator, times(2)).addListener(captor.capture())
captor.value.onAnimationEnd(mockAnimator)
assertThat(titleText.getText()).isEqualTo(TITLE)
assertThat(artistText.getText()).isEqualTo(ARTIST)
// Second binding sets transition drawable
player.bindPlayer(state1, PACKAGE)
bgExecutor.runAllReady()
mainExecutor.runAllReady()
verify(albumView, times(2)).setImageDrawable(any(Drawable::class.java))
// Third binding does run transition or update background
player.bindPlayer(state2, PACKAGE)
bgExecutor.runAllReady()
mainExecutor.runAllReady()
verify(albumView, times(2)).setImageDrawable(any(Drawable::class.java))
}
@Test @Test
fun bind_seekBarDisabled_hasActions_seekBarVisibilityIsSetToInvisible() { fun bind_seekBarDisabled_hasActions_seekBarVisibilityIsSetToInvisible() {
useRealConstraintSets() useRealConstraintSets()