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

Commit ab3d4e41 authored by Caitlin Cassidy's avatar Caitlin Cassidy
Browse files

[Media Recs] Update colors to be themed based on the app icon and always

dark mode.

Fixes: 229757852
Test: manual (see bug for screenshot)
Change-Id: I893101fd4526536c8e81efb06c3605679524e0f2
parent 54ad297e
Loading
Loading
Loading
Loading
+44 −46
Original line number Diff line number Diff line
@@ -95,8 +95,8 @@ class ColorSchemeTransition internal constructor(

    val surfaceColor = colorTransitionFactory(
        bgColor,
        { colorScheme -> colorScheme.accent2[9] }, // A2-800
        { surfaceColor ->
        ::surfaceFromScheme
    ) { surfaceColor ->
        val colorList = ColorStateList.valueOf(surfaceColor)
        mediaViewHolder.player.backgroundTintList = colorList
        mediaViewHolder.albumView.foregroundTintList = colorList
@@ -104,24 +104,24 @@ class ColorSchemeTransition internal constructor(
        mediaViewHolder.seamlessIcon.imageTintList = colorList
        mediaViewHolder.seamlessText.setTextColor(surfaceColor)
        mediaViewHolder.dismissText.setTextColor(surfaceColor)
        })
    }

    val accentPrimary = colorTransitionFactory(
        loadDefaultColor(R.attr.textColorPrimary),
        { colorScheme -> colorScheme.accent1[2] }, // A1-100
        { accentPrimary ->
        ::accentPrimaryFromScheme
    ) { accentPrimary ->
        val accentColorList = ColorStateList.valueOf(accentPrimary)
        mediaViewHolder.actionPlayPause.backgroundTintList = accentColorList
        mediaViewHolder.seamlessButton.backgroundTintList = accentColorList
        mediaViewHolder.settings.imageTintList = accentColorList
        mediaViewHolder.cancelText.backgroundTintList = accentColorList
        mediaViewHolder.dismissText.backgroundTintList = accentColorList
        })
    }

    val textPrimary = colorTransitionFactory(
        loadDefaultColor(R.attr.textColorPrimary),
        { colorScheme -> colorScheme.neutral1[1] }, // N1-50
        { textPrimary ->
        ::textPrimaryFromScheme
    ) { textPrimary ->
        mediaViewHolder.titleText.setTextColor(textPrimary)
        val textColorList = ColorStateList.valueOf(textPrimary)
        mediaViewHolder.seekBar.thumb.setTintList(textColorList)
@@ -133,28 +133,26 @@ class ColorSchemeTransition internal constructor(
        for (button in mediaViewHolder.getTransparentActionButtons()) {
            button.imageTintList = textColorList
        }
        })
    }

    val textPrimaryInverse = colorTransitionFactory(
        loadDefaultColor(R.attr.textColorPrimaryInverse),
        { colorScheme -> colorScheme.neutral1[10] }, // N1-900
        { textPrimaryInverse ->
            mediaViewHolder.actionPlayPause.imageTintList =
                ColorStateList.valueOf(textPrimaryInverse)
        })
        ::textPrimaryInverseFromScheme
    ) { textPrimaryInverse ->
        mediaViewHolder.actionPlayPause.imageTintList = ColorStateList.valueOf(textPrimaryInverse)
    }

    val textSecondary = colorTransitionFactory(
        loadDefaultColor(R.attr.textColorSecondary),
        { colorScheme -> colorScheme.neutral2[3] }, // N2-200
        { textSecondary -> mediaViewHolder.artistText.setTextColor(textSecondary) })
        ::textSecondaryFromScheme
    ) { textSecondary -> mediaViewHolder.artistText.setTextColor(textSecondary) }

    val textTertiary = colorTransitionFactory(
        loadDefaultColor(R.attr.textColorTertiary),
        { colorScheme -> colorScheme.neutral2[5] }, // N2-400
        { textTertiary ->
            mediaViewHolder.seekBar.progressBackgroundTintList =
                ColorStateList.valueOf(textTertiary)
        })
        ::textTertiaryFromScheme
    ) { textTertiary ->
        mediaViewHolder.seekBar.progressBackgroundTintList = ColorStateList.valueOf(textTertiary)
    }

    val colorTransitions = arrayOf(
        surfaceColor, accentPrimary, textPrimary,
+37 −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.media

import com.android.systemui.monet.ColorScheme

/** Returns the surface color for media controls based on the scheme. */
internal fun surfaceFromScheme(scheme: ColorScheme) = scheme.accent2[9] // A2-800

/** Returns the primary accent color for media controls based on the scheme. */
internal fun accentPrimaryFromScheme(scheme: ColorScheme) = scheme.accent1[2] // A1-100

/** Returns the primary text color for media controls based on the scheme. */
internal fun textPrimaryFromScheme(scheme: ColorScheme) = scheme.neutral1[1] // N1-50

/** Returns the inverse of the primary text color for media controls based on the scheme. */
internal fun textPrimaryInverseFromScheme(scheme: ColorScheme) = scheme.neutral1[10] // N1-900

/** Returns the secondary text color for media controls based on the scheme. */
internal fun textSecondaryFromScheme(scheme: ColorScheme) = scheme.neutral2[3] // N2-200

/** Returns the tertiary text color for media controls based on the scheme. */
internal fun textTertiaryFromScheme(scheme: ColorScheme) = scheme.neutral2[5] // N2-400
+26 −7
Original line number Diff line number Diff line
@@ -60,7 +60,6 @@ import androidx.constraintlayout.widget.ConstraintSet;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.jank.InteractionJankMonitor;
import com.android.internal.logging.InstanceId;
import com.android.settingslib.Utils;
import com.android.settingslib.widget.AdaptiveIcon;
import com.android.systemui.ActivityIntentHelper;
import com.android.systemui.R;
@@ -973,8 +972,6 @@ public class MediaControlPanel {
        mPackageName = data.getPackageName();
        mInstanceId = data.getInstanceId();
        TransitionLayout recommendationCard = mRecommendationViewHolder.getRecommendations();
        recommendationCard.setBackgroundTintList(
                Utils.getColorAttr(mContext, com.android.internal.R.attr.colorSurface));

        List<SmartspaceAction> mediaRecommendationList = data.getRecommendations();
        if (mediaRecommendationList == null || mediaRecommendationList.isEmpty()) {
@@ -998,6 +995,7 @@ public class MediaControlPanel {
        Drawable icon = packageManager.getApplicationIcon(applicationInfo);
        ImageView headerLogoImageView = mRecommendationViewHolder.getCardIcon();
        headerLogoImageView.setImageDrawable(icon);
        fetchAndUpdateRecommendationColors(icon);

        // Set up media source app's label text.
        CharSequence appName = getAppName(data.getCardAction());
@@ -1073,8 +1071,6 @@ public class MediaControlPanel {
            TextView titleView =
                    mRecommendationViewHolder.getMediaTitles().get(uiComponentIndex);
            titleView.setText(title);
            titleView.setTextColor(Utils.getColorAttrDefaultColor(
                    mContext, com.android.internal.R.attr.textColorPrimary));
            // TODO(b/223603970): If none of them have titles, should we then hide the views?

            // Set up subtitle
@@ -1085,8 +1081,6 @@ public class MediaControlPanel {
            boolean shouldShowSubtitleText = !TextUtils.isEmpty(title);
            CharSequence subtitleText = shouldShowSubtitleText ? subtitle : "";
            subtitleView.setText(subtitleText);
            subtitleView.setTextColor(Utils.getColorAttrDefaultColor(
                    mContext, com.android.internal.R.attr.textColorSecondary));
            // TODO(b/223603970): If none of them have subtitles, should we then hide the views?

            uiComponentIndex++;
@@ -1128,6 +1122,31 @@ public class MediaControlPanel {
        }
    }

    private void fetchAndUpdateRecommendationColors(Drawable appIcon) {
        mBackgroundExecutor.execute(() -> {
            ColorScheme colorScheme = new ColorScheme(
                    WallpaperColors.fromDrawable(appIcon), /* darkTheme= */ true);
            mMainExecutor.execute(() -> setRecommendationColors(colorScheme));
        });
    }

    private void setRecommendationColors(ColorScheme colorScheme) {
        if (mRecommendationViewHolder == null) {
            return;
        }

        int backgroundColor = MediaColorSchemesKt.surfaceFromScheme(colorScheme);
        int textPrimaryColor = MediaColorSchemesKt.textPrimaryFromScheme(colorScheme);
        int textSecondaryColor = MediaColorSchemesKt.textSecondaryFromScheme(colorScheme);

        mRecommendationViewHolder.getRecommendations()
                .setBackgroundTintList(ColorStateList.valueOf(backgroundColor));
        mRecommendationViewHolder.getMediaTitles().forEach(
                (title) -> title.setTextColor(textPrimaryColor));
        mRecommendationViewHolder.getMediaSubtitles().forEach(
                (subtitle) -> subtitle.setTextColor(textSecondaryColor));
    }

    /**
     * Close the guts for this player.
     *