Loading packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java +18 −5 Original line number Diff line number Diff line Loading @@ -30,10 +30,12 @@ import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.ColorStateList; import android.graphics.Color; import android.graphics.ColorMatrix; import android.graphics.ColorMatrixColorFilter; import android.graphics.Rect; import android.graphics.drawable.Animatable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.graphics.drawable.TransitionDrawable; Loading Loading @@ -159,6 +161,7 @@ public class MediaControlPanel { private MetadataAnimationHandler mMetadataAnimationHandler; private ColorSchemeTransition mColorSchemeTransition; private Drawable mPrevArtwork = null; private boolean mIsArtworkBound = false; private int mArtworkBoundId = 0; private int mArtworkNextBindRequestId = 0; Loading Loading @@ -586,6 +589,9 @@ public class MediaControlPanel { private void bindArtworkAndColors(MediaData data, boolean updateBackground) { final int reqId = mArtworkNextBindRequestId++; if (updateBackground) { mIsArtworkBound = false; } // Capture width & height from views in foreground for artwork scaling in background int width = mMediaViewHolder.getPlayer().getWidth(); Loading @@ -597,15 +603,18 @@ public class MediaControlPanel { // Album art ColorScheme mutableColorScheme = null; Drawable artwork; boolean isArtworkBound; Icon artworkIcon = data.getArtwork(); if (artworkIcon != null) { WallpaperColors wallpaperColors = WallpaperColors .fromBitmap(artworkIcon.getBitmap()); mutableColorScheme = new ColorScheme(wallpaperColors, true); artwork = getScaledBackground(artworkIcon, width, height); isArtworkBound = true; } else { // If there's no artwork, use colors from the app icon artwork = null; artwork = new ColorDrawable(Color.TRANSPARENT); isArtworkBound = false; try { Drawable icon = mContext.getPackageManager() .getApplicationIcon(data.getPackageName()); Loading @@ -625,16 +634,20 @@ public class MediaControlPanel { ImageView albumView = mMediaViewHolder.getAlbumView(); albumView.setPadding(0, 0, 0, 0); albumView.setClipToOutline(true); if (updateBackground) { if (mPrevArtwork == null || artwork == null) { if (updateBackground || (!mIsArtworkBound && isArtworkBound)) { if (mPrevArtwork == null) { albumView.setImageDrawable(artwork); } 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( new Drawable[]{mPrevArtwork, artwork}); albumView.setImageDrawable(transitionDrawable); transitionDrawable.startTransition(333); transitionDrawable.startTransition(isArtworkBound ? 333 : 80); } mPrevArtwork = artwork; mIsArtworkBound = isArtworkBound; } // Transition Colors to current color scheme Loading packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt +59 −3 Original line number Diff line number Diff line Loading @@ -25,8 +25,12 @@ import org.mockito.Mockito.`when` as whenever import android.content.Intent import android.content.pm.ApplicationInfo 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.AnimatedVectorDrawable import android.graphics.drawable.Drawable import android.graphics.drawable.GradientDrawable import android.graphics.drawable.Icon import android.graphics.drawable.RippleDrawable Loading Loading @@ -124,7 +128,7 @@ public class MediaControlPanelTest : SysuiTestCase() { @Mock private lateinit var falsingManager: FalsingManager @Mock private lateinit var transitionParent: ViewGroup private lateinit var appIcon: ImageView private lateinit var albumView: ImageView @Mock private lateinit var albumView: ImageView private lateinit var titleText: TextView private lateinit var artistText: TextView private lateinit var seamless: ViewGroup Loading Loading @@ -296,7 +300,6 @@ public class MediaControlPanelTest : SysuiTestCase() { // Set up mock views for the players appIcon = ImageView(context) albumView = ImageView(context) titleText = TextView(context) artistText = TextView(context) seamless = FrameLayout(context) Loading Loading @@ -416,7 +419,6 @@ public class MediaControlPanelTest : SysuiTestCase() { whenever(coverContainer1.context).thenReturn(mockContext) whenever(coverContainer2.context).thenReturn(mockContext) whenever(coverContainer3.context).thenReturn(mockContext) } @After Loading Loading @@ -536,6 +538,60 @@ public class MediaControlPanelTest : SysuiTestCase() { 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 fun bind_seekBarDisabled_hasActions_seekBarVisibilityIsSetToInvisible() { useRealConstraintSets() Loading Loading
packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java +18 −5 Original line number Diff line number Diff line Loading @@ -30,10 +30,12 @@ import android.content.pm.ActivityInfo; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.res.ColorStateList; import android.graphics.Color; import android.graphics.ColorMatrix; import android.graphics.ColorMatrixColorFilter; import android.graphics.Rect; import android.graphics.drawable.Animatable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; import android.graphics.drawable.Icon; import android.graphics.drawable.TransitionDrawable; Loading Loading @@ -159,6 +161,7 @@ public class MediaControlPanel { private MetadataAnimationHandler mMetadataAnimationHandler; private ColorSchemeTransition mColorSchemeTransition; private Drawable mPrevArtwork = null; private boolean mIsArtworkBound = false; private int mArtworkBoundId = 0; private int mArtworkNextBindRequestId = 0; Loading Loading @@ -586,6 +589,9 @@ public class MediaControlPanel { private void bindArtworkAndColors(MediaData data, boolean updateBackground) { final int reqId = mArtworkNextBindRequestId++; if (updateBackground) { mIsArtworkBound = false; } // Capture width & height from views in foreground for artwork scaling in background int width = mMediaViewHolder.getPlayer().getWidth(); Loading @@ -597,15 +603,18 @@ public class MediaControlPanel { // Album art ColorScheme mutableColorScheme = null; Drawable artwork; boolean isArtworkBound; Icon artworkIcon = data.getArtwork(); if (artworkIcon != null) { WallpaperColors wallpaperColors = WallpaperColors .fromBitmap(artworkIcon.getBitmap()); mutableColorScheme = new ColorScheme(wallpaperColors, true); artwork = getScaledBackground(artworkIcon, width, height); isArtworkBound = true; } else { // If there's no artwork, use colors from the app icon artwork = null; artwork = new ColorDrawable(Color.TRANSPARENT); isArtworkBound = false; try { Drawable icon = mContext.getPackageManager() .getApplicationIcon(data.getPackageName()); Loading @@ -625,16 +634,20 @@ public class MediaControlPanel { ImageView albumView = mMediaViewHolder.getAlbumView(); albumView.setPadding(0, 0, 0, 0); albumView.setClipToOutline(true); if (updateBackground) { if (mPrevArtwork == null || artwork == null) { if (updateBackground || (!mIsArtworkBound && isArtworkBound)) { if (mPrevArtwork == null) { albumView.setImageDrawable(artwork); } 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( new Drawable[]{mPrevArtwork, artwork}); albumView.setImageDrawable(transitionDrawable); transitionDrawable.startTransition(333); transitionDrawable.startTransition(isArtworkBound ? 333 : 80); } mPrevArtwork = artwork; mIsArtworkBound = isArtworkBound; } // Transition Colors to current color scheme Loading
packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt +59 −3 Original line number Diff line number Diff line Loading @@ -25,8 +25,12 @@ import org.mockito.Mockito.`when` as whenever import android.content.Intent import android.content.pm.ApplicationInfo 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.AnimatedVectorDrawable import android.graphics.drawable.Drawable import android.graphics.drawable.GradientDrawable import android.graphics.drawable.Icon import android.graphics.drawable.RippleDrawable Loading Loading @@ -124,7 +128,7 @@ public class MediaControlPanelTest : SysuiTestCase() { @Mock private lateinit var falsingManager: FalsingManager @Mock private lateinit var transitionParent: ViewGroup private lateinit var appIcon: ImageView private lateinit var albumView: ImageView @Mock private lateinit var albumView: ImageView private lateinit var titleText: TextView private lateinit var artistText: TextView private lateinit var seamless: ViewGroup Loading Loading @@ -296,7 +300,6 @@ public class MediaControlPanelTest : SysuiTestCase() { // Set up mock views for the players appIcon = ImageView(context) albumView = ImageView(context) titleText = TextView(context) artistText = TextView(context) seamless = FrameLayout(context) Loading Loading @@ -416,7 +419,6 @@ public class MediaControlPanelTest : SysuiTestCase() { whenever(coverContainer1.context).thenReturn(mockContext) whenever(coverContainer2.context).thenReturn(mockContext) whenever(coverContainer3.context).thenReturn(mockContext) } @After Loading Loading @@ -536,6 +538,60 @@ public class MediaControlPanelTest : SysuiTestCase() { 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 fun bind_seekBarDisabled_hasActions_seekBarVisibilityIsSetToInvisible() { useRealConstraintSets() Loading