Merge "Revert "[Media] Update background gradient scrim to use album theme colors."" into tm-dev am: 783f9c9091
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/18027822 Change-Id: I05a0b0952e3a8b2ca3a83a82e6a2f71174b065cb Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
@@ -15,8 +15,6 @@
|
||||
*/
|
||||
package com.android.keyguard;
|
||||
|
||||
import static com.android.systemui.util.ColorUtilKt.getPrivateAttrColorIfUnset;
|
||||
|
||||
import android.animation.AnimatorSet;
|
||||
import android.animation.ArgbEvaluator;
|
||||
import android.animation.ValueAnimator;
|
||||
@@ -154,7 +152,7 @@ class NumPadAnimator {
|
||||
|
||||
ContextThemeWrapper ctw = new ContextThemeWrapper(context, mStyle);
|
||||
TypedArray a = ctw.obtainStyledAttributes(customAttrs);
|
||||
mNormalColor = getPrivateAttrColorIfUnset(ctw, a, 0, 0,
|
||||
mNormalColor = Utils.getPrivateAttrColorIfUnset(ctw, a, 0, 0,
|
||||
com.android.internal.R.attr.colorSurface);
|
||||
mHighlightColor = a.getColor(1, 0);
|
||||
a.recycle();
|
||||
|
||||
@@ -21,41 +21,24 @@ import android.animation.ValueAnimator.AnimatorUpdateListener
|
||||
import android.animation.ValueAnimator
|
||||
import android.content.Context
|
||||
import android.content.res.ColorStateList
|
||||
import android.graphics.drawable.GradientDrawable
|
||||
import com.android.internal.R
|
||||
import com.android.internal.annotations.VisibleForTesting
|
||||
import com.android.settingslib.Utils
|
||||
import com.android.systemui.monet.ColorScheme
|
||||
import com.android.systemui.util.getColorWithAlpha
|
||||
|
||||
/**
|
||||
* A [ColorTransition] is an object that updates the colors of views each time [updateColorScheme]
|
||||
* is triggered.
|
||||
*/
|
||||
interface ColorTransition {
|
||||
fun updateColorScheme(scheme: ColorScheme?)
|
||||
}
|
||||
|
||||
/** A generic implementation of [ColorTransition] so that we can define a factory method. */
|
||||
open class GenericColorTransition(
|
||||
private val applyTheme: (ColorScheme?) -> Unit
|
||||
) : ColorTransition {
|
||||
override fun updateColorScheme(scheme: ColorScheme?) = applyTheme(scheme)
|
||||
}
|
||||
|
||||
/**
|
||||
* A [ColorTransition] that animates between two specific colors.
|
||||
* ColorTransition is responsible for managing the animation between two specific colors.
|
||||
* It uses a ValueAnimator to execute the animation and interpolate between the source color and
|
||||
* the target color.
|
||||
*
|
||||
* Selection of the target color from the scheme, and application of the interpolated color
|
||||
* are delegated to callbacks.
|
||||
*/
|
||||
open class AnimatingColorTransition(
|
||||
open class ColorTransition(
|
||||
private val defaultColor: Int,
|
||||
private val extractColor: (ColorScheme) -> Int,
|
||||
private val applyColor: (Int) -> Unit
|
||||
) : AnimatorUpdateListener, ColorTransition {
|
||||
) : AnimatorUpdateListener {
|
||||
|
||||
private val argbEvaluator = ArgbEvaluator()
|
||||
private val valueAnimator = buildAnimator()
|
||||
@@ -70,7 +53,7 @@ open class AnimatingColorTransition(
|
||||
applyColor(currentColor)
|
||||
}
|
||||
|
||||
override fun updateColorScheme(scheme: ColorScheme?) {
|
||||
fun updateColorScheme(scheme: ColorScheme?) {
|
||||
val newTargetColor = if (scheme == null) defaultColor else extractColor(scheme)
|
||||
if (newTargetColor != targetColor) {
|
||||
sourceColor = currentColor
|
||||
@@ -93,9 +76,7 @@ open class AnimatingColorTransition(
|
||||
}
|
||||
}
|
||||
|
||||
typealias AnimatingColorTransitionFactory =
|
||||
(Int, (ColorScheme) -> Int, (Int) -> Unit) -> AnimatingColorTransition
|
||||
typealias GenericColorTransitionFactory = ((ColorScheme?) -> Unit) -> GenericColorTransition
|
||||
typealias ColorTransitionFactory = (Int, (ColorScheme) -> Int, (Int) -> Unit) -> ColorTransition
|
||||
|
||||
/**
|
||||
* ColorSchemeTransition constructs a ColorTransition for each color in the scheme
|
||||
@@ -105,26 +86,27 @@ typealias GenericColorTransitionFactory = ((ColorScheme?) -> Unit) -> GenericCol
|
||||
class ColorSchemeTransition internal constructor(
|
||||
private val context: Context,
|
||||
mediaViewHolder: MediaViewHolder,
|
||||
animatingColorTransitionFactory: AnimatingColorTransitionFactory,
|
||||
genericColorTransitionFactory: GenericColorTransitionFactory
|
||||
colorTransitionFactory: ColorTransitionFactory
|
||||
) {
|
||||
constructor(context: Context, mediaViewHolder: MediaViewHolder) :
|
||||
this(context, mediaViewHolder, ::AnimatingColorTransition, ::GenericColorTransition)
|
||||
this(context, mediaViewHolder, ::ColorTransition)
|
||||
|
||||
val bgColor = context.getColor(com.android.systemui.R.color.material_dynamic_secondary95)
|
||||
|
||||
val surfaceColor = animatingColorTransitionFactory(
|
||||
val surfaceColor = colorTransitionFactory(
|
||||
bgColor,
|
||||
::surfaceFromScheme
|
||||
) { surfaceColor ->
|
||||
val colorList = ColorStateList.valueOf(surfaceColor)
|
||||
mediaViewHolder.player.backgroundTintList = colorList
|
||||
mediaViewHolder.albumView.foregroundTintList = colorList
|
||||
mediaViewHolder.albumView.backgroundTintList = colorList
|
||||
mediaViewHolder.seamlessIcon.imageTintList = colorList
|
||||
mediaViewHolder.seamlessText.setTextColor(surfaceColor)
|
||||
mediaViewHolder.gutsViewHolder.setSurfaceColor(surfaceColor)
|
||||
}
|
||||
|
||||
val accentPrimary = animatingColorTransitionFactory(
|
||||
val accentPrimary = colorTransitionFactory(
|
||||
loadDefaultColor(R.attr.textColorPrimary),
|
||||
::accentPrimaryFromScheme
|
||||
) { accentPrimary ->
|
||||
@@ -134,7 +116,7 @@ class ColorSchemeTransition internal constructor(
|
||||
mediaViewHolder.gutsViewHolder.setAccentPrimaryColor(accentPrimary)
|
||||
}
|
||||
|
||||
val textPrimary = animatingColorTransitionFactory(
|
||||
val textPrimary = colorTransitionFactory(
|
||||
loadDefaultColor(R.attr.textColorPrimary),
|
||||
::textPrimaryFromScheme
|
||||
) { textPrimary ->
|
||||
@@ -150,65 +132,28 @@ class ColorSchemeTransition internal constructor(
|
||||
mediaViewHolder.gutsViewHolder.setTextPrimaryColor(textPrimary)
|
||||
}
|
||||
|
||||
val textPrimaryInverse = animatingColorTransitionFactory(
|
||||
val textPrimaryInverse = colorTransitionFactory(
|
||||
loadDefaultColor(R.attr.textColorPrimaryInverse),
|
||||
::textPrimaryInverseFromScheme
|
||||
) { textPrimaryInverse ->
|
||||
mediaViewHolder.actionPlayPause.imageTintList = ColorStateList.valueOf(textPrimaryInverse)
|
||||
}
|
||||
|
||||
val textSecondary = animatingColorTransitionFactory(
|
||||
val textSecondary = colorTransitionFactory(
|
||||
loadDefaultColor(R.attr.textColorSecondary),
|
||||
::textSecondaryFromScheme
|
||||
) { textSecondary -> mediaViewHolder.artistText.setTextColor(textSecondary) }
|
||||
|
||||
val textTertiary = animatingColorTransitionFactory(
|
||||
val textTertiary = colorTransitionFactory(
|
||||
loadDefaultColor(R.attr.textColorTertiary),
|
||||
::textTertiaryFromScheme
|
||||
) { textTertiary ->
|
||||
mediaViewHolder.seekBar.progressBackgroundTintList = ColorStateList.valueOf(textTertiary)
|
||||
}
|
||||
|
||||
// Note: This background gradient currently doesn't animate between colors.
|
||||
val backgroundGradient = genericColorTransitionFactory { scheme ->
|
||||
val defaultTintColor = ColorStateList.valueOf(bgColor)
|
||||
if (scheme == null) {
|
||||
mediaViewHolder.albumView.foregroundTintList = defaultTintColor
|
||||
mediaViewHolder.albumView.backgroundTintList = defaultTintColor
|
||||
return@genericColorTransitionFactory
|
||||
}
|
||||
|
||||
// If there's no album art, just hide the gradient so we show the solid background.
|
||||
val showGradient = mediaViewHolder.albumView.drawable != null
|
||||
val startColor = getColorWithAlpha(
|
||||
backgroundStartFromScheme(scheme),
|
||||
alpha = if (showGradient) .25f else 0f
|
||||
)
|
||||
val endColor = getColorWithAlpha(
|
||||
backgroundEndFromScheme(scheme),
|
||||
alpha = if (showGradient) .90f else 0f
|
||||
)
|
||||
val gradientColors = intArrayOf(startColor, endColor)
|
||||
|
||||
val foregroundGradient = mediaViewHolder.albumView.foreground.mutate()
|
||||
if (foregroundGradient is GradientDrawable) {
|
||||
foregroundGradient.colors = gradientColors
|
||||
}
|
||||
val backgroundGradient = mediaViewHolder.albumView.background.mutate()
|
||||
if (backgroundGradient is GradientDrawable) {
|
||||
backgroundGradient.colors = gradientColors
|
||||
}
|
||||
}
|
||||
|
||||
val colorTransitions = arrayOf(
|
||||
surfaceColor,
|
||||
accentPrimary,
|
||||
textPrimary,
|
||||
textPrimaryInverse,
|
||||
textSecondary,
|
||||
textTertiary,
|
||||
backgroundGradient
|
||||
)
|
||||
surfaceColor, accentPrimary, textPrimary,
|
||||
textPrimaryInverse, textSecondary, textTertiary)
|
||||
|
||||
private fun loadDefaultColor(id: Int): Int {
|
||||
return Utils.getColorAttr(context, id).defaultColor
|
||||
|
||||
@@ -35,9 +35,3 @@ internal fun textSecondaryFromScheme(scheme: ColorScheme) = scheme.neutral2[3] /
|
||||
|
||||
/** Returns the tertiary text color for media controls based on the scheme. */
|
||||
internal fun textTertiaryFromScheme(scheme: ColorScheme) = scheme.neutral2[5] // N2-400
|
||||
|
||||
/** Returns the color for the start of the background gradient based on the scheme. */
|
||||
internal fun backgroundStartFromScheme(scheme: ColorScheme) = scheme.accent2[8] // A2-700
|
||||
|
||||
/** Returns the color for the end of the background gradient based on the scheme. */
|
||||
internal fun backgroundEndFromScheme(scheme: ColorScheme) = scheme.accent1[8] // A1-700
|
||||
|
||||
@@ -17,7 +17,6 @@ import android.util.MathUtils.lerp
|
||||
import android.view.View
|
||||
import com.android.systemui.animation.Interpolators
|
||||
import com.android.systemui.statusbar.LightRevealEffect.Companion.getPercentPastThreshold
|
||||
import com.android.systemui.util.getColorWithAlpha
|
||||
import java.util.function.Consumer
|
||||
|
||||
/**
|
||||
@@ -368,7 +367,7 @@ class LightRevealScrim(context: Context?, attrs: AttributeSet?) : View(context,
|
||||
}
|
||||
|
||||
if (startColorAlpha > 0f) {
|
||||
canvas.drawColor(getColorWithAlpha(revealGradientEndColor, startColorAlpha))
|
||||
canvas.drawColor(updateColorAlpha(revealGradientEndColor, startColorAlpha))
|
||||
}
|
||||
|
||||
with(shaderGradientMatrix) {
|
||||
@@ -384,7 +383,15 @@ class LightRevealScrim(context: Context?, attrs: AttributeSet?) : View(context,
|
||||
|
||||
private fun setPaintColorFilter() {
|
||||
gradientPaint.colorFilter = PorterDuffColorFilter(
|
||||
getColorWithAlpha(revealGradientEndColor, revealGradientEndColorAlpha),
|
||||
updateColorAlpha(revealGradientEndColor, revealGradientEndColorAlpha),
|
||||
PorterDuff.Mode.MULTIPLY)
|
||||
}
|
||||
|
||||
private fun updateColorAlpha(color: Int, alpha: Float): Int =
|
||||
Color.argb(
|
||||
(alpha * 255).toInt(),
|
||||
Color.red(color),
|
||||
Color.green(color),
|
||||
Color.blue(color)
|
||||
)
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2022 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.util
|
||||
|
||||
import android.content.res.TypedArray
|
||||
import android.graphics.Color
|
||||
import android.view.ContextThemeWrapper
|
||||
|
||||
/** Returns an ARGB color version of [color] at the given [alpha]. */
|
||||
fun getColorWithAlpha(color: Int, alpha: Float): Int =
|
||||
Color.argb(
|
||||
(alpha * 255).toInt(),
|
||||
Color.red(color),
|
||||
Color.green(color),
|
||||
Color.blue(color)
|
||||
)
|
||||
|
||||
|
||||
/**
|
||||
* Returns the color provided at the specified {@param attrIndex} in {@param a} if it exists,
|
||||
* otherwise, returns the color from the private attribute {@param privAttrId}.
|
||||
*/
|
||||
fun getPrivateAttrColorIfUnset(
|
||||
ctw: ContextThemeWrapper, attrArray: TypedArray,
|
||||
attrIndex: Int, defColor: Int, privAttrId: Int
|
||||
): Int {
|
||||
// If the index is specified, use that value
|
||||
var a = attrArray
|
||||
if (a.hasValue(attrIndex)) {
|
||||
return a.getColor(attrIndex, defColor)
|
||||
}
|
||||
|
||||
// Otherwise fallback to the value of the private attribute
|
||||
val customAttrs = intArrayOf(privAttrId)
|
||||
a = ctw.obtainStyledAttributes(customAttrs)
|
||||
val color = a.getColor(0, defColor)
|
||||
a.recycle()
|
||||
return color
|
||||
}
|
||||
@@ -104,6 +104,25 @@ public class Utils {
|
||||
return resources.getBoolean(R.bool.config_quickSettingsMediaLandscapeCollapsed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the color provided at the specified {@param attrIndex} in {@param a} if it exists,
|
||||
* otherwise, returns the color from the private attribute {@param privAttrId}.
|
||||
*/
|
||||
public static int getPrivateAttrColorIfUnset(ContextThemeWrapper ctw, TypedArray a,
|
||||
int attrIndex, int defColor, int privAttrId) {
|
||||
// If the index is specified, use that value
|
||||
if (a.hasValue(attrIndex)) {
|
||||
return a.getColor(attrIndex, defColor);
|
||||
}
|
||||
|
||||
// Otherwise fallback to the value of the private attribute
|
||||
int[] customAttrs = { privAttrId };
|
||||
a = ctw.obtainStyledAttributes(customAttrs);
|
||||
int color = a.getColor(0, defColor);
|
||||
a.recycle();
|
||||
return color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the {@link R.dimen#status_bar_header_height_keyguard}.
|
||||
*/
|
||||
|
||||
@@ -19,9 +19,9 @@ package com.android.systemui.media
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
import android.animation.ValueAnimator
|
||||
import android.graphics.Color
|
||||
import android.test.suitebuilder.annotation.SmallTest
|
||||
import android.testing.AndroidTestingRunner
|
||||
import android.testing.TestableLooper
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.monet.ColorScheme
|
||||
import junit.framework.Assert.assertEquals
|
||||
@@ -46,35 +46,28 @@ class ColorSchemeTransitionTest : SysuiTestCase() {
|
||||
|
||||
private interface ExtractCB : (ColorScheme) -> Int
|
||||
private interface ApplyCB : (Int) -> Unit
|
||||
private lateinit var colorTransition: AnimatingColorTransition
|
||||
private lateinit var colorTransition: ColorTransition
|
||||
private lateinit var colorSchemeTransition: ColorSchemeTransition
|
||||
|
||||
@Mock private lateinit var mockAnimatingTransition: AnimatingColorTransition
|
||||
@Mock private lateinit var mockGenericTransition: GenericColorTransition
|
||||
@Mock private lateinit var mockTransition: ColorTransition
|
||||
@Mock private lateinit var valueAnimator: ValueAnimator
|
||||
@Mock private lateinit var colorScheme: ColorScheme
|
||||
@Mock private lateinit var extractColor: ExtractCB
|
||||
@Mock private lateinit var applyColor: ApplyCB
|
||||
|
||||
private lateinit var animatingColorTransitionFactory: AnimatingColorTransitionFactory
|
||||
private lateinit var genericColorTransitionFactory: GenericColorTransitionFactory
|
||||
private lateinit var transitionFactory: ColorTransitionFactory
|
||||
@Mock private lateinit var mediaViewHolder: MediaViewHolder
|
||||
|
||||
@JvmField @Rule val mockitoRule = MockitoJUnit.rule()
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
animatingColorTransitionFactory = { _, _, _ -> mockAnimatingTransition }
|
||||
genericColorTransitionFactory = { _ -> mockGenericTransition }
|
||||
transitionFactory = { default, extractColor, applyColor -> mockTransition }
|
||||
whenever(extractColor.invoke(colorScheme)).thenReturn(TARGET_COLOR)
|
||||
|
||||
colorSchemeTransition = ColorSchemeTransition(
|
||||
context, mediaViewHolder, animatingColorTransitionFactory, genericColorTransitionFactory
|
||||
)
|
||||
colorSchemeTransition = ColorSchemeTransition(context, mediaViewHolder, transitionFactory)
|
||||
|
||||
colorTransition = object : AnimatingColorTransition(
|
||||
DEFAULT_COLOR, extractColor, applyColor
|
||||
) {
|
||||
colorTransition = object : ColorTransition(DEFAULT_COLOR, extractColor, applyColor) {
|
||||
override fun buildAnimator(): ValueAnimator {
|
||||
return valueAnimator
|
||||
}
|
||||
@@ -149,7 +142,6 @@ class ColorSchemeTransitionTest : SysuiTestCase() {
|
||||
@Test
|
||||
fun testColorSchemeTransition_update() {
|
||||
colorSchemeTransition.updateColorScheme(colorScheme)
|
||||
verify(mockAnimatingTransition, times(6)).updateColorScheme(colorScheme)
|
||||
verify(mockGenericTransition).updateColorScheme(colorScheme)
|
||||
verify(mockTransition, times(6)).updateColorScheme(colorScheme)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user