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

Commit c5c196eb authored by Michael Mikhail's avatar Michael Mikhail Committed by Automerger Merge Worker
Browse files

Merge "Intensify recommendation gradient and scale the cover." into tm-qpr-dev...

Merge "Intensify recommendation gradient and scale the cover." into tm-qpr-dev am: 7ef14ecb am: 7510b55e am: 5aaa7783

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



Change-Id: I42696090adefd063bbcf3bd6dd009ff68d361713
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents c47cd512 5aaa7783
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
<?xml version="1.0" encoding="utf-8"?>
<!--
  ~ Copyright (C) 2023 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
  -->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
    android:shape="rectangle">
    <!-- gradient from 25% in the center to 100% at edges -->
    <gradient
        android:type="radial"
        android:gradientRadius="40%p"
        android:startColor="#AE000000"
        android:endColor="#00000000" />
</shape>
 No newline at end of file
+2 −1
Original line number Diff line number Diff line
@@ -22,9 +22,10 @@
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:translationZ="0dp"
        android:scaleType="centerCrop"
        android:scaleType="matrix"
        android:adjustViewBounds="true"
        android:clipToOutline="true"
        android:layerType="hardware"
        android:background="@drawable/bg_smartspace_media_item"/>

    <!-- App icon -->
+73 −16
Original line number Diff line number Diff line
@@ -32,12 +32,15 @@ import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.graphics.Bitmap;
import android.graphics.BlendMode;
import android.graphics.Color;
import android.graphics.ColorMatrix;
import android.graphics.ColorMatrixColorFilter;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.graphics.drawable.Animatable;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.GradientDrawable;
@@ -63,7 +66,6 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.constraintlayout.widget.ConstraintSet;

import com.android.internal.annotations.VisibleForTesting;
@@ -146,6 +148,12 @@ public class MediaControlPanel {
    private static final int SMARTSPACE_CARD_CLICK_EVENT = 760;
    protected static final int SMARTSPACE_CARD_DISMISS_EVENT = 761;

    private static final float REC_MEDIA_COVER_SCALE_FACTOR = 1.25f;
    private static final float MEDIA_SCRIM_START_ALPHA = 0.25f;
    private static final float MEDIA_REC_SCRIM_START_ALPHA = 0.15f;
    private static final float MEDIA_PLAYER_SCRIM_END_ALPHA = 0.9f;
    private static final float MEDIA_REC_SCRIM_END_ALPHA = 1.0f;

    private static final Intent SETTINGS_INTENT = new Intent(ACTION_MEDIA_CONTROLS_SETTINGS);

    // Buttons to show in small player when using semantic actions
@@ -779,7 +787,7 @@ public class MediaControlPanel {
            WallpaperColors wallpaperColors = getWallpaperColor(artworkIcon);
            if (wallpaperColors != null) {
                mutableColorScheme = new ColorScheme(wallpaperColors, true, Style.CONTENT);
                artwork = addGradientToIcon(artworkIcon, mutableColorScheme, width, height);
                artwork = addGradientToPlayerAlbum(artworkIcon, mutableColorScheme, width, height);
                isArtworkBound = true;
            } else {
                // If there's no artwork, use colors from the app icon
@@ -869,8 +877,9 @@ public class MediaControlPanel {
        Trace.beginAsyncSection(traceName, traceCookie);

        // Capture width & height from views in foreground for artwork scaling in background
        int width = mRecommendationViewHolder.getMediaCoverContainers().get(0).getMeasuredWidth();
        int height = mRecommendationViewHolder.getMediaCoverContainers().get(0).getMeasuredHeight();
        int width = mContext.getResources().getDimensionPixelSize(R.dimen.qs_media_rec_album_width);
        int height = mContext.getResources().getDimensionPixelSize(
                R.dimen.qs_media_rec_album_height_expanded);

        mBackgroundExecutor.execute(() -> {
            // Album art
@@ -880,7 +889,8 @@ public class MediaControlPanel {
            WallpaperColors wallpaperColors = getWallpaperColor(artworkIcon);
            if (wallpaperColors != null) {
                mutableColorScheme = new ColorScheme(wallpaperColors, true, Style.CONTENT);
                artwork = addGradientToIcon(artworkIcon, mutableColorScheme, width, height);
                artwork = addGradientToRecommendationAlbum(artworkIcon, mutableColorScheme, width,
                        height);
            } else {
                artwork = new ColorDrawable(Color.TRANSPARENT);
            }
@@ -889,6 +899,11 @@ public class MediaControlPanel {
                // Bind the artwork drawable to media cover.
                ImageView mediaCover =
                        mRecommendationViewHolder.getMediaCoverItems().get(itemIndex);
                // Rescale media cover
                Matrix coverMatrix = new Matrix(mediaCover.getImageMatrix());
                coverMatrix.postScale(REC_MEDIA_COVER_SCALE_FACTOR, REC_MEDIA_COVER_SCALE_FACTOR,
                        0.5f * width, 0.5f * height);
                mediaCover.setImageMatrix(coverMatrix);
                mediaCover.setImageDrawable(artwork);

                // Set up the app icon.
@@ -910,7 +925,8 @@ public class MediaControlPanel {
    // This method should be called from a background thread. WallpaperColors.fromBitmap takes a
    // good amount of time. We do that work on the background executor to avoid stalling animations
    // on the UI Thread.
    private WallpaperColors getWallpaperColor(Icon artworkIcon) {
    @VisibleForTesting
    protected WallpaperColors getWallpaperColor(Icon artworkIcon) {
        if (artworkIcon != null) {
            if (artworkIcon.getType() == Icon.TYPE_BITMAP
                    || artworkIcon.getType() == Icon.TYPE_ADAPTIVE_BITMAP) {
@@ -928,22 +944,40 @@ public class MediaControlPanel {
        return null;
    }

    private LayerDrawable addGradientToIcon(
            Icon artworkIcon,
            ColorScheme mutableColorScheme,
            int width,
            int height
    ) {
    @VisibleForTesting
    protected LayerDrawable addGradientToPlayerAlbum(Icon artworkIcon,
            ColorScheme mutableColorScheme, int width, int height) {
        Drawable albumArt = getScaledBackground(artworkIcon, width, height);
        GradientDrawable gradient = (GradientDrawable) AppCompatResources
                .getDrawable(mContext, R.drawable.qs_media_scrim);
        GradientDrawable gradient = (GradientDrawable) mContext.getDrawable(
                R.drawable.qs_media_scrim).mutate();
        return setupGradientColorOnDrawable(albumArt, gradient, mutableColorScheme,
                MEDIA_SCRIM_START_ALPHA, MEDIA_PLAYER_SCRIM_END_ALPHA);
    }

    @VisibleForTesting
    protected LayerDrawable addGradientToRecommendationAlbum(Icon artworkIcon,
            ColorScheme mutableColorScheme, int width, int height) {
        // First try scaling rec card using bitmap drawable.
        // If returns null, set drawable bounds.
        Drawable albumArt = getScaledRecommendationCover(artworkIcon, width, height);
        if (albumArt == null) {
            albumArt = getScaledBackground(artworkIcon, width, height);
        }
        GradientDrawable gradient = (GradientDrawable) mContext.getDrawable(
                R.drawable.qs_media_rec_scrim).mutate();
        return setupGradientColorOnDrawable(albumArt, gradient, mutableColorScheme,
                MEDIA_REC_SCRIM_START_ALPHA, MEDIA_REC_SCRIM_END_ALPHA);
    }

    private LayerDrawable setupGradientColorOnDrawable(Drawable albumArt, GradientDrawable gradient,
            ColorScheme mutableColorScheme, float startAlpha, float endAlpha) {
        gradient.setColors(new int[] {
                ColorUtilKt.getColorWithAlpha(
                        MediaColorSchemesKt.backgroundStartFromScheme(mutableColorScheme),
                        0.25f),
                        startAlpha),
                ColorUtilKt.getColorWithAlpha(
                        MediaColorSchemesKt.backgroundEndFromScheme(mutableColorScheme),
                        0.9f),
                        endAlpha),
        });
        return new LayerDrawable(new Drawable[] { albumArt, gradient });
    }
@@ -1588,6 +1622,29 @@ public class MediaControlPanel {
        return drawable;
    }

    /**
     * Scale artwork to fill the background of media covers in recommendation card.
     */
    @UiThread
    private Drawable getScaledRecommendationCover(Icon artworkIcon, int width, int height) {
        if (width == 0 || height == 0) {
            return null;
        }
        if (artworkIcon != null) {
            Bitmap bitmap;
            if (artworkIcon.getType() == Icon.TYPE_BITMAP
                    || artworkIcon.getType() == Icon.TYPE_ADAPTIVE_BITMAP) {
                Bitmap artworkBitmap = artworkIcon.getBitmap();
                if (artworkBitmap != null) {
                    bitmap = Bitmap.createScaledBitmap(artworkIcon.getBitmap(), width,
                            height, false);
                    return new BitmapDrawable(mContext.getResources(), bitmap);
                }
            }
        }
        return null;
    }

    /**
     * Get the current media controller
     *
+61 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.content.pm.PackageManager
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Matrix
import android.graphics.drawable.Animatable2
import android.graphics.drawable.AnimatedVectorDrawable
import android.graphics.drawable.Drawable
@@ -78,6 +79,8 @@ import com.android.systemui.media.controls.pipeline.EMPTY_SMARTSPACE_MEDIA_DATA
import com.android.systemui.media.controls.pipeline.MediaDataManager
import com.android.systemui.media.controls.util.MediaUiEventLogger
import com.android.systemui.media.dialog.MediaOutputDialogFactory
import com.android.systemui.monet.ColorScheme
import com.android.systemui.monet.Style
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.FalsingManager
import com.android.systemui.statusbar.NotificationLockscreenUserManager
@@ -214,6 +217,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
    @Mock private lateinit var recSubtitleMock2: TextView
    @Mock private lateinit var recSubtitleMock3: TextView
    @Mock private lateinit var coverItem: ImageView
    @Mock private lateinit var matrix: Matrix
    private lateinit var coverItem1: ImageView
    private lateinit var coverItem2: ImageView
    private lateinit var coverItem3: ImageView
@@ -699,6 +703,33 @@ public class MediaControlPanelTest : SysuiTestCase() {
        verify(albumView, times(3)).setImageDrawable(any(Drawable::class.java))
    }

    @Test
    fun addTwoPlayerGradients_differentStates() {
        // Setup redArtwork and its color scheme.
        val redBmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
        val redCanvas = Canvas(redBmp)
        redCanvas.drawColor(Color.RED)
        val redArt = Icon.createWithBitmap(redBmp)
        val redWallpaperColor = player.getWallpaperColor(redArt)
        val redColorScheme = ColorScheme(redWallpaperColor, true, Style.CONTENT)

        // Setup greenArt and its color scheme.
        val greenBmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
        val greenCanvas = Canvas(greenBmp)
        greenCanvas.drawColor(Color.GREEN)
        val greenArt = Icon.createWithBitmap(greenBmp)
        val greenWallpaperColor = player.getWallpaperColor(greenArt)
        val greenColorScheme = ColorScheme(greenWallpaperColor, true, Style.CONTENT)

        // Add gradient to both icons.
        val redArtwork = player.addGradientToPlayerAlbum(redArt, redColorScheme, 10, 10)
        val greenArtwork = player.addGradientToPlayerAlbum(greenArt, greenColorScheme, 10, 10)

        // They should have different constant states as they have different gradient color.
        assertThat(redArtwork.getDrawable(1).constantState)
            .isNotEqualTo(greenArtwork.getDrawable(1).constantState)
    }

    @Test
    fun bind_seekBarDisabled_hasActions_seekBarVisibilityIsSetToInvisible() {
        useRealConstraintSets()
@@ -2092,6 +2123,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
            .thenReturn(listOf(recProgressBar1, recProgressBar2, recProgressBar3))
        whenever(recommendationViewHolder.mediaSubtitles)
            .thenReturn(listOf(recSubtitleMock1, recSubtitleMock2, recSubtitleMock3))
        whenever(coverItem.imageMatrix).thenReturn(matrix)

        val bmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
        val canvas = Canvas(bmp)
@@ -2127,6 +2159,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
        verify(recCardTitle).setTextColor(any<Int>())
        verify(recAppIconItem, times(3)).setImageDrawable(any(Drawable::class.java))
        verify(coverItem, times(3)).setImageDrawable(any(Drawable::class.java))
        verify(coverItem, times(3)).imageMatrix = any()
    }

    @Test
@@ -2188,6 +2221,34 @@ public class MediaControlPanelTest : SysuiTestCase() {
        verify(recSubtitleMock3).visibility = View.VISIBLE
    }

    @Test
    fun addTwoRecommendationGradients_differentStates() {
        // Setup redArtwork and its color scheme.
        val redBmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
        val redCanvas = Canvas(redBmp)
        redCanvas.drawColor(Color.RED)
        val redArt = Icon.createWithBitmap(redBmp)
        val redWallpaperColor = player.getWallpaperColor(redArt)
        val redColorScheme = ColorScheme(redWallpaperColor, true, Style.CONTENT)

        // Setup greenArt and its color scheme.
        val greenBmp = Bitmap.createBitmap(10, 10, Bitmap.Config.ARGB_8888)
        val greenCanvas = Canvas(greenBmp)
        greenCanvas.drawColor(Color.GREEN)
        val greenArt = Icon.createWithBitmap(greenBmp)
        val greenWallpaperColor = player.getWallpaperColor(greenArt)
        val greenColorScheme = ColorScheme(greenWallpaperColor, true, Style.CONTENT)

        // Add gradient to both icons.
        val redArtwork = player.addGradientToRecommendationAlbum(redArt, redColorScheme, 10, 10)
        val greenArtwork =
            player.addGradientToRecommendationAlbum(greenArt, greenColorScheme, 10, 10)

        // They should have different constant states as they have different gradient color.
        assertThat(redArtwork.getDrawable(1).constantState)
            .isNotEqualTo(greenArtwork.getDrawable(1).constantState)
    }

    @Test
    fun onButtonClick_touchRippleFlagEnabled_playsTouchRipple() {
        fakeFeatureFlag.set(Flags.UMO_SURFACE_RIPPLE, true)