summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt41
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaRecommendationsViewBinder.kt226
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaArtworkHelper.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/GutsViewModel.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt34
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaPlayerViewModel.kt4
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecViewModel.kt9
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModel.kt151
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecsCardViewModel.kt3
10 files changed, 258 insertions, 231 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt
index 4055818dcb0b..7a6de5c07b43 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaControlViewBinder.kt
@@ -55,6 +55,7 @@ import com.android.systemui.media.controls.ui.viewmodel.MediaOutputSwitcherViewM
import com.android.systemui.media.controls.ui.viewmodel.MediaPlayerViewModel
import com.android.systemui.media.controls.util.MediaDataUtils
import com.android.systemui.monet.ColorScheme
+import com.android.systemui.monet.Style
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.res.R
import com.android.systemui.surfaceeffects.ripple.MultiRippleView
@@ -66,6 +67,8 @@ import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
+private const val TAG = "MediaControlViewBinder"
+
object MediaControlViewBinder {
fun bind(
@@ -234,9 +237,6 @@ object MediaControlViewBinder {
}
}
setDismissible(model.isDismissEnabled)
- setTextPrimaryColor(model.textPrimaryColor)
- setAccentPrimaryColor(model.accentPrimaryColor)
- setSurfaceColor(model.surfaceColor)
}
}
@@ -423,22 +423,37 @@ object MediaControlViewBinder {
val width = viewController.widthInSceneContainerPx
val height = viewController.heightInSceneContainerPx
withContext(backgroundDispatcher) {
+ val wallpaperColors =
+ MediaArtworkHelper.getWallpaperColor(
+ viewHolder.albumView.context,
+ backgroundDispatcher,
+ viewModel.backgroundCover,
+ TAG,
+ )
+ val isArtworkBound = wallpaperColors != null
+ val scheme =
+ wallpaperColors?.let { ColorScheme(it, true, Style.CONTENT) }
+ ?: let {
+ if (viewModel.launcherIcon is Icon.Loaded) {
+ MediaArtworkHelper.getColorScheme(viewModel.launcherIcon.drawable, TAG)
+ } else {
+ null
+ }
+ }
val artwork =
- if (viewModel.shouldAddGradient) {
+ wallpaperColors?.let {
addGradientToPlayerAlbum(
viewHolder.albumView.context,
viewModel.backgroundCover!!,
- viewModel.colorScheme,
+ scheme!!,
width,
height,
)
- } else {
- ColorDrawable(Color.TRANSPARENT)
- }
+ } ?: ColorDrawable(Color.TRANSPARENT)
withContext(mainDispatcher) {
// Transition Colors to current color scheme
val colorSchemeChanged =
- viewController.colorSchemeTransition.updateColorScheme(viewModel.colorScheme)
+ viewController.colorSchemeTransition.updateColorScheme(scheme)
val albumView = viewHolder.albumView
// Set up width of album view constraint.
@@ -449,7 +464,7 @@ object MediaControlViewBinder {
if (
updateBackground ||
colorSchemeChanged ||
- (!viewController.isArtworkBound && viewModel.shouldAddGradient)
+ (!viewController.isArtworkBound && isArtworkBound)
) {
viewController.prevArtwork?.let {
// Since we throw away the last transition, this will pop if your
@@ -464,12 +479,10 @@ object MediaControlViewBinder {
transitionDrawable.isCrossFadeEnabled = true
albumView.setImageDrawable(transitionDrawable)
- transitionDrawable.startTransition(
- if (viewModel.shouldAddGradient) 333 else 80
- )
+ transitionDrawable.startTransition(if (isArtworkBound) 333 else 80)
} ?: albumView.setImageDrawable(artwork)
}
- viewController.isArtworkBound = viewModel.shouldAddGradient
+ viewController.isArtworkBound = isArtworkBound
viewController.prevArtwork = artwork
if (viewModel.useGrayColorFilter) {
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaRecommendationsViewBinder.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaRecommendationsViewBinder.kt
index 5e8a879adbb4..8a04799d3f94 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaRecommendationsViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/binder/MediaRecommendationsViewBinder.kt
@@ -16,13 +16,24 @@
package com.android.systemui.media.controls.ui.binder
+import android.app.WallpaperColors
import android.content.Context
import android.content.res.ColorStateList
import android.content.res.Configuration
+import android.graphics.Bitmap
+import android.graphics.Color
import android.graphics.Matrix
+import android.graphics.drawable.BitmapDrawable
+import android.graphics.drawable.ColorDrawable
+import android.graphics.drawable.Drawable
+import android.graphics.drawable.GradientDrawable
+import android.graphics.drawable.Icon
+import android.graphics.drawable.LayerDrawable
+import android.os.Trace
import android.util.TypedValue
import android.view.View
import android.view.ViewGroup
+import androidx.appcompat.content.res.AppCompatResources
import androidx.constraintlayout.widget.ConstraintSet
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.lifecycleScope
@@ -30,17 +41,29 @@ import androidx.lifecycle.repeatOnLifecycle
import com.android.systemui.animation.Expandable
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.media.controls.shared.model.NUM_REQUIRED_RECOMMENDATIONS
+import com.android.systemui.media.controls.ui.animation.surfaceFromScheme
+import com.android.systemui.media.controls.ui.animation.textPrimaryFromScheme
+import com.android.systemui.media.controls.ui.animation.textSecondaryFromScheme
import com.android.systemui.media.controls.ui.controller.MediaViewController
+import com.android.systemui.media.controls.ui.util.MediaArtworkHelper
import com.android.systemui.media.controls.ui.view.RecommendationViewHolder
import com.android.systemui.media.controls.ui.viewmodel.MediaRecViewModel
import com.android.systemui.media.controls.ui.viewmodel.MediaRecommendationsViewModel
import com.android.systemui.media.controls.ui.viewmodel.MediaRecsCardViewModel
+import com.android.systemui.monet.ColorScheme
+import com.android.systemui.monet.Style
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.res.R
import com.android.systemui.util.animation.TransitionLayout
import kotlin.math.min
+import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+private const val TAG = "MediaRecommendationsViewBinder"
+private const val MEDIA_REC_SCRIM_START_ALPHA = 0.15f
+private const val MEDIA_REC_SCRIM_END_ALPHA = 1.0f
object MediaRecommendationsViewBinder {
@@ -50,6 +73,8 @@ object MediaRecommendationsViewBinder {
viewModel: MediaRecommendationsViewModel,
mediaViewController: MediaViewController,
falsingManager: FalsingManager,
+ backgroundDispatcher: CoroutineDispatcher,
+ mainDispatcher: CoroutineDispatcher,
) {
mediaViewController.recsConfigurationChangeListener = this::updateRecommendationsVisibility
val cardView = viewHolder.recommendations
@@ -59,7 +84,14 @@ object MediaRecommendationsViewBinder {
launch {
viewModel.mediaRecsCard.collectLatest { viewModel ->
viewModel?.let {
- bindRecsCard(viewHolder, it, mediaViewController, falsingManager)
+ bindRecsCard(
+ viewHolder,
+ it,
+ mediaViewController,
+ falsingManager,
+ backgroundDispatcher,
+ mainDispatcher,
+ )
}
}
}
@@ -68,19 +100,19 @@ object MediaRecommendationsViewBinder {
}
}
- fun bindRecsCard(
+ suspend fun bindRecsCard(
viewHolder: RecommendationViewHolder,
viewModel: MediaRecsCardViewModel,
viewController: MediaViewController,
falsingManager: FalsingManager,
+ backgroundDispatcher: CoroutineDispatcher,
+ mainDispatcher: CoroutineDispatcher,
) {
// Set up media control location and its listener.
viewModel.onLocationChanged(viewController.currentEndLocation)
viewController.locationChangeListener = viewModel.onLocationChanged
// Bind main card.
- viewHolder.cardTitle.setTextColor(viewModel.cardTitleColor)
- viewHolder.recommendations.backgroundTintList = ColorStateList.valueOf(viewModel.cardColor)
viewHolder.recommendations.contentDescription =
viewModel.contentDescription.invoke(viewController.isGutsVisible)
@@ -100,8 +132,17 @@ object MediaRecommendationsViewBinder {
return@setOnLongClickListener true
}
+ // Bind colors
+ val appIcon = viewModel.mediaRecs.first().appIcon
+ fetchAndUpdateColors(viewHolder, appIcon, backgroundDispatcher, mainDispatcher)
// Bind all recommendations.
- bindRecommendationsList(viewHolder, viewModel.mediaRecs, falsingManager)
+ bindRecommendationsList(
+ viewHolder,
+ viewModel.mediaRecs,
+ falsingManager,
+ backgroundDispatcher,
+ mainDispatcher,
+ )
updateRecommendationsVisibility(viewController, viewHolder.recommendations)
// Set visibility of recommendations.
@@ -153,26 +194,21 @@ object MediaRecommendationsViewBinder {
}
gutsViewHolder.setDismissible(gutsViewModel.isDismissEnabled)
- gutsViewHolder.setTextPrimaryColor(gutsViewModel.textPrimaryColor)
- gutsViewHolder.setAccentPrimaryColor(gutsViewModel.accentPrimaryColor)
- gutsViewHolder.setSurfaceColor(gutsViewModel.surfaceColor)
}
- private fun bindRecommendationsList(
+ private suspend fun bindRecommendationsList(
viewHolder: RecommendationViewHolder,
mediaRecs: List<MediaRecViewModel>,
- falsingManager: FalsingManager
+ falsingManager: FalsingManager,
+ backgroundDispatcher: CoroutineDispatcher,
+ mainDispatcher: CoroutineDispatcher,
) {
mediaRecs.forEachIndexed { index, mediaRecViewModel ->
if (index >= NUM_REQUIRED_RECOMMENDATIONS) return@forEachIndexed
val appIconView = viewHolder.mediaAppIcons[index]
appIconView.clearColorFilter()
- if (mediaRecViewModel.appIcon != null) {
- appIconView.setImageDrawable(mediaRecViewModel.appIcon)
- } else {
- appIconView.setImageResource(R.drawable.ic_music_note)
- }
+ appIconView.setImageDrawable(mediaRecViewModel.appIcon)
val mediaCoverContainer = viewHolder.mediaCoverContainers[index]
mediaCoverContainer.setOnClickListener {
@@ -187,29 +223,24 @@ object MediaRecommendationsViewBinder {
}
val mediaCover = viewHolder.mediaCoverItems[index]
- val width: Int =
- mediaCover.context.resources.getDimensionPixelSize(R.dimen.qs_media_rec_album_width)
- val height: Int =
- mediaCover.context.resources.getDimensionPixelSize(
- R.dimen.qs_media_rec_album_height_expanded
- )
- val coverMatrix = Matrix(mediaCover.imageMatrix)
- coverMatrix.postScale(1.25f, 1.25f, 0.5f * width, 0.5f * height)
- mediaCover.imageMatrix = coverMatrix
- mediaCover.setImageDrawable(mediaRecViewModel.albumIcon)
+ bindRecommendationArtwork(
+ mediaCover.context,
+ viewHolder,
+ mediaRecViewModel,
+ index,
+ backgroundDispatcher,
+ mainDispatcher,
+ )
mediaCover.contentDescription = mediaRecViewModel.contentDescription
val title = viewHolder.mediaTitles[index]
title.text = mediaRecViewModel.title
- title.setTextColor(ColorStateList.valueOf(mediaRecViewModel.titleColor))
val subtitle = viewHolder.mediaSubtitles[index]
subtitle.text = mediaRecViewModel.subtitle
- subtitle.setTextColor(ColorStateList.valueOf(mediaRecViewModel.subtitleColor))
val progressBar = viewHolder.mediaProgressBars[index]
progressBar.progress = mediaRecViewModel.progress
- progressBar.progressTintList = ColorStateList.valueOf(mediaRecViewModel.progressColor)
if (mediaRecViewModel.progress == 0) {
progressBar.visibility = View.GONE
}
@@ -291,11 +322,148 @@ object MediaRecommendationsViewBinder {
TypedValue.applyDimension(
TypedValue.COMPLEX_UNIT_DIP,
displayAvailableDpWidth.toFloat(),
- res.displayMetrics
+ res.displayMetrics,
)
.toInt()
displayAvailableWidth / recCoverWidth
}
return min(fittedNum.toDouble(), NUM_REQUIRED_RECOMMENDATIONS.toDouble()).toInt()
}
+
+ private suspend fun bindRecommendationArtwork(
+ context: Context,
+ viewHolder: RecommendationViewHolder,
+ viewModel: MediaRecViewModel,
+ index: Int,
+ backgroundDispatcher: CoroutineDispatcher,
+ mainDispatcher: CoroutineDispatcher,
+ ) {
+ val traceCookie = viewHolder.hashCode()
+ val traceName = "MediaRecommendationsViewBinder#bindRecommendationArtwork"
+ Trace.beginAsyncSection(traceName, traceCookie)
+
+ // Capture width & height from views in foreground for artwork scaling in background
+ val width = context.resources.getDimensionPixelSize(R.dimen.qs_media_rec_album_width)
+ val height =
+ context.resources.getDimensionPixelSize(R.dimen.qs_media_rec_album_height_expanded)
+
+ withContext(backgroundDispatcher) {
+ val artwork =
+ getRecCoverBackground(
+ context,
+ viewModel.albumIcon,
+ width,
+ height,
+ backgroundDispatcher,
+ )
+ withContext(mainDispatcher) {
+ val mediaCover = viewHolder.mediaCoverItems[index]
+ val coverMatrix = Matrix(mediaCover.imageMatrix)
+ coverMatrix.postScale(1.25f, 1.25f, 0.5f * width, 0.5f * height)
+ mediaCover.imageMatrix = coverMatrix
+ mediaCover.setImageDrawable(artwork)
+ }
+ }
+ }
+
+ /** Returns the recommendation album cover of [width]x[height] size. */
+ private suspend fun getRecCoverBackground(
+ context: Context,
+ icon: Icon?,
+ width: Int,
+ height: Int,
+ backgroundDispatcher: CoroutineDispatcher,
+ ): Drawable =
+ withContext(backgroundDispatcher) {
+ return@withContext MediaArtworkHelper.getWallpaperColor(
+ context,
+ backgroundDispatcher,
+ icon,
+ TAG,
+ )
+ ?.let { wallpaperColors ->
+ addGradientToRecommendationAlbum(
+ context,
+ icon!!,
+ ColorScheme(wallpaperColors, true, Style.CONTENT),
+ width,
+ height,
+ )
+ } ?: ColorDrawable(Color.TRANSPARENT)
+ }
+
+ private fun addGradientToRecommendationAlbum(
+ context: Context,
+ artworkIcon: Icon,
+ mutableColorScheme: ColorScheme,
+ width: Int,
+ height: Int,
+ ): LayerDrawable {
+ // First try scaling rec card using bitmap drawable.
+ // If returns null, set drawable bounds.
+ val albumArt =
+ getScaledRecommendationCover(context, artworkIcon, width, height)
+ ?: MediaArtworkHelper.getScaledBackground(context, artworkIcon, width, height)
+ val gradient =
+ AppCompatResources.getDrawable(context, R.drawable.qs_media_rec_scrim)?.mutate()
+ as GradientDrawable
+ return MediaArtworkHelper.setUpGradientColorOnDrawable(
+ albumArt,
+ gradient,
+ mutableColorScheme,
+ MEDIA_REC_SCRIM_START_ALPHA,
+ MEDIA_REC_SCRIM_END_ALPHA,
+ )
+ }
+
+ /** Returns a [Drawable] of a given [artworkIcon] scaled to [width]x[height] size, . */
+ private fun getScaledRecommendationCover(
+ context: Context,
+ artworkIcon: Icon,
+ width: Int,
+ height: Int,
+ ): Drawable? {
+ check(width > 0) { "Width must be a positive number but was $width" }
+ check(height > 0) { "Height must be a positive number but was $height" }
+
+ return if (
+ artworkIcon.type == Icon.TYPE_BITMAP || artworkIcon.type == Icon.TYPE_ADAPTIVE_BITMAP
+ ) {
+ artworkIcon.bitmap?.let {
+ val bitmap = Bitmap.createScaledBitmap(it, width, height, false)
+ BitmapDrawable(context.resources, bitmap)
+ }
+ } else {
+ null
+ }
+ }
+
+ private suspend fun fetchAndUpdateColors(
+ viewHolder: RecommendationViewHolder,
+ appIcon: Drawable,
+ backgroundDispatcher: CoroutineDispatcher,
+ mainDispatcher: CoroutineDispatcher,
+ ) =
+ withContext(backgroundDispatcher) {
+ val colorScheme =
+ ColorScheme(WallpaperColors.fromDrawable(appIcon), /* darkTheme= */ true)
+ withContext(mainDispatcher) {
+ val backgroundColor = surfaceFromScheme(colorScheme)
+ val textPrimaryColor = textPrimaryFromScheme(colorScheme)
+ val textSecondaryColor = textSecondaryFromScheme(colorScheme)
+
+ viewHolder.cardTitle.setTextColor(textPrimaryColor)
+ viewHolder.recommendations.setBackgroundTintList(
+ ColorStateList.valueOf(backgroundColor)
+ )
+
+ viewHolder.mediaTitles.forEach { it.setTextColor(textPrimaryColor) }
+ viewHolder.mediaSubtitles.forEach { it.setTextColor(textSecondaryColor) }
+ viewHolder.mediaProgressBars.forEach {
+ it.progressTintList = ColorStateList.valueOf(textPrimaryColor)
+ }
+
+ viewHolder.gutsViewHolder.setColors(colorScheme)
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
index 49a8758ed51e..bb9517a14142 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaCarouselController.kt
@@ -768,6 +768,8 @@ constructor(
commonViewModel.recsViewModel,
viewController,
falsingManager,
+ backgroundDispatcher,
+ mainDispatcher,
)
mediaContent.addView(viewHolder.recommendations, position)
controllerById[commonViewModel.key] = viewController
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaArtworkHelper.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaArtworkHelper.kt
index c97221e7bd50..c21513b1263a 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaArtworkHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/util/MediaArtworkHelper.kt
@@ -87,26 +87,19 @@ object MediaArtworkHelper {
gradient: GradientDrawable,
colorScheme: ColorScheme,
startAlpha: Float,
- endAlpha: Float
+ endAlpha: Float,
): LayerDrawable {
gradient.colors =
intArrayOf(
getColorWithAlpha(backgroundStartFromScheme(colorScheme), startAlpha),
- getColorWithAlpha(backgroundEndFromScheme(colorScheme), endAlpha)
+ getColorWithAlpha(backgroundEndFromScheme(colorScheme), endAlpha),
)
return LayerDrawable(arrayOf(albumArt, gradient))
}
- /** Returns [ColorScheme] of media app given its [packageName]. */
- fun getColorScheme(
- applicationContext: Context,
- packageName: String,
- tag: String,
- style: Style = Style.TONAL_SPOT
- ): ColorScheme? {
+ /** Returns [ColorScheme] of media app given its [icon]. */
+ fun getColorScheme(icon: Drawable, tag: String, style: Style = Style.TONAL_SPOT): ColorScheme? {
return try {
- // Set up media source app's logo.
- val icon = applicationContext.packageManager.getApplicationIcon(packageName)
ColorScheme(WallpaperColors.fromDrawable(icon), true, style)
} catch (e: PackageManager.NameNotFoundException) {
Log.w(tag, "Fail to get media app info", e)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/GutsViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/GutsViewModel.kt
index 6c7c31c41eeb..314d9afe5aa6 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/GutsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/GutsViewModel.kt
@@ -16,15 +16,11 @@
package com.android.systemui.media.controls.ui.viewmodel
-import android.annotation.ColorInt
import android.graphics.drawable.Drawable
/** Models UI state for media guts menu */
data class GutsViewModel(
val gutsText: CharSequence,
- @ColorInt val textPrimaryColor: Int,
- @ColorInt val accentPrimaryColor: Int,
- @ColorInt val surfaceColor: Int,
val isDismissEnabled: Boolean = true,
val onDismissClicked: () -> Unit,
val cancelTextBackground: Drawable?,
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt
index 104d155ab74e..f07f2de08537 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt
@@ -33,15 +33,9 @@ import com.android.systemui.media.controls.domain.pipeline.interactor.MediaContr
import com.android.systemui.media.controls.shared.model.MediaAction
import com.android.systemui.media.controls.shared.model.MediaButton
import com.android.systemui.media.controls.shared.model.MediaControlModel
-import com.android.systemui.media.controls.ui.animation.accentPrimaryFromScheme
-import com.android.systemui.media.controls.ui.animation.surfaceFromScheme
-import com.android.systemui.media.controls.ui.animation.textPrimaryFromScheme
-import com.android.systemui.media.controls.ui.util.MediaArtworkHelper
import com.android.systemui.media.controls.util.MediaSmartspaceLogger.Companion.SMARTSPACE_CARD_CLICK_EVENT
import com.android.systemui.media.controls.util.MediaSmartspaceLogger.Companion.SMARTSPACE_CARD_DISMISS_EVENT
import com.android.systemui.media.controls.util.MediaUiEventLogger
-import com.android.systemui.monet.ColorScheme
-import com.android.systemui.monet.Style
import com.android.systemui.res.R
import java.util.concurrent.Executor
import kotlinx.coroutines.CoroutineDispatcher
@@ -104,26 +98,9 @@ class MediaControlViewModel(
)
}
- private suspend fun toViewModel(model: MediaControlModel): MediaPlayerViewModel? {
+ private fun toViewModel(model: MediaControlModel): MediaPlayerViewModel {
val mediaController = model.token?.let { MediaController(applicationContext, it) }
- val wallpaperColors =
- MediaArtworkHelper.getWallpaperColor(
- applicationContext,
- backgroundDispatcher,
- model.artwork,
- TAG,
- )
- val scheme =
- wallpaperColors?.let { ColorScheme(it, true, Style.CONTENT) }
- ?: MediaArtworkHelper.getColorScheme(
- applicationContext,
- model.packageName,
- TAG,
- Style.CONTENT,
- )
- ?: return null
-
- val gutsViewModel = toGutsViewModel(model, scheme)
+ val gutsViewModel = toGutsViewModel(model)
// Set playing state
val wasPlaying = isPlaying
@@ -154,8 +131,6 @@ class MediaControlViewModel(
artistName = model.artistName ?: "",
titleName = model.songName ?: "",
isExplicitVisible = model.showExplicit,
- shouldAddGradient = wallpaperColors != null,
- colorScheme = scheme,
canShowTime = canShowScrubbingTimeViews(model.semanticActionButtons),
playTurbulenceNoise = isPlaying && !wasPlaying && wasButtonClicked,
useSemanticActions = model.semanticActionButtons != null,
@@ -276,7 +251,7 @@ class MediaControlViewModel(
)
}
- private fun toGutsViewModel(model: MediaControlModel, scheme: ColorScheme): GutsViewModel {
+ private fun toGutsViewModel(model: MediaControlModel): GutsViewModel {
return GutsViewModel(
gutsText =
if (model.isDismissible) {
@@ -287,9 +262,6 @@ class MediaControlViewModel(
} else {
applicationContext.getString(R.string.controls_media_active_session)
},
- textPrimaryColor = textPrimaryFromScheme(scheme),
- accentPrimaryColor = accentPrimaryFromScheme(scheme),
- surfaceColor = surfaceFromScheme(scheme),
isDismissEnabled = model.isDismissible,
onDismissClicked = {
onDismissMediaData(model.token, model.uid, model.packageName, model.instanceId)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaPlayerViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaPlayerViewModel.kt
index f4b0d6e2c990..4aae72fb375b 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaPlayerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaPlayerViewModel.kt
@@ -18,7 +18,6 @@ package com.android.systemui.media.controls.ui.viewmodel
import com.android.systemui.animation.Expandable
import com.android.systemui.common.shared.model.Icon
-import com.android.systemui.monet.ColorScheme
/** Models UI state for media player. */
data class MediaPlayerViewModel(
@@ -30,8 +29,6 @@ data class MediaPlayerViewModel(
val artistName: CharSequence,
val titleName: CharSequence,
val isExplicitVisible: Boolean,
- val shouldAddGradient: Boolean,
- val colorScheme: ColorScheme,
val canShowTime: Boolean,
val playTurbulenceNoise: Boolean,
val useSemanticActions: Boolean,
@@ -52,7 +49,6 @@ data class MediaPlayerViewModel(
artistName == other.artistName &&
titleName == other.titleName &&
isExplicitVisible == other.isExplicitVisible &&
- shouldAddGradient == other.shouldAddGradient &&
canShowTime == other.canShowTime &&
playTurbulenceNoise == other.playTurbulenceNoise &&
useSemanticActions == other.useSemanticActions &&
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecViewModel.kt
index 2f9fc9bc699a..77add4035067 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecViewModel.kt
@@ -16,21 +16,18 @@
package com.android.systemui.media.controls.ui.viewmodel
-import android.annotation.ColorInt
import android.graphics.drawable.Drawable
+import android.graphics.drawable.Icon
import com.android.systemui.animation.Expandable
/** Models UI state for media recommendation item */
data class MediaRecViewModel(
val contentDescription: CharSequence,
val title: CharSequence = "",
- @ColorInt val titleColor: Int,
val subtitle: CharSequence = "",
- @ColorInt val subtitleColor: Int,
/** track progress [0 - 100] for the recommendation album. */
val progress: Int = 0,
- @ColorInt val progressColor: Int,
- val albumIcon: Drawable? = null,
- val appIcon: Drawable? = null,
+ val albumIcon: Icon? = null,
+ val appIcon: Drawable,
val onClicked: ((Expandable, Int) -> Unit),
)
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModel.kt
index 1fd9c4f014ee..a7bce7772270 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecommendationsViewModel.kt
@@ -18,17 +18,10 @@ package com.android.systemui.media.controls.ui.viewmodel
import android.content.Context
import android.content.Intent
-import android.graphics.Bitmap
-import android.graphics.Color
-import android.graphics.drawable.BitmapDrawable
-import android.graphics.drawable.ColorDrawable
+import android.content.pm.PackageManager
import android.graphics.drawable.Drawable
-import android.graphics.drawable.GradientDrawable
-import android.graphics.drawable.Icon
-import android.graphics.drawable.LayerDrawable
import android.os.Process
import android.util.Log
-import androidx.appcompat.content.res.AppCompatResources
import com.android.internal.logging.InstanceId
import com.android.systemui.animation.Expandable
import com.android.systemui.dagger.SysUISingleton
@@ -38,18 +31,11 @@ import com.android.systemui.media.controls.domain.pipeline.interactor.MediaRecom
import com.android.systemui.media.controls.shared.model.MediaRecModel
import com.android.systemui.media.controls.shared.model.MediaRecommendationsModel
import com.android.systemui.media.controls.shared.model.NUM_REQUIRED_RECOMMENDATIONS
-import com.android.systemui.media.controls.ui.animation.accentPrimaryFromScheme
-import com.android.systemui.media.controls.ui.animation.surfaceFromScheme
-import com.android.systemui.media.controls.ui.animation.textPrimaryFromScheme
-import com.android.systemui.media.controls.ui.animation.textSecondaryFromScheme
import com.android.systemui.media.controls.ui.controller.MediaViewController.Companion.GUTS_ANIMATION_DURATION
-import com.android.systemui.media.controls.ui.util.MediaArtworkHelper
import com.android.systemui.media.controls.util.MediaDataUtils
import com.android.systemui.media.controls.util.MediaSmartspaceLogger.Companion.SMARTSPACE_CARD_CLICK_EVENT
import com.android.systemui.media.controls.util.MediaSmartspaceLogger.Companion.SMARTSPACE_CARD_DISMISS_EVENT
import com.android.systemui.media.controls.util.MediaUiEventLogger
-import com.android.systemui.monet.ColorScheme
-import com.android.systemui.monet.Style
import com.android.systemui.res.R
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
@@ -59,7 +45,6 @@ import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.withContext
/** Models UI state and handles user input for media recommendations */
@SysUISingleton
@@ -92,7 +77,7 @@ constructor(
uid: Int,
packageName: String,
dismissIntent: Intent?,
- instanceId: InstanceId?
+ instanceId: InstanceId?,
) {
logger.logLongPressDismiss(uid, packageName, instanceId)
interactor.removeMediaRecommendations(
@@ -100,7 +85,7 @@ constructor(
dismissIntent,
GUTS_DISMISS_DELAY_MS_DURATION,
SMARTSPACE_CARD_DISMISS_EVENT,
- location
+ location,
)
}
@@ -109,7 +94,7 @@ constructor(
intent: Intent?,
packageName: String,
instanceId: InstanceId?,
- index: Int
+ index: Int,
) {
if (intent == null || intent.extras == null) {
Log.e(TAG, "No tap action can be set up")
@@ -131,7 +116,7 @@ constructor(
SMARTSPACE_CARD_CLICK_EVENT,
location,
index,
- NUM_REQUIRED_RECOMMENDATIONS
+ NUM_REQUIRED_RECOMMENDATIONS,
)
}
@@ -145,22 +130,7 @@ constructor(
return null
}
- val scheme =
- MediaArtworkHelper.getColorScheme(applicationContext, model.packageName, TAG)
- ?: return null
-
- // Capture width & height from views in foreground for artwork scaling in background
- val width =
- applicationContext.resources.getDimensionPixelSize(R.dimen.qs_media_rec_album_width)
- val height =
- applicationContext.resources.getDimensionPixelSize(
- R.dimen.qs_media_rec_album_height_expanded
- )
-
- val appIcon = applicationContext.packageManager.getApplicationIcon(model.packageName)
- val textPrimaryColor = textPrimaryFromScheme(scheme)
- val textSecondaryColor = textSecondaryFromScheme(scheme)
- val backgroundColor = surfaceFromScheme(scheme)
+ val appIcon = getIconFromApp(model.packageName) ?: return null
var areTitlesVisible = false
var areSubtitlesVisible = false
@@ -173,17 +143,9 @@ constructor(
contentDescription =
setUpMediaRecContentDescription(mediaRecModel, model.appName),
title = mediaRecModel.title ?: "",
- titleColor = textPrimaryColor,
subtitle = mediaRecModel.subtitle ?: "",
- subtitleColor = textSecondaryColor,
progress = (progress * 100).toInt(),
- progressColor = textPrimaryColor,
- albumIcon =
- getRecCoverBackground(
- mediaRecModel.icon,
- width,
- height,
- ),
+ albumIcon = mediaRecModel.icon,
appIcon = appIcon,
onClicked = { expandable, index ->
onClicked(
@@ -193,7 +155,7 @@ constructor(
model.instanceId,
index,
)
- }
+ },
)
}
// Subtitles should only be visible if titles are visible.
@@ -204,21 +166,19 @@ constructor(
if (gutsVisible) {
applicationContext.getString(
R.string.controls_media_close_session,
- model.appName
+ model.appName,
)
} else {
applicationContext.getString(R.string.controls_media_smartspace_rec_header)
}
},
- cardColor = backgroundColor,
- cardTitleColor = textPrimaryColor,
onClicked = { expandable ->
onClicked(
expandable,
model.dismissIntent,
model.packageName,
model.instanceId,
- index = -1
+ index = -1,
)
},
onLongClicked = {
@@ -227,28 +187,22 @@ constructor(
mediaRecs = mediaRecs,
areTitlesVisible = areTitlesVisible,
areSubtitlesVisible = areSubtitlesVisible,
- gutsMenu = toGutsViewModel(model, scheme),
- onLocationChanged = { location = it }
+ gutsMenu = toGutsViewModel(model),
+ onLocationChanged = { location = it },
)
}
- private fun toGutsViewModel(
- model: MediaRecommendationsModel,
- scheme: ColorScheme
- ): GutsViewModel {
+ private fun toGutsViewModel(model: MediaRecommendationsModel): GutsViewModel {
return GutsViewModel(
gutsText =
applicationContext.getString(R.string.controls_media_close_session, model.appName),
- textPrimaryColor = textPrimaryFromScheme(scheme),
- accentPrimaryColor = accentPrimaryFromScheme(scheme),
- surfaceColor = surfaceFromScheme(scheme),
onDismissClicked = {
onMediaRecommendationsDismissed(
model.key,
model.uid,
model.packageName,
model.dismissIntent,
- model.instanceId
+ model.instanceId,
)
},
cancelTextBackground =
@@ -260,56 +214,9 @@ constructor(
)
}
- /** Returns the recommendation album cover of [width]x[height] size. */
- private suspend fun getRecCoverBackground(icon: Icon?, width: Int, height: Int): Drawable =
- withContext(backgroundDispatcher) {
- return@withContext MediaArtworkHelper.getWallpaperColor(
- applicationContext,
- backgroundDispatcher,
- icon,
- TAG,
- )
- ?.let { wallpaperColors ->
- addGradientToRecommendationAlbum(
- icon!!,
- ColorScheme(wallpaperColors, true, Style.CONTENT),
- width,
- height
- )
- } ?: ColorDrawable(Color.TRANSPARENT)
- }
-
- private fun addGradientToRecommendationAlbum(
- artworkIcon: Icon,
- mutableColorScheme: ColorScheme,
- width: Int,
- height: Int
- ): LayerDrawable {
- // First try scaling rec card using bitmap drawable.
- // If returns null, set drawable bounds.
- val albumArt =
- getScaledRecommendationCover(artworkIcon, width, height)
- ?: MediaArtworkHelper.getScaledBackground(
- applicationContext,
- artworkIcon,
- width,
- height
- )
- val gradient =
- AppCompatResources.getDrawable(applicationContext, R.drawable.qs_media_rec_scrim)
- ?.mutate() as GradientDrawable
- return MediaArtworkHelper.setUpGradientColorOnDrawable(
- albumArt,
- gradient,
- mutableColorScheme,
- MEDIA_REC_SCRIM_START_ALPHA,
- MEDIA_REC_SCRIM_END_ALPHA
- )
- }
-
private fun setUpMediaRecContentDescription(
mediaRec: MediaRecModel,
- appName: CharSequence?
+ appName: CharSequence?,
): CharSequence {
// Set up the accessibility label for the media item.
val artistName = mediaRec.extras?.getString(KEY_SMARTSPACE_ARTIST_NAME, "")
@@ -317,35 +224,23 @@ constructor(
applicationContext.getString(
R.string.controls_media_smartspace_rec_item_no_artist_description,
mediaRec.title,
- appName
+ appName,
)
} else {
applicationContext.getString(
R.string.controls_media_smartspace_rec_item_description,
mediaRec.title,
artistName,
- appName
+ appName,
)
}
}
- /** Returns a [Drawable] of a given [artworkIcon] scaled to [width]x[height] size, . */
- private fun getScaledRecommendationCover(
- artworkIcon: Icon,
- width: Int,
- height: Int
- ): Drawable? {
- check(width > 0) { "Width must be a positive number but was $width" }
- check(height > 0) { "Height must be a positive number but was $height" }
-
- return if (
- artworkIcon.type == Icon.TYPE_BITMAP || artworkIcon.type == Icon.TYPE_ADAPTIVE_BITMAP
- ) {
- artworkIcon.bitmap?.let {
- val bitmap = Bitmap.createScaledBitmap(it, width, height, false)
- BitmapDrawable(applicationContext.resources, bitmap)
- }
- } else {
+ private fun getIconFromApp(packageName: String): Drawable? {
+ return try {
+ applicationContext.packageManager.getApplicationIcon(packageName)
+ } catch (e: PackageManager.NameNotFoundException) {
+ Log.w(TAG, "Cannot find icon for package $packageName", e)
null
}
}
@@ -353,8 +248,6 @@ constructor(
companion object {
private const val TAG = "MediaRecommendationsViewModel"
private const val KEY_SMARTSPACE_ARTIST_NAME = "artist_name"
- private const val MEDIA_REC_SCRIM_START_ALPHA = 0.15f
- private const val MEDIA_REC_SCRIM_END_ALPHA = 1.0f
/**
* Delay duration is based on [GUTS_ANIMATION_DURATION], it should have 100 ms increase in
* order to let the animation end.
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecsCardViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecsCardViewModel.kt
index 5ecbcb20a58a..f1f7dc2195d5 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecsCardViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaRecsCardViewModel.kt
@@ -16,14 +16,11 @@
package com.android.systemui.media.controls.ui.viewmodel
-import android.annotation.ColorInt
import com.android.systemui.animation.Expandable
/** Models UI state for media recommendations card. */
data class MediaRecsCardViewModel(
val contentDescription: (Boolean) -> CharSequence,
- @ColorInt val cardColor: Int,
- @ColorInt val cardTitleColor: Int,
val onClicked: (Expandable) -> Unit,
val onLongClicked: () -> Unit,
val mediaRecs: List<MediaRecViewModel>,