Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9d450d0c authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "[Media] Update background gradient scrim to use album theme colors."...

Merge "[Media] Update background gradient scrim to use album theme colors." into tm-dev am: 64bf097a am: 5d7b72bf

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17896371



Change-Id: I9327318d9eacc6850073d3cc0723b14390b836fc
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 3380e774 5d7b72bf
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -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;
@@ -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();
+72 −17
Original line number Diff line number Diff line
@@ -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()
@@ -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
@@ -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
@@ -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 ->
@@ -116,7 +134,7 @@ class ColorSchemeTransition internal constructor(
        mediaViewHolder.gutsViewHolder.setAccentPrimaryColor(accentPrimary)
    }

    val textPrimary = colorTransitionFactory(
    val textPrimary = animatingColorTransitionFactory(
        loadDefaultColor(R.attr.textColorPrimary),
        ::textPrimaryFromScheme
    ) { textPrimary ->
@@ -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
+6 −0
Original line number Diff line number Diff line
@@ -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
+3 −10
Original line number Diff line number Diff line
@@ -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

/**
@@ -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) {
@@ -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
+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