Loading packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java +3 −1 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ */ package com.android.keyguard; import static com.android.systemui.util.ColorUtilKt.getPrivateAttrColorIfUnset; import android.animation.AnimatorSet; import android.animation.ArgbEvaluator; import android.animation.ValueAnimator; Loading Loading @@ -152,7 +154,7 @@ class NumPadAnimator { ContextThemeWrapper ctw = new ContextThemeWrapper(context, mStyle); TypedArray a = ctw.obtainStyledAttributes(customAttrs); mNormalColor = Utils.getPrivateAttrColorIfUnset(ctw, a, 0, 0, mNormalColor = getPrivateAttrColorIfUnset(ctw, a, 0, 0, com.android.internal.R.attr.colorSurface); mHighlightColor = a.getColor(1, 0); a.recycle(); Loading packages/SystemUI/src/com/android/systemui/media/ColorSchemeTransition.kt +72 −17 Original line number Diff line number Diff line Loading @@ -21,24 +21,41 @@ 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 /** * ColorTransition is responsible for managing the animation between two specific colors. * 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. * 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 ColorTransition( open class AnimatingColorTransition( private val defaultColor: Int, private val extractColor: (ColorScheme) -> Int, private val applyColor: (Int) -> Unit ) : AnimatorUpdateListener { ) : AnimatorUpdateListener, ColorTransition { private val argbEvaluator = ArgbEvaluator() private val valueAnimator = buildAnimator() Loading @@ -53,7 +70,7 @@ open class ColorTransition( applyColor(currentColor) } fun updateColorScheme(scheme: ColorScheme?) { override fun updateColorScheme(scheme: ColorScheme?) { val newTargetColor = if (scheme == null) defaultColor else extractColor(scheme) if (newTargetColor != targetColor) { sourceColor = currentColor Loading @@ -76,7 +93,9 @@ open class ColorTransition( } } typealias ColorTransitionFactory = (Int, (ColorScheme) -> Int, (Int) -> Unit) -> ColorTransition typealias AnimatingColorTransitionFactory = (Int, (ColorScheme) -> Int, (Int) -> Unit) -> AnimatingColorTransition typealias GenericColorTransitionFactory = ((ColorScheme?) -> Unit) -> GenericColorTransition /** * ColorSchemeTransition constructs a ColorTransition for each color in the scheme Loading @@ -86,27 +105,26 @@ typealias ColorTransitionFactory = (Int, (ColorScheme) -> Int, (Int) -> Unit) -> class ColorSchemeTransition internal constructor( private val context: Context, mediaViewHolder: MediaViewHolder, colorTransitionFactory: ColorTransitionFactory animatingColorTransitionFactory: AnimatingColorTransitionFactory, genericColorTransitionFactory: GenericColorTransitionFactory ) { constructor(context: Context, mediaViewHolder: MediaViewHolder) : this(context, mediaViewHolder, ::ColorTransition) this(context, mediaViewHolder, ::AnimatingColorTransition, ::GenericColorTransition) val bgColor = context.getColor(com.android.systemui.R.color.material_dynamic_secondary95) val surfaceColor = colorTransitionFactory( val surfaceColor = animatingColorTransitionFactory( 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 = colorTransitionFactory( val accentPrimary = animatingColorTransitionFactory( loadDefaultColor(R.attr.textColorPrimary), ::accentPrimaryFromScheme ) { accentPrimary -> Loading @@ -116,7 +134,7 @@ class ColorSchemeTransition internal constructor( mediaViewHolder.gutsViewHolder.setAccentPrimaryColor(accentPrimary) } val textPrimary = colorTransitionFactory( val textPrimary = animatingColorTransitionFactory( loadDefaultColor(R.attr.textColorPrimary), ::textPrimaryFromScheme ) { textPrimary -> Loading @@ -132,28 +150,65 @@ class ColorSchemeTransition internal constructor( mediaViewHolder.gutsViewHolder.setTextPrimaryColor(textPrimary) } val textPrimaryInverse = colorTransitionFactory( val textPrimaryInverse = animatingColorTransitionFactory( loadDefaultColor(R.attr.textColorPrimaryInverse), ::textPrimaryInverseFromScheme ) { textPrimaryInverse -> mediaViewHolder.actionPlayPause.imageTintList = ColorStateList.valueOf(textPrimaryInverse) } val textSecondary = colorTransitionFactory( val textSecondary = animatingColorTransitionFactory( loadDefaultColor(R.attr.textColorSecondary), ::textSecondaryFromScheme ) { textSecondary -> mediaViewHolder.artistText.setTextColor(textSecondary) } val textTertiary = colorTransitionFactory( val textTertiary = animatingColorTransitionFactory( 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) surfaceColor, accentPrimary, textPrimary, textPrimaryInverse, textSecondary, textTertiary, backgroundGradient ) private fun loadDefaultColor(id: Int): Int { return Utils.getColorAttr(context, id).defaultColor Loading packages/SystemUI/src/com/android/systemui/media/MediaColorSchemes.kt +6 −0 Original line number Diff line number Diff line Loading @@ -35,3 +35,9 @@ 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 packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt +3 −10 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ 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 /** Loading Loading @@ -367,7 +368,7 @@ class LightRevealScrim(context: Context?, attrs: AttributeSet?) : View(context, } if (startColorAlpha > 0f) { canvas.drawColor(updateColorAlpha(revealGradientEndColor, startColorAlpha)) canvas.drawColor(getColorWithAlpha(revealGradientEndColor, startColorAlpha)) } with(shaderGradientMatrix) { Loading @@ -383,15 +384,7 @@ class LightRevealScrim(context: Context?, attrs: AttributeSet?) : View(context, private fun setPaintColorFilter() { gradientPaint.colorFilter = PorterDuffColorFilter( updateColorAlpha(revealGradientEndColor, revealGradientEndColorAlpha), getColorWithAlpha(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) ) } No newline at end of file packages/SystemUI/src/com/android/systemui/util/ColorUtil.kt 0 → 100644 +53 −0 Original line number Diff line number Diff line /* * 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 } Loading
packages/SystemUI/src/com/android/keyguard/NumPadAnimator.java +3 −1 Original line number Diff line number Diff line Loading @@ -15,6 +15,8 @@ */ package com.android.keyguard; import static com.android.systemui.util.ColorUtilKt.getPrivateAttrColorIfUnset; import android.animation.AnimatorSet; import android.animation.ArgbEvaluator; import android.animation.ValueAnimator; Loading Loading @@ -152,7 +154,7 @@ class NumPadAnimator { ContextThemeWrapper ctw = new ContextThemeWrapper(context, mStyle); TypedArray a = ctw.obtainStyledAttributes(customAttrs); mNormalColor = Utils.getPrivateAttrColorIfUnset(ctw, a, 0, 0, mNormalColor = getPrivateAttrColorIfUnset(ctw, a, 0, 0, com.android.internal.R.attr.colorSurface); mHighlightColor = a.getColor(1, 0); a.recycle(); Loading
packages/SystemUI/src/com/android/systemui/media/ColorSchemeTransition.kt +72 −17 Original line number Diff line number Diff line Loading @@ -21,24 +21,41 @@ 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 /** * ColorTransition is responsible for managing the animation between two specific colors. * 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. * 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 ColorTransition( open class AnimatingColorTransition( private val defaultColor: Int, private val extractColor: (ColorScheme) -> Int, private val applyColor: (Int) -> Unit ) : AnimatorUpdateListener { ) : AnimatorUpdateListener, ColorTransition { private val argbEvaluator = ArgbEvaluator() private val valueAnimator = buildAnimator() Loading @@ -53,7 +70,7 @@ open class ColorTransition( applyColor(currentColor) } fun updateColorScheme(scheme: ColorScheme?) { override fun updateColorScheme(scheme: ColorScheme?) { val newTargetColor = if (scheme == null) defaultColor else extractColor(scheme) if (newTargetColor != targetColor) { sourceColor = currentColor Loading @@ -76,7 +93,9 @@ open class ColorTransition( } } typealias ColorTransitionFactory = (Int, (ColorScheme) -> Int, (Int) -> Unit) -> ColorTransition typealias AnimatingColorTransitionFactory = (Int, (ColorScheme) -> Int, (Int) -> Unit) -> AnimatingColorTransition typealias GenericColorTransitionFactory = ((ColorScheme?) -> Unit) -> GenericColorTransition /** * ColorSchemeTransition constructs a ColorTransition for each color in the scheme Loading @@ -86,27 +105,26 @@ typealias ColorTransitionFactory = (Int, (ColorScheme) -> Int, (Int) -> Unit) -> class ColorSchemeTransition internal constructor( private val context: Context, mediaViewHolder: MediaViewHolder, colorTransitionFactory: ColorTransitionFactory animatingColorTransitionFactory: AnimatingColorTransitionFactory, genericColorTransitionFactory: GenericColorTransitionFactory ) { constructor(context: Context, mediaViewHolder: MediaViewHolder) : this(context, mediaViewHolder, ::ColorTransition) this(context, mediaViewHolder, ::AnimatingColorTransition, ::GenericColorTransition) val bgColor = context.getColor(com.android.systemui.R.color.material_dynamic_secondary95) val surfaceColor = colorTransitionFactory( val surfaceColor = animatingColorTransitionFactory( 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 = colorTransitionFactory( val accentPrimary = animatingColorTransitionFactory( loadDefaultColor(R.attr.textColorPrimary), ::accentPrimaryFromScheme ) { accentPrimary -> Loading @@ -116,7 +134,7 @@ class ColorSchemeTransition internal constructor( mediaViewHolder.gutsViewHolder.setAccentPrimaryColor(accentPrimary) } val textPrimary = colorTransitionFactory( val textPrimary = animatingColorTransitionFactory( loadDefaultColor(R.attr.textColorPrimary), ::textPrimaryFromScheme ) { textPrimary -> Loading @@ -132,28 +150,65 @@ class ColorSchemeTransition internal constructor( mediaViewHolder.gutsViewHolder.setTextPrimaryColor(textPrimary) } val textPrimaryInverse = colorTransitionFactory( val textPrimaryInverse = animatingColorTransitionFactory( loadDefaultColor(R.attr.textColorPrimaryInverse), ::textPrimaryInverseFromScheme ) { textPrimaryInverse -> mediaViewHolder.actionPlayPause.imageTintList = ColorStateList.valueOf(textPrimaryInverse) } val textSecondary = colorTransitionFactory( val textSecondary = animatingColorTransitionFactory( loadDefaultColor(R.attr.textColorSecondary), ::textSecondaryFromScheme ) { textSecondary -> mediaViewHolder.artistText.setTextColor(textSecondary) } val textTertiary = colorTransitionFactory( val textTertiary = animatingColorTransitionFactory( 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) surfaceColor, accentPrimary, textPrimary, textPrimaryInverse, textSecondary, textTertiary, backgroundGradient ) private fun loadDefaultColor(id: Int): Int { return Utils.getColorAttr(context, id).defaultColor Loading
packages/SystemUI/src/com/android/systemui/media/MediaColorSchemes.kt +6 −0 Original line number Diff line number Diff line Loading @@ -35,3 +35,9 @@ 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
packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt +3 −10 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ 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 /** Loading Loading @@ -367,7 +368,7 @@ class LightRevealScrim(context: Context?, attrs: AttributeSet?) : View(context, } if (startColorAlpha > 0f) { canvas.drawColor(updateColorAlpha(revealGradientEndColor, startColorAlpha)) canvas.drawColor(getColorWithAlpha(revealGradientEndColor, startColorAlpha)) } with(shaderGradientMatrix) { Loading @@ -383,15 +384,7 @@ class LightRevealScrim(context: Context?, attrs: AttributeSet?) : View(context, private fun setPaintColorFilter() { gradientPaint.colorFilter = PorterDuffColorFilter( updateColorAlpha(revealGradientEndColor, revealGradientEndColorAlpha), getColorWithAlpha(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) ) } No newline at end of file
packages/SystemUI/src/com/android/systemui/util/ColorUtil.kt 0 → 100644 +53 −0 Original line number Diff line number Diff line /* * 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 }