From 16ea9a69510269ee47f957f6ea8281f1c794290e Mon Sep 17 00:00:00 2001 From: Beth Thibodeau Date: Mon, 8 Feb 2021 13:47:04 -0500 Subject: [PATCH] Use system colors for media Instead of deriving background color from the album art, use theme colors Also fixes layout so the output switcher touch target is not too wide Bug: 176177555 Test: visual Change-Id: I3de7caa6cd6870f65d50068a81af4472e0566ed7 --- .../SystemUI/res/layout/media_carousel.xml | 2 +- packages/SystemUI/res/layout/media_view.xml | 40 ++++++++-------- packages/SystemUI/res/values/colors.xml | 5 +- packages/SystemUI/res/values/styles.xml | 2 +- packages/SystemUI/res/xml/media_collapsed.xml | 8 ++-- packages/SystemUI/res/xml/media_expanded.xml | 8 ++-- .../systemui/media/MediaCarouselController.kt | 35 ++++++++++++-- .../systemui/media/MediaDataManager.kt | 47 +++---------------- .../systemui/media/MediaDataManagerTest.kt | 3 +- 9 files changed, 67 insertions(+), 83 deletions(-) diff --git a/packages/SystemUI/res/layout/media_carousel.xml b/packages/SystemUI/res/layout/media_carousel.xml index 8a47a22ff9857..95cee66af5362 100644 --- a/packages/SystemUI/res/layout/media_carousel.xml +++ b/packages/SystemUI/res/layout/media_carousel.xml @@ -47,7 +47,7 @@ android:layout_width="wrap_content" android:layout_height="48dp" android:layout_marginBottom="4dp" - android:tint="@color/media_primary_text" + android:tint="?android:attr/textColorPrimary" android:forceHasOverlappingRendering="false" /> diff --git a/packages/SystemUI/res/layout/media_view.xml b/packages/SystemUI/res/layout/media_view.xml index 6b4270531d0b1..a4cf5eddb30e2 100644 --- a/packages/SystemUI/res/layout/media_view.xml +++ b/packages/SystemUI/res/layout/media_view.xml @@ -48,7 +48,7 @@ android:layout_height="wrap_content" android:layout_alignParentStart="true" android:fontFamily="@*android:string/config_bodyFontFamily" - android:textColor="@color/media_primary_text" + android:textColor="?android:attr/textColorPrimary" android:gravity="start" android:textSize="14sp" /> @@ -58,7 +58,7 @@ android:layout_height="wrap_content" android:layout_alignParentEnd="true" android:fontFamily="@*android:string/config_bodyFontFamily" - android:textColor="@color/media_primary_text" + android:textColor="?android:attr/textColorPrimary" android:gravity="end" android:textSize="14sp" /> @@ -120,13 +120,13 @@ android:layout_width="0dp" android:layout_height="wrap_content" android:orientation="horizontal" - android:gravity="center_vertical|end" + android:gravity="center" + android:background="@drawable/qs_media_light_source" android:forceHasOverlappingRendering="false"> @@ -135,7 +135,7 @@ android:layout_width="@dimen/qs_seamless_icon_size" android:layout_height="@dimen/qs_seamless_icon_size" android:layout_gravity="center" - android:tint="@color/media_primary_text" + android:tint="?android:attr/colorPrimary" android:src="@*android:drawable/ic_media_seamless" /> @@ -157,7 +157,7 @@ android:id="@+id/media_seamless_fallback" android:layout_width="@dimen/qs_seamless_icon_size" android:layout_height="@dimen/qs_seamless_icon_size" - android:tint="@color/media_primary_text" + android:tint="?android:attr/textColorPrimary" android:src="@drawable/ic_cast_connected" android:forceHasOverlappingRendering="false" /> @@ -171,15 +171,15 @@ android:clickable="true" android:maxHeight="@dimen/qs_media_enabled_seekbar_height" android:paddingVertical="@dimen/qs_media_enabled_seekbar_vertical_padding" - android:thumbTint="@color/media_primary_text" - android:progressTint="@color/media_seekbar_progress" - android:progressBackgroundTint="@color/media_disabled" + android:thumbTint="?android:attr/textColorPrimary" + android:progressTint="?android:attr/textColorPrimary" + android:progressBackgroundTint="?android:attr/colorBackground" android:splitTrack="false" /> @@ -204,12 +204,12 @@ android:layout_height="wrap_content" android:fontFamily="@*android:string/config_headlineFontFamily" android:singleLine="true" - android:textColor="@color/media_secondary_text" + android:textColor="?android:attr/textColorSecondary" android:textSize="14sp" /> @@ -223,7 +223,7 @@ android:layout_marginEnd="@dimen/qs_media_panel_outer_padding" android:id="@+id/media_text" android:fontFamily="@*android:string/config_headlineFontFamilyMedium" - android:textColor="@color/media_primary_text" + android:textColor="?android:attr/textColorSecondary" android:text="@string/controls_media_title" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" @@ -238,7 +238,7 @@ android:id="@+id/remove_text" android:fontFamily="@*android:string/config_headlineFontFamily" android:singleLine="true" - android:textColor="@color/media_primary_text" + android:textColor="?android:attr/textColorPrimary" android:text="@string/controls_media_close_session" app:layout_constraintTop_toBottomOf="@id/media_text" app:layout_constraintStart_toStartOf="parent" @@ -262,7 +262,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:fontFamily="@*android:string/config_headlineFontFamilyMedium" - android:textColor="@android:color/white" + android:textColor="?android:attr/textColorPrimary" android:text="@string/controls_media_settings_button" /> @@ -283,7 +283,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:fontFamily="@*android:string/config_headlineFontFamilyMedium" - android:textColor="@android:color/white" + android:textColor="?android:attr/textColorPrimary" android:text="@string/cancel" /> @@ -304,7 +304,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:fontFamily="@*android:string/config_headlineFontFamilyMedium" - android:textColor="@android:color/white" + android:textColor="?android:attr/textColorPrimary" android:text="@string/controls_media_dismiss_button" /> diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml index 5fb6de7bb5889..dd7724c1706e3 100644 --- a/packages/SystemUI/res/values/colors.xml +++ b/packages/SystemUI/res/values/colors.xml @@ -240,11 +240,8 @@ #7F000000 - @android:color/white - #99ffffff - #c0ffffff #80ffffff - #26ffffff + ?android:attr/colorAccent #1d000000 diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index 7c72548a72526..3df07f1d7728c 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -582,7 +582,7 @@ diff --git a/packages/SystemUI/res/xml/media_collapsed.xml b/packages/SystemUI/res/xml/media_collapsed.xml index f834d6df15c2a..f83e3a1d9b262 100644 --- a/packages/SystemUI/res/xml/media_collapsed.xml +++ b/packages/SystemUI/res/xml/media_collapsed.xml @@ -36,25 +36,23 @@ app:layout_constraintTop_toTopOf="@id/icon" app:layout_constraintBottom_toBottomOf="@id/icon" app:layout_constraintStart_toEndOf="@id/icon" - app:layout_constraintEnd_toStartOf="@id/media_seamless" - app:layout_constraintHorizontal_chainStyle="spread_inside" + app:layout_constraintEnd_toStartOf="@id/center_vertical_guideline" app:layout_constrainedWidth="true" app:layout_constraintHorizontal_bias="0" /> diff --git a/packages/SystemUI/res/xml/media_expanded.xml b/packages/SystemUI/res/xml/media_expanded.xml index d89e0eb4df630..7c6772059695d 100644 --- a/packages/SystemUI/res/xml/media_expanded.xml +++ b/packages/SystemUI/res/xml/media_expanded.xml @@ -36,25 +36,23 @@ app:layout_constraintTop_toTopOf="@id/icon" app:layout_constraintBottom_toBottomOf="@id/icon" app:layout_constraintStart_toEndOf="@id/icon" - app:layout_constraintEnd_toStartOf="@id/media_seamless" - app:layout_constraintHorizontal_chainStyle="spread_inside" + app:layout_constraintEnd_toStartOf="@id/center_vertical_guideline" app:layout_constrainedWidth="true" app:layout_constraintHorizontal_bias="0" /> diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt index 9353526653143..a3ff3753cbf92 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt @@ -1,7 +1,9 @@ package com.android.systemui.media +import android.animation.ArgbEvaluator import android.content.Context import android.content.Intent +import android.content.res.ColorStateList import android.content.res.Configuration import android.provider.Settings.ACTION_MEDIA_CONTROLS_SETTINGS import android.util.Log @@ -112,6 +114,9 @@ class MediaCarouselController @Inject constructor( private val visualStabilityCallback: VisualStabilityManager.Callback private var needsReordering: Boolean = false private var keysNeedRemoval = mutableSetOf() + private var bgColor = getBackgroundColor() + private var fgColor = com.android.settingslib.Utils.getColorAttr(context, + com.android.internal.R.attr.textColorPrimary).defaultColor private var isRtl: Boolean = false set(value) { if (value != field) { @@ -147,7 +152,7 @@ class MediaCarouselController @Inject constructor( } override fun onUiModeChanged() { - // Only settings button needs to update for dark theme + recreatePlayers() inflateSettingsButton() } } @@ -249,6 +254,11 @@ class MediaCarouselController @Inject constructor( } private fun addOrUpdatePlayer(key: String, oldKey: String?, data: MediaData) { + data.actions.forEach { + it.icon?.setTintList(ColorStateList.valueOf(fgColor)) + } + data.appIcon?.setTintList(ColorStateList.valueOf(fgColor)) + val dataCopy = data.copy(backgroundColor = bgColor) val existingPlayer = MediaPlayerData.getMediaPlayer(key, oldKey) if (existingPlayer == null) { var newPlayer = mediaControlPanelFactory.get() @@ -257,14 +267,14 @@ class MediaCarouselController @Inject constructor( val lp = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT) newPlayer.view?.player?.setLayoutParams(lp) - newPlayer.bind(data, key) + newPlayer.bind(dataCopy, key) newPlayer.setListening(currentlyExpanded) - MediaPlayerData.addMediaPlayer(key, data, newPlayer) + MediaPlayerData.addMediaPlayer(key, dataCopy, newPlayer) updatePlayerToState(newPlayer, noAnimation = true) reorderAllPlayers() } else { - existingPlayer.bind(data, key) - MediaPlayerData.addMediaPlayer(key, data, existingPlayer) + existingPlayer.bind(dataCopy, key) + MediaPlayerData.addMediaPlayer(key, dataCopy, existingPlayer) if (visualStabilityManager.isReorderingAllowed) { reorderAllPlayers() } else { @@ -298,12 +308,27 @@ class MediaCarouselController @Inject constructor( } private fun recreatePlayers() { + bgColor = getBackgroundColor() + + fgColor = com.android.settingslib.Utils.getColorAttr(context, + com.android.internal.R.attr.textColorPrimary).defaultColor + pageIndicator.tintList = ColorStateList.valueOf(fgColor) + MediaPlayerData.mediaData().forEach { (key, data) -> removePlayer(key, dismissMediaData = false) addOrUpdatePlayer(key = key, oldKey = null, data = data) } } + private fun getBackgroundColor(): Int { + val themeAccent = com.android.settingslib.Utils.getColorAttr(context, + com.android.internal.R.attr.colorAccent).defaultColor + val themeBackground = com.android.settingslib.Utils.getColorAttr(context, + com.android.internal.R.attr.colorBackground).defaultColor + // Simulate transparency - cannot be actually transparent because of lockscreen + return ArgbEvaluator().evaluate(0.25f, themeBackground, themeAccent) as Int + } + private fun updatePageIndicator() { val numPages = mediaContent.getChildCount() pageIndicator.setNumPages(numPages) diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt index 3629d4d6141c4..55c55b97db514 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt @@ -25,7 +25,6 @@ import android.content.Intent import android.content.IntentFilter import android.graphics.Bitmap import android.graphics.Canvas -import android.graphics.Color import android.graphics.ImageDecoder import android.graphics.drawable.Drawable import android.graphics.drawable.Icon @@ -38,7 +37,6 @@ import android.os.UserHandle import android.service.notification.StatusBarNotification import android.text.TextUtils import android.util.Log -import com.android.internal.graphics.ColorUtils import com.android.systemui.Dumpable import com.android.systemui.R import com.android.systemui.broadcast.BroadcastDispatcher @@ -48,7 +46,6 @@ import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.dump.DumpManager import com.android.systemui.plugins.ActivityStarter import com.android.systemui.statusbar.NotificationMediaManager.isPlayingState -import com.android.systemui.statusbar.notification.MediaNotificationProcessor import com.android.systemui.statusbar.notification.row.HybridGroupManager import com.android.systemui.util.Assert import com.android.systemui.util.Utils @@ -68,10 +65,6 @@ private val ART_URIS = arrayOf( private const val TAG = "MediaDataManager" private const val DEBUG = true -private const val DEFAULT_LUMINOSITY = 0.25f -private const val LUMINOSITY_THRESHOLD = 0.05f -private const val SATURATION_MULTIPLIER = 0.8f -const val DEFAULT_COLOR = Color.DKGRAY private val LOADING = MediaData(-1, false, 0, null, null, null, null, null, emptyList(), emptyList(), "INVALID", null, null, null, true, null) @@ -110,6 +103,11 @@ class MediaDataManager( private val useQsMediaPlayer: Boolean ) : Dumpable { + private val themeText = com.android.settingslib.Utils.getColorAttr(context, + com.android.internal.R.attr.textColorPrimary).defaultColor + private val bgColor = com.android.settingslib.Utils.getColorAttr(context, + com.android.internal.R.attr.colorBackground).defaultColor + // Internal listeners are part of the internal pipeline. External listeners (those registered // with [MediaDeviceManager.addListener]) receive events after they have propagated through // the internal pipeline. @@ -395,7 +393,6 @@ class MediaDataManager( } else { null } - val bgColor = artworkBitmap?.let { computeBackgroundColor(it) } ?: DEFAULT_COLOR val mediaAction = getResumeMediaAction(resumeAction) foregroundExecutor.execute { @@ -449,7 +446,6 @@ class MediaDataManager( } } } - val bgColor = computeBackgroundColor(artworkBitmap) // App name val builder = Notification.Builder.recoverBuilder(context, notif) @@ -506,7 +502,7 @@ class MediaDataManager( Icon.createWithResource(packageContext, action.getIcon()!!.getResId()) } else { action.getIcon() - } + }.setTint(themeText) val mediaAction = MediaAction( mediaActionIcon, runnable, @@ -589,38 +585,9 @@ class MediaDataManager( } } - private fun computeBackgroundColor(artworkBitmap: Bitmap?): Int { - var color = Color.WHITE - if (artworkBitmap != null && artworkBitmap.width > 1 && artworkBitmap.height > 1) { - // If we have valid art, get colors from that - val p = MediaNotificationProcessor.generateArtworkPaletteBuilder(artworkBitmap) - .generate() - val swatch = MediaNotificationProcessor.findBackgroundSwatch(p) - color = swatch.rgb - } else { - return DEFAULT_COLOR - } - // Adapt background color, so it's always subdued and text is legible - val tmpHsl = floatArrayOf(0f, 0f, 0f) - ColorUtils.colorToHSL(color, tmpHsl) - - val l = tmpHsl[2] - // Colors with very low luminosity can have any saturation. This means that changing the - // luminosity can make a black become red. Let's remove the saturation of very light or - // very dark colors to avoid this issue. - if (l < LUMINOSITY_THRESHOLD || l > 1f - LUMINOSITY_THRESHOLD) { - tmpHsl[1] = 0f - } - tmpHsl[1] *= SATURATION_MULTIPLIER - tmpHsl[2] = DEFAULT_LUMINOSITY - - color = ColorUtils.HSLToColor(tmpHsl) - return color - } - private fun getResumeMediaAction(action: Runnable): MediaAction { return MediaAction( - Icon.createWithResource(context, R.drawable.lb_ic_play), + Icon.createWithResource(context, R.drawable.lb_ic_play).setTint(themeText), action, context.getString(R.string.controls_media_resume) ) diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt index 2db224f85eb0a..e88c72860ed8f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt @@ -315,10 +315,9 @@ class MediaDataManagerTest : SysuiTestCase() { } mediaDataManager.onNotificationAdded(KEY, notif) - // THEN it loads and uses the default background color + // THEN it still loads assertThat(backgroundExecutor.runAllReady()).isEqualTo(1) assertThat(foregroundExecutor.runAllReady()).isEqualTo(1) verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor)) - assertThat(mediaDataCaptor.value!!.backgroundColor).isEqualTo(DEFAULT_COLOR) } }