summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Cecilia Hong <xiaotinghong@google.com> 2021-04-10 14:55:08 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2021-04-10 14:55:08 +0000
commitd8a78dcb51f7281bd89f222f8e84bb0e7d394b40 (patch)
treebb67cd8615e914753a98404ecf6e1cf635a79d0a
parent34440439c57a2ea0f751b9fe673a10ed3f7a971c (diff)
parent629f3cb0bb6f587795a4d418ec17b9d1bb202a30 (diff)
Merge "Add Smartspace media card in media carousel when the Ss data is available." into sc-dev
-rw-r--r--packages/SystemUI/res/drawable/bg_smartspace_media_item.xml21
-rw-r--r--packages/SystemUI/res/layout/smartspace_card_media.xml86
-rw-r--r--packages/SystemUI/res/values/dimens.xml6
-rw-r--r--packages/SystemUI/res/xml/media_recommendation.xml97
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt80
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt2
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java201
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt10
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt15
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt33
-rw-r--r--packages/SystemUI/src/com/android/systemui/media/RecommendationViewHolder.kt61
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt42
12 files changed, 566 insertions, 88 deletions
diff --git a/packages/SystemUI/res/drawable/bg_smartspace_media_item.xml b/packages/SystemUI/res/drawable/bg_smartspace_media_item.xml
new file mode 100644
index 000000000000..69390848245d
--- /dev/null
+++ b/packages/SystemUI/res/drawable/bg_smartspace_media_item.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2020 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">
+ <solid android:color="@android:color/white" />
+ <corners android:radius="@dimen/qs_media_album_radius" />
+</shape> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/smartspace_card_media.xml b/packages/SystemUI/res/layout/smartspace_card_media.xml
new file mode 100644
index 000000000000..a03044f014d4
--- /dev/null
+++ b/packages/SystemUI/res/layout/smartspace_card_media.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2019 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
+ -->
+
+<com.android.systemui.util.animation.TransitionLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/media_recommendations"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="8dp"
+ android:paddingBottom="8dp"
+ android:clipChildren="false"
+ android:clipToPadding="false"
+ android:forceHasOverlappingRendering="false"
+ android:background="@drawable/qs_media_background">
+
+ <ImageView
+ android:id="@+id/media_cover1"
+ android:layout_width="@dimen/qs_aa_media_rec_album_size"
+ android:layout_height="@dimen/qs_aa_media_rec_album_size"
+ android:adjustViewBounds="true"
+ android:background="@drawable/bg_smartspace_media_item"
+ android:clipToOutline="true"
+ android:scaleType="centerCrop"/>
+
+ <ImageView
+ android:id="@+id/media_logo1"
+ android:layout_width="@dimen/qs_aa_media_rec_icon_size"
+ android:layout_height="@dimen/qs_aa_media_rec_icon_size" />
+
+ <ImageView
+ android:id="@+id/media_cover2"
+ android:layout_width="@dimen/qs_aa_media_rec_album_size"
+ android:layout_height="@dimen/qs_aa_media_rec_album_size"
+ android:adjustViewBounds="true"
+ android:background="@drawable/bg_smartspace_media_item"
+ android:clipToOutline="true"
+ android:scaleType="centerCrop"/>
+
+ <ImageView
+ android:id="@+id/media_logo2"
+ android:layout_width="@dimen/qs_aa_media_rec_icon_size"
+ android:layout_height="@dimen/qs_aa_media_rec_icon_size" />
+
+ <ImageView
+ android:id="@+id/media_cover3"
+ android:layout_width="@dimen/qs_aa_media_rec_album_size"
+ android:layout_height="@dimen/qs_aa_media_rec_album_size"
+ android:adjustViewBounds="true"
+ android:background="@drawable/bg_smartspace_media_item"
+ android:clipToOutline="true"
+ android:scaleType="centerCrop"/>
+
+ <ImageView
+ android:id="@+id/media_logo3"
+ android:layout_width="@dimen/qs_aa_media_rec_icon_size"
+ android:layout_height="@dimen/qs_aa_media_rec_icon_size" />
+
+ <ImageView
+ android:id="@+id/media_cover4"
+ android:layout_width="@dimen/qs_aa_media_rec_album_size"
+ android:layout_height="@dimen/qs_aa_media_rec_album_size"
+ android:adjustViewBounds="true"
+ android:background="@drawable/bg_smartspace_media_item"
+ android:clipToOutline="true"
+ android:scaleType="centerCrop"/>
+
+ <ImageView
+ android:id="@+id/media_logo4"
+ android:layout_width="@dimen/qs_aa_media_rec_icon_size"
+ android:layout_height="@dimen/qs_aa_media_rec_icon_size" />
+
+</com.android.systemui.util.animation.TransitionLayout> \ No newline at end of file
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 3cd7a0b2da58..eb19b2eaba9a 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -1232,6 +1232,7 @@
<dimen name="qs_media_padding">16dp</dimen>
<dimen name="qs_media_panel_outer_padding">16dp</dimen>
<dimen name="qs_media_album_size">120dp</dimen>
+ <dimen name="qs_media_album_radius">14dp</dimen>
<dimen name="qs_media_icon_size">16dp</dimen>
<dimen name="qs_center_guideline_padding">10dp</dimen>
<dimen name="qs_seamless_icon_size">@dimen/qs_media_icon_size</dimen>
@@ -1244,6 +1245,11 @@
<dimen name="qs_media_enabled_seekbar_vertical_padding">15dp</dimen>
<dimen name="qs_media_disabled_seekbar_vertical_padding">16dp</dimen>
+ <!-- Size of Smartspace media recommendations cards in the QSPanel carousel -->
+ <dimen name="qs_aa_media_rec_album_size">80dp</dimen>
+ <dimen name="qs_aa_media_rec_icon_size">20dp</dimen>
+
+
<!-- Window magnification -->
<dimen name="magnification_border_drag_size">35dp</dimen>
<dimen name="magnification_outer_border_margin">15dp</dimen>
diff --git a/packages/SystemUI/res/xml/media_recommendation.xml b/packages/SystemUI/res/xml/media_recommendation.xml
new file mode 100644
index 000000000000..a1bd231806a1
--- /dev/null
+++ b/packages/SystemUI/res/xml/media_recommendation.xml
@@ -0,0 +1,97 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2020 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
+ -->
+<ConstraintSet
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto">
+
+ <Constraint
+ android:id="@+id/media_cover1"
+ android:layout_width="@dimen/qs_aa_media_rec_album_size"
+ android:layout_height="@dimen/qs_aa_media_rec_album_size"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toStartOf="@id/media_cover2"
+ app:layout_constraintHorizontal_weight="1"
+ android:visibility="gone"/>
+
+ <Constraint
+ android:id="@+id/media_logo1"
+ android:layout_width="@dimen/qs_aa_media_rec_icon_size"
+ android:layout_height="@dimen/qs_aa_media_rec_icon_size"
+ app:layout_constraintEnd_toEndOf="@+id/media_cover1"
+ app:layout_constraintBottom_toBottomOf="@+id/media_cover1"
+ android:visibility="gone" />
+
+ <Constraint
+ android:id="@+id/media_cover2"
+ android:layout_width="@dimen/qs_aa_media_rec_album_size"
+ android:layout_height="@dimen/qs_aa_media_rec_album_size"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toEndOf="@id/media_cover1"
+ app:layout_constraintEnd_toStartOf="@id/media_cover3"
+ app:layout_constraintHorizontal_weight="1"
+ android:visibility="gone"/>
+
+ <Constraint
+ android:id="@+id/media_logo2"
+ android:layout_width="@dimen/qs_aa_media_rec_icon_size"
+ android:layout_height="@dimen/qs_aa_media_rec_icon_size"
+ app:layout_constraintEnd_toEndOf="@+id/media_cover2"
+ app:layout_constraintBottom_toBottomOf="@+id/media_cover2"
+ android:visibility="gone" />
+
+ <Constraint
+ android:id="@+id/media_cover3"
+ android:layout_width="@dimen/qs_aa_media_rec_album_size"
+ android:layout_height="@dimen/qs_aa_media_rec_album_size"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toEndOf="@id/media_cover2"
+ app:layout_constraintEnd_toStartOf="@id/media_cover4"
+ app:layout_constraintHorizontal_weight="1"
+ android:visibility="gone"/>
+
+ <Constraint
+ android:id="@+id/media_logo3"
+ android:layout_width="@dimen/qs_aa_media_rec_icon_size"
+ android:layout_height="@dimen/qs_aa_media_rec_icon_size"
+ app:layout_constraintEnd_toEndOf="@+id/media_cover3"
+ app:layout_constraintBottom_toBottomOf="@+id/media_cover3"
+ android:visibility="gone" />
+
+ <Constraint
+ android:id="@+id/media_cover4"
+ android:layout_width="@dimen/qs_aa_media_rec_album_size"
+ android:layout_height="@dimen/qs_aa_media_rec_album_size"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toEndOf="@id/media_cover3"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHorizontal_weight="1"
+ android:visibility="gone"/>
+
+ <Constraint
+ android:id="@+id/media_logo4"
+ android:layout_width="@dimen/qs_aa_media_rec_icon_size"
+ android:layout_height="@dimen/qs_aa_media_rec_icon_size"
+ app:layout_constraintEnd_toEndOf="@+id/media_cover4"
+ app:layout_constraintBottom_toBottomOf="@+id/media_cover4"
+ android:visibility="gone" />
+
+</ConstraintSet>
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
index 33681c8d03e5..2ecd40578d68 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
@@ -204,7 +204,7 @@ class MediaCarouselController @Inject constructor(
override fun onSmartspaceMediaDataLoaded(key: String, data: SmartspaceTarget) {
Log.d(TAG, "My Smartspace media update is here")
- addOrUpdateSmartspaceMediaRecommendations(key, data)
+ addSmartspaceMediaRecommendations(key, data)
}
override fun onMediaDataRemoved(key: String) {
@@ -213,6 +213,7 @@ class MediaCarouselController @Inject constructor(
override fun onSmartspaceMediaDataRemoved(key: String) {
Log.d(TAG, "My Smartspace media removal request is received")
+ removePlayer(key)
}
})
mediaFrame.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
@@ -256,8 +257,10 @@ class MediaCarouselController @Inject constructor(
private fun reorderAllPlayers() {
mediaContent.removeAllViews()
for (mediaPlayer in MediaPlayerData.players()) {
- mediaPlayer.view?.let {
+ mediaPlayer.playerViewHolder?.let {
mediaContent.addView(it.player)
+ } ?: mediaPlayer.recommendationViewHolder?.let {
+ mediaContent.addView(it.recommendations)
}
}
mediaCarouselScrollHandler.onPlayersChanged()
@@ -272,18 +275,19 @@ class MediaCarouselController @Inject constructor(
val existingPlayer = MediaPlayerData.getMediaPlayer(key, oldKey)
if (existingPlayer == null) {
var newPlayer = mediaControlPanelFactory.get()
- newPlayer.attach(PlayerViewHolder.create(LayoutInflater.from(context), mediaContent))
+ newPlayer.attachPlayer(
+ PlayerViewHolder.create(LayoutInflater.from(context), mediaContent))
newPlayer.mediaViewController.sizeChangedListener = this::updateCarouselDimensions
val lp = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT)
- newPlayer.view?.player?.setLayoutParams(lp)
- newPlayer.bind(dataCopy, key)
+ newPlayer.playerViewHolder?.player?.setLayoutParams(lp)
+ newPlayer.bindPlayer(dataCopy, key)
newPlayer.setListening(currentlyExpanded)
MediaPlayerData.addMediaPlayer(key, dataCopy, newPlayer)
updatePlayerToState(newPlayer, noAnimation = true)
reorderAllPlayers()
} else {
- existingPlayer.bind(dataCopy, key)
+ existingPlayer.bindPlayer(dataCopy, key)
MediaPlayerData.addMediaPlayer(key, dataCopy, existingPlayer)
if (visualStabilityManager.isReorderingAllowed) {
reorderAllPlayers()
@@ -301,15 +305,43 @@ class MediaCarouselController @Inject constructor(
}
}
- private fun addOrUpdateSmartspaceMediaRecommendations(key: String, data: SmartspaceTarget) {
- // TODO(b/182813345): Add Smartspace media recommendation view.
+ private fun addSmartspaceMediaRecommendations(key: String, data: SmartspaceTarget) {
+ Log.d(TAG, "Updating smartspace target in carousel")
+ if (MediaPlayerData.getMediaPlayer(key, null) != null) {
+ Log.w(TAG, "Skip adding smartspace target in carousel")
+ return
+ }
+
+ var newRecs = mediaControlPanelFactory.get()
+ newRecs.attachRecommendation(
+ RecommendationViewHolder.create(LayoutInflater.from(context), mediaContent))
+ newRecs.mediaViewController.sizeChangedListener = this::updateCarouselDimensions
+ val lp = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT)
+ newRecs.recommendationViewHolder?.recommendations?.setLayoutParams(lp)
+ newRecs.bindRecommendation(data, bgColor, { v -> removePlayer(key) })
+ MediaPlayerData.addMediaPlayer(key, newRecs)
+ updatePlayerToState(newRecs, noAnimation = true)
+ reorderAllPlayers()
+ updatePageIndicator()
+ mediaCarousel.requiresRemeasuring = true
+ // Check postcondition: mediaContent should have the same number of children as there are
+ // elements in mediaPlayers.
+ if (MediaPlayerData.players().size != mediaContent.childCount) {
+ Log.wtf(TAG, "Size of players list and number of views in carousel are out of sync")
+ }
}
- private fun removePlayer(key: String, dismissMediaData: Boolean = true) {
+ private fun removePlayer(
+ key: String,
+ dismissMediaData: Boolean = true,
+ dismissRecommendation: Boolean = true
+ ) {
val removed = MediaPlayerData.removeMediaPlayer(key)
removed?.apply {
mediaCarouselScrollHandler.onPrePlayerRemoved(removed)
- mediaContent.removeView(removed.view?.player)
+ mediaContent.removeView(removed.playerViewHolder?.player)
+ mediaContent.removeView(removed.recommendationViewHolder?.recommendations)
removed.onDestroy()
mediaCarouselScrollHandler.onPlayersChanged()
updatePageIndicator()
@@ -318,6 +350,10 @@ class MediaCarouselController @Inject constructor(
// Inform the media manager of a potentially late dismissal
mediaManager.dismissMediaData(key, 0L)
}
+ if (dismissRecommendation) {
+ // Inform the media manager of a potentially late dismissal
+ mediaManager.dismissSmartspaceRecommendation()
+ }
}
}
@@ -539,23 +575,37 @@ class MediaCarouselController @Inject constructor(
@VisibleForTesting
internal object MediaPlayerData {
+ private val EMPTY = MediaData(-1, false, 0, null, null, null, null, null,
+ emptyList(), emptyList(), "INVALID", null, null, null, true, null)
+
private data class MediaSortKey(
+ // Is Smartspace media recommendation. When the Smartspace media is present, it should
+ // always be the first card in carousel.
+ val isSsMediaRec: Boolean,
val data: MediaData,
val updateTime: Long = 0
)
private val comparator =
- compareByDescending<MediaSortKey> { it.data.isPlaying }
- .thenByDescending { it.data.isLocalSession }
- .thenByDescending { !it.data.resumption }
- .thenByDescending { it.updateTime }
+ compareByDescending<MediaSortKey> { it.isSsMediaRec }
+ .thenByDescending { it.data.isPlaying }
+ .thenByDescending { it.data.isLocalSession }
+ .thenByDescending { !it.data.resumption }
+ .thenByDescending { it.updateTime }
private val mediaPlayers = TreeMap<MediaSortKey, MediaControlPanel>(comparator)
private val mediaData: MutableMap<String, MediaSortKey> = mutableMapOf()
fun addMediaPlayer(key: String, data: MediaData, player: MediaControlPanel) {
removeMediaPlayer(key)
- val sortKey = MediaSortKey(data, System.currentTimeMillis())
+ val sortKey = MediaSortKey(isSsMediaRec = false, data, System.currentTimeMillis())
+ mediaData.put(key, sortKey)
+ mediaPlayers.put(sortKey, player)
+ }
+
+ fun addMediaPlayer(key: String, player: MediaControlPanel) {
+ removeMediaPlayer(key)
+ val sortKey = MediaSortKey(isSsMediaRec = true, EMPTY, System.currentTimeMillis())
mediaData.put(key, sortKey)
mediaPlayers.put(sortKey, player)
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt
index bb6fbfab4c90..f0b78dde0ebd 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt
@@ -510,7 +510,7 @@ class MediaCarouselScrollHandler(
* where it was and update our scroll position.
*/
fun onPrePlayerRemoved(removed: MediaControlPanel) {
- val removedIndex = mediaContent.indexOfChild(removed.view?.player)
+ val removedIndex = mediaContent.indexOfChild(removed.playerViewHolder?.player)
// If the removed index is less than the activeMediaIndex, then we need to decrement it.
// RTL has no effect on this, because indices are always relative (start-to-end).
// Update the index 'manually' since we won't always get a call to onMediaScrollingChanged
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
index 4fd8fe7b921b..60c08118af35 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java
@@ -16,12 +16,14 @@
package com.android.systemui.media;
-import static android.app.Notification.safeCharSequence;
import static android.provider.Settings.ACTION_MEDIA_CONTROLS_SETTINGS;
import android.app.PendingIntent;
+import android.app.smartspace.SmartspaceAction;
+import android.app.smartspace.SmartspaceTarget;
import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.graphics.Outline;
import android.graphics.Rect;
@@ -30,6 +32,7 @@ import android.graphics.drawable.Icon;
import android.media.session.MediaController;
import android.media.session.MediaSession;
import android.media.session.PlaybackState;
+import android.os.Bundle;
import android.os.SystemProperties;
import android.util.Log;
import android.view.View;
@@ -67,6 +70,9 @@ import dagger.Lazy;
public class MediaControlPanel {
private static final String TAG = "MediaControlPanel";
private static final float DISABLED_ALPHA = 0.38f;
+ private static final String EXTRAS_MEDIA_SOURCE_LOGO = "media_source_logo";
+ private static final String EXTRAS_MEDIA_SOURCE_PACKAGE_NAME = "package_name";
+ private static final int MEDIA_RECOMMENDATION_MAX_NUM = 4;
private final boolean mShowAppName = SystemProperties.getBoolean(
"persist.sysui.qs_media_show_app_name", false);
@@ -90,7 +96,8 @@ public class MediaControlPanel {
private final ActivityStarter mActivityStarter;
private Context mContext;
- private PlayerViewHolder mViewHolder;
+ private PlayerViewHolder mPlayerViewHolder;
+ private RecommendationViewHolder mRecommendationViewHolder;
private String mKey;
private MediaViewController mMediaViewController;
private MediaSession.Token mToken;
@@ -149,13 +156,22 @@ public class MediaControlPanel {
}
/**
- * Get the view holder used to display media controls
+ * Get the player view holder used to display media controls.
*
- * @return the view holder
+ * @return the player view holder
*/
@Nullable
- public PlayerViewHolder getView() {
- return mViewHolder;
+ public PlayerViewHolder getPlayerViewHolder() {
+ return mPlayerViewHolder;
+ }
+
+ /**
+ * Get the recommendation view holder used to display Smartspace media recs.
+ * @return the recommendation view holder
+ */
+ @Nullable
+ public RecommendationViewHolder getRecommendationViewHolder() {
+ return mRecommendationViewHolder;
}
/**
@@ -189,9 +205,9 @@ public class MediaControlPanel {
return mContext;
}
- /** Attaches the player to the view holder. */
- public void attach(PlayerViewHolder vh) {
- mViewHolder = vh;
+ /** Attaches the player to the player view holder. */
+ public void attachPlayer(PlayerViewHolder vh) {
+ mPlayerViewHolder = vh;
TransitionLayout player = vh.getPlayer();
ImageView albumView = vh.getAlbumView();
@@ -201,9 +217,9 @@ public class MediaControlPanel {
mSeekBarObserver = new SeekBarObserver(vh);
mSeekBarViewModel.getProgress().observeForever(mSeekBarObserver);
mSeekBarViewModel.attachTouchHandlers(vh.getSeekBar());
- mMediaViewController.attach(player);
+ mMediaViewController.attach(player, MediaViewController.TYPE.PLAYER);
- mViewHolder.getPlayer().setOnLongClickListener(v -> {
+ mPlayerViewHolder.getPlayer().setOnLongClickListener(v -> {
if (!mMediaViewController.isGutsVisible()) {
mMediaViewController.openGuts();
return true;
@@ -211,19 +227,25 @@ public class MediaControlPanel {
return false;
}
});
- mViewHolder.getCancel().setOnClickListener(v -> {
+ mPlayerViewHolder.getCancel().setOnClickListener(v -> {
closeGuts();
});
- mViewHolder.getSettings().setOnClickListener(v -> {
+ mPlayerViewHolder.getSettings().setOnClickListener(v -> {
mActivityStarter.startActivity(SETTINGS_INTENT, true /* dismissShade */);
});
}
- /**
- * Bind this view based on the data given
- */
- public void bind(@NonNull MediaData data, String key) {
- if (mViewHolder == null) {
+ /** Attaches the recommendations to the recommendation view holder. */
+ public void attachRecommendation(RecommendationViewHolder vh) {
+ mRecommendationViewHolder = vh;
+ TransitionLayout recommendations = vh.getRecommendations();
+
+ mMediaViewController.attach(recommendations, MediaViewController.TYPE.RECOMMENDATION);
+ }
+
+ /** Bind this player view based on the data given. */
+ public void bindPlayer(@NonNull MediaData data, String key) {
+ if (mPlayerViewHolder == null) {
return;
}
mKey = key;
@@ -242,20 +264,20 @@ public class MediaControlPanel {
ConstraintSet expandedSet = mMediaViewController.getExpandedLayout();
ConstraintSet collapsedSet = mMediaViewController.getCollapsedLayout();
- mViewHolder.getPlayer().setBackgroundTintList(
+ mPlayerViewHolder.getPlayer().setBackgroundTintList(
ColorStateList.valueOf(mBackgroundColor));
// Click action
PendingIntent clickIntent = data.getClickIntent();
if (clickIntent != null) {
- mViewHolder.getPlayer().setOnClickListener(v -> {
+ mPlayerViewHolder.getPlayer().setOnClickListener(v -> {
if (mMediaViewController.isGutsVisible()) return;
mActivityStarter.postStartActivityDismissingKeyguard(clickIntent,
- buildLaunchAnimatorController(mViewHolder.getPlayer()));
+ buildLaunchAnimatorController(mPlayerViewHolder.getPlayer()));
});
}
- ImageView albumView = mViewHolder.getAlbumView();
+ ImageView albumView = mPlayerViewHolder.getAlbumView();
boolean hasArtwork = data.getArtwork() != null;
if (hasArtwork) {
Drawable artwork = scaleDrawable(data.getArtwork());
@@ -265,7 +287,7 @@ public class MediaControlPanel {
setVisibleAndAlpha(expandedSet, R.id.album_art, hasArtwork);
// App icon
- ImageView appIcon = mViewHolder.getAppIcon();
+ ImageView appIcon = mPlayerViewHolder.getAppIcon();
if (data.getAppIcon() != null) {
appIcon.setImageIcon(data.getAppIcon());
} else {
@@ -273,52 +295,53 @@ public class MediaControlPanel {
}
// Song name
- TextView titleText = mViewHolder.getTitleText();
- titleText.setText(safeCharSequence(data.getSong()));
+
+ TextView titleText = mPlayerViewHolder.getTitleText();
+ titleText.setText(data.getSong());
// App title
- TextView appName = mViewHolder.getAppName();
+ TextView appName = mPlayerViewHolder.getAppName();
appName.setText(data.getApp());
appName.setVisibility(mShowAppName ? View.VISIBLE : View.GONE);
setVisibleAndAlpha(collapsedSet, R.id.app_name, mShowAppName);
setVisibleAndAlpha(expandedSet, R.id.app_name, mShowAppName);
// Artist name
- TextView artistText = mViewHolder.getArtistText();
- artistText.setText(safeCharSequence(data.getArtist()));
+ TextView artistText = mPlayerViewHolder.getArtistText();
+ artistText.setText(data.getArtist());
// Transfer chip
- mViewHolder.getSeamless().setVisibility(View.VISIBLE);
+ mPlayerViewHolder.getSeamless().setVisibility(View.VISIBLE);
setVisibleAndAlpha(collapsedSet, R.id.media_seamless, true /*visible */);
setVisibleAndAlpha(expandedSet, R.id.media_seamless, true /*visible */);
- mViewHolder.getSeamless().setOnClickListener(v -> {
+ mPlayerViewHolder.getSeamless().setOnClickListener(v -> {
mMediaOutputDialogFactory.create(data.getPackageName(), true);
});
- TextView mDeviceName = mViewHolder.getSeamlessText();
+ TextView mDeviceName = mPlayerViewHolder.getSeamlessText();
mDeviceName.setVisibility(mShowDeviceName ? View.VISIBLE : View.GONE);
setVisibleAndAlpha(collapsedSet, R.id.media_seamless_text, mShowDeviceName);
setVisibleAndAlpha(expandedSet, R.id.media_seamless_text, mShowDeviceName);
- ImageView iconView = mViewHolder.getSeamlessIcon();
- TextView deviceName = mViewHolder.getSeamlessText();
+ ImageView iconView = mPlayerViewHolder.getSeamlessIcon();
+ TextView deviceName = mPlayerViewHolder.getSeamlessText();
final MediaDeviceData device = data.getDevice();
- final int seamlessId = mViewHolder.getSeamless().getId();
- final int seamlessFallbackId = mViewHolder.getSeamlessFallback().getId();
+ final int seamlessId = mPlayerViewHolder.getSeamless().getId();
+ final int seamlessFallbackId = mPlayerViewHolder.getSeamlessFallback().getId();
final boolean showFallback = device != null && !device.getEnabled();
final int seamlessFallbackVisibility = showFallback ? View.VISIBLE : View.GONE;
- mViewHolder.getSeamlessFallback().setVisibility(seamlessFallbackVisibility);
+ mPlayerViewHolder.getSeamlessFallback().setVisibility(seamlessFallbackVisibility);
expandedSet.setVisibility(seamlessFallbackId, seamlessFallbackVisibility);
collapsedSet.setVisibility(seamlessFallbackId, seamlessFallbackVisibility);
final int seamlessVisibility = showFallback ? View.GONE : View.VISIBLE;
- mViewHolder.getSeamless().setVisibility(seamlessVisibility);
+ mPlayerViewHolder.getSeamless().setVisibility(seamlessVisibility);
expandedSet.setVisibility(seamlessId, seamlessVisibility);
collapsedSet.setVisibility(seamlessId, seamlessVisibility);
final float seamlessAlpha = data.getResumption() ? DISABLED_ALPHA : 1.0f;
expandedSet.setAlpha(seamlessId, seamlessAlpha);
collapsedSet.setAlpha(seamlessId, seamlessAlpha);
// Disable clicking on output switcher for resumption controls.
- mViewHolder.getSeamless().setEnabled(!data.getResumption());
+ mPlayerViewHolder.getSeamless().setEnabled(!data.getResumption());
if (showFallback) {
iconView.setImageDrawable(null);
deviceName.setText(null);
@@ -346,7 +369,7 @@ public class MediaControlPanel {
List<MediaAction> actionIcons = data.getActions();
for (; i < actionIcons.size() && i < ACTION_IDS.length; i++) {
int actionId = ACTION_IDS[i];
- final ImageButton button = mViewHolder.getAction(actionId);
+ final ImageButton button = mPlayerViewHolder.getAction(actionId);
MediaAction mediaAction = actionIcons.get(i);
button.setImageIcon(mediaAction.getIcon());
button.setContentDescription(mediaAction.getContentDescription());
@@ -377,14 +400,14 @@ public class MediaControlPanel {
// Guts label
boolean isDismissible = data.isClearable();
- mViewHolder.getSettingsText().setText(isDismissible
+ mPlayerViewHolder.getSettingsText().setText(isDismissible
? R.string.controls_media_close_session
: R.string.controls_media_active_session);
// Dismiss
- mViewHolder.getDismissLabel().setAlpha(isDismissible ? 1 : DISABLED_ALPHA);
- mViewHolder.getDismiss().setEnabled(isDismissible);
- mViewHolder.getDismiss().setOnClickListener(v -> {
+ mPlayerViewHolder.getDismissLabel().setAlpha(isDismissible ? 1 : DISABLED_ALPHA);
+ mPlayerViewHolder.getDismiss().setEnabled(isDismissible);
+ mPlayerViewHolder.getDismiss().setOnClickListener(v -> {
if (mKey != null) {
closeGuts();
mKeyguardDismissUtil.executeWhenUnlocked(() -> {
@@ -436,6 +459,78 @@ public class MediaControlPanel {
};
}
+ /** Bind this recommendation view based on the data given. */
+ public void bindRecommendation(
+ @NonNull SmartspaceTarget target,
+ @NonNull int backgroundColor,
+ @Nullable View.OnClickListener callback) {
+ if (mRecommendationViewHolder == null) {
+ return;
+ }
+
+ mRecommendationViewHolder.getRecommendations()
+ .setBackgroundTintList(ColorStateList.valueOf(backgroundColor));
+ mBackgroundColor = backgroundColor;
+
+ List<SmartspaceAction> mediaRecommendationList = target.getIconGrid();
+ if (mediaRecommendationList == null || mediaRecommendationList.isEmpty()) {
+ Log.w(TAG, "Empty media recommendations");
+ return;
+ }
+
+ List<ImageView> mediaCoverItems = mRecommendationViewHolder.getMediaCoverItems();
+ List<ImageView> mediaLogoItems = mRecommendationViewHolder.getMediaLogoItems();
+ List<Integer> mediaCoverItemsResIds = mRecommendationViewHolder.getMediaCoverItemsResIds();
+ List<Integer> mediaLogoItemsResIds = mRecommendationViewHolder.getMediaLogoItemsResIds();
+ ConstraintSet expandedSet = mMediaViewController.getExpandedLayout();
+ ConstraintSet collapsedSet = mMediaViewController.getCollapsedLayout();
+ int mediaRecommendationNum = Math.min(mediaRecommendationList.size(),
+ MEDIA_RECOMMENDATION_MAX_NUM);
+ for (int i = 0; i < mediaRecommendationNum; i++) {
+ SmartspaceAction recommendation = mediaRecommendationList.get(i);
+ if (recommendation.getIcon() == null) {
+ Log.w(TAG, "No media cover is provided. Skipping this item...");
+ continue;
+ }
+
+ // Get media source app's logo.
+ Bundle extras = recommendation.getExtras();
+ Drawable icon = null;
+ if (extras != null && extras.getString(EXTRAS_MEDIA_SOURCE_PACKAGE_NAME) != null) {
+ // Get the logo from app's package name when applicable.
+ String packageName = extras.getString(EXTRAS_MEDIA_SOURCE_PACKAGE_NAME);
+ try {
+ icon = mContext.getPackageManager().getApplicationIcon(
+ packageName);
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, "No media source icon can be fetched via package name", e);
+ }
+ } else {
+ Log.w(TAG, "No media source icon is provided. Skipping this item...");
+ continue;
+ }
+
+ // Set up media source app's logo.
+ ImageView mediaSourceLogoImageView = mediaLogoItems.get(i);
+ mediaSourceLogoImageView.setImageDrawable(icon);
+
+ // Set up media item cover.
+ ImageView mediaCoverImageView = mediaCoverItems.get(i);
+ mediaCoverImageView.setImageIcon(recommendation.getIcon());
+
+ // Set up the click listener if applicable.
+ setSmartspaceOnClickListener(mediaCoverImageView, recommendation, callback);
+
+ setVisibleAndAlpha(expandedSet, mediaCoverItemsResIds.get(i), true);
+ setVisibleAndAlpha(expandedSet, mediaLogoItemsResIds.get(i), true);
+ setVisibleAndAlpha(collapsedSet, mediaCoverItemsResIds.get(i), true);
+ setVisibleAndAlpha(collapsedSet, mediaLogoItemsResIds.get(i), true);
+ }
+
+ mController = null;
+ mMediaViewController.refreshState();
+ }
+
/**
* Close the guts for this player.
*
@@ -515,4 +610,24 @@ public class MediaControlPanel {
set.setVisibility(actionId, visible ? ConstraintSet.VISIBLE : ConstraintSet.GONE);
set.setAlpha(actionId, visible ? 1.0f : 0.0f);
}
+
+ private void setSmartspaceOnClickListener(
+ @NonNull View view,
+ @NonNull SmartspaceAction action,
+ @Nullable View.OnClickListener callback) {
+ if (view == null || action == null || action.getIntent() == null) {
+ Log.e(TAG, "No tap action can be set up");
+ return;
+ }
+
+ view.setOnClickListener(v -> {
+ mActivityStarter.postStartActivityDismissingKeyguard(
+ action.getIntent(),
+ 0 /* delay */,
+ buildLaunchAnimatorController(mRecommendationViewHolder.getRecommendations()));
+ if (callback != null) {
+ callback.onClick(v);
+ }
+ });
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt
index aab27473d3e8..a274eabed198 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt
@@ -51,6 +51,7 @@ class MediaDataFilter @Inject constructor(
private val allEntries: LinkedHashMap<String, MediaData> = LinkedHashMap()
// The filtered userEntries, which will be a subset of all userEntries in MediaDataManager
private val userEntries: LinkedHashMap<String, MediaData> = LinkedHashMap()
+ private var hasSmartspace: Boolean = false
init {
userTracker = object : CurrentUserTracker(broadcastDispatcher) {
@@ -84,6 +85,7 @@ class MediaDataFilter @Inject constructor(
}
override fun onSmartspaceMediaDataLoaded(key: String, data: SmartspaceTarget) {
+ hasSmartspace = true
listeners.forEach { it.onSmartspaceMediaDataLoaded(key, data) }
}
@@ -98,6 +100,7 @@ class MediaDataFilter @Inject constructor(
}
override fun onSmartspaceMediaDataRemoved(key: String) {
+ hasSmartspace = false
listeners.forEach { it.onSmartspaceMediaDataRemoved(key) }
}
@@ -136,17 +139,20 @@ class MediaDataFilter @Inject constructor(
mediaKeys.forEach {
mediaDataManager.setTimedOut(it, timedOut = true)
}
+ if (hasSmartspace) {
+ mediaDataManager.dismissSmartspaceRecommendation()
+ }
}
/**
* Are there any media notifications active?
*/
- fun hasActiveMedia() = userEntries.any { it.value.active }
+ fun hasActiveMedia() = userEntries.any { it.value.active } || hasSmartspace
/**
* Are there any media entries we should display?
*/
- fun hasAnyMedia() = userEntries.isNotEmpty()
+ fun hasAnyMedia() = userEntries.isNotEmpty() || hasSmartspace
/**
* Add a listener for filtered [MediaData] changes
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
index dfd588d0406e..574ce0dffee0 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
@@ -424,6 +424,20 @@ class MediaDataManager(
foregroundExecutor.executeDelayed({ removeEntry(key) }, delay)
}
+ /**
+ * Called whenever the recommendation has been expired, or swiped from QQS.
+ * This will make the recommendation view to not be shown anymore during this headphone
+ * connection session.
+ */
+ fun dismissSmartspaceRecommendation() {
+ Log.d(TAG, "Dismissing Smartspace media target")
+ // Do not set smartspaceMediaTarget to null. So the instance is preserved during the entire
+ // headphone connection, and will ONLY be set to null when headphones are disconnected.
+ smartspaceMediaTarget?.let {
+ notifySmartspaceMediaDataRemoved(it.smartspaceTargetId)
+ }
+ }
+
private fun loadMediaDataInBgForResumption(
userId: Int,
desc: MediaDescription,
@@ -669,6 +683,7 @@ class MediaDataManager(
0 -> {
Log.d(TAG, "Empty Smartspace media target")
smartspaceMediaTarget?.let {
+ Log.d(TAG, "Setting Smartspace media target to null")
notifySmartspaceMediaDataRemoved(it.smartspaceTargetId)
}
smartspaceMediaTarget = null
diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt
index 92eeed46388d..7cfe4c4073d2 100644
--- a/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt
@@ -32,11 +32,16 @@ import javax.inject.Inject
* with the view instance and keeping the media view states up to date.
*/
class MediaViewController @Inject constructor(
- context: Context,
+ private val context: Context,
private val configurationController: ConfigurationController,
private val mediaHostStatesManager: MediaHostStatesManager
) {
+ /** Indicating the media view controller is for a player or recommendation. */
+ enum class TYPE {
+ PLAYER, RECOMMENDATION
+ }
+
companion object {
@JvmField
val GUTS_ANIMATION_DURATION = 500L
@@ -53,6 +58,7 @@ class MediaViewController @Inject constructor(
private var animationDuration: Long = 0
private var animateNextStateChange: Boolean = false
private val measurement = MeasurementOutput(0, 0)
+ private var type: TYPE = TYPE.PLAYER
/**
* A map containing all viewStates for all locations of this mediaState
@@ -181,8 +187,6 @@ class MediaViewController @Inject constructor(
private set
init {
- collapsedLayout.load(context, R.xml.media_collapsed)
- expandedLayout.load(context, R.xml.media_expanded)
mediaHostStatesManager.addController(this)
layoutController.sizeChangedListener = { width: Int, height: Int ->
currentWidth = width
@@ -313,7 +317,11 @@ class MediaViewController @Inject constructor(
return result
}
- private fun getKey(state: MediaHostState, guts: Boolean, result: CacheKey): CacheKey {
+ private fun getKey(
+ state: MediaHostState,
+ guts: Boolean,
+ result: CacheKey
+ ): CacheKey {
result.apply {
heightMeasureSpec = state.measurementInput?.heightMeasureSpec ?: 0
widthMeasureSpec = state.measurementInput?.widthMeasureSpec ?: 0
@@ -327,7 +335,8 @@ class MediaViewController @Inject constructor(
* Attach a view to this controller. This may perform measurements if it's not available yet
* and should therefore be done carefully.
*/
- fun attach(transitionLayout: TransitionLayout) {
+ fun attach(transitionLayout: TransitionLayout, type: TYPE) {
+ updateMediaViewControllerType(type)
this.transitionLayout = transitionLayout
layoutController.attach(transitionLayout)
if (currentEndLocation == -1) {
@@ -426,7 +435,7 @@ class MediaViewController @Inject constructor(
viewState: TransitionViewState?,
location: Int,
outState: TransitionViewState
- ) : TransitionViewState? {
+ ): TransitionViewState? {
val result = viewState?.copy(outState) ?: return null
val overrideSize = mediaHostStatesManager.carouselSizes[location]
overrideSize?.let {
@@ -438,6 +447,18 @@ class MediaViewController @Inject constructor(
return result
}
+ private fun updateMediaViewControllerType(type: TYPE) {
+ this.type = type
+ if (type == TYPE.PLAYER) {
+ collapsedLayout.load(context, R.xml.media_collapsed)
+ expandedLayout.load(context, R.xml.media_expanded)
+ } else {
+ collapsedLayout.load(context, R.xml.media_recommendation)
+ expandedLayout.load(context, R.xml.media_recommendation)
+ }
+ refreshState()
+ }
+
/**
* Retrieves the [TransitionViewState] and [MediaHostState] of a [@MediaLocation].
* In the event of [location] not being visible, [locationWhenHidden] will be used instead.
diff --git a/packages/SystemUI/src/com/android/systemui/media/RecommendationViewHolder.kt b/packages/SystemUI/src/com/android/systemui/media/RecommendationViewHolder.kt
new file mode 100644
index 000000000000..a375771f1104
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/media/RecommendationViewHolder.kt
@@ -0,0 +1,61 @@
+package com.android.systemui.media
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import androidx.annotation.IntegerRes
+import com.android.systemui.R
+import com.android.systemui.util.animation.TransitionLayout
+
+/** ViewHolder for a Smartspace media recommendation. */
+class RecommendationViewHolder private constructor(itemView: View) {
+
+ val recommendations = itemView as TransitionLayout
+ val mediaCoverItems = listOf<ImageView>(
+ itemView.requireViewById(R.id.media_cover1),
+ itemView.requireViewById(R.id.media_cover2),
+ itemView.requireViewById(R.id.media_cover3),
+ itemView.requireViewById(R.id.media_cover4))
+ val mediaLogoItems = listOf<ImageView>(
+ itemView.requireViewById(R.id.media_logo1),
+ itemView.requireViewById(R.id.media_logo2),
+ itemView.requireViewById(R.id.media_logo3),
+ itemView.requireViewById(R.id.media_logo4))
+ val mediaCoverItemsResIds = listOf<@IntegerRes Int>(
+ R.id.media_cover1,
+ R.id.media_cover2,
+ R.id.media_cover3,
+ R.id.media_cover4)
+ val mediaLogoItemsResIds = listOf<@IntegerRes Int>(
+ R.id.media_logo1,
+ R.id.media_logo2,
+ R.id.media_logo3,
+ R.id.media_logo4)
+
+ init {
+ (recommendations.background as IlluminationDrawable).let { background ->
+ mediaCoverItems.forEach { background.registerLightSource(it) }
+ mediaLogoItems.forEach { background.registerLightSource(it) }
+ }
+ }
+
+ companion object {
+ /**
+ * Creates a PlayerViewHolder.
+ *
+ * @param inflater LayoutInflater to use to inflate the layout.
+ * @param parent Parent of inflated view.
+ */
+ @JvmStatic fun create(inflater: LayoutInflater, parent: ViewGroup):
+ RecommendationViewHolder {
+ val itemView =
+ inflater.inflate(R.layout.smartspace_card_media, parent, /* attachToRoot= */ false)
+ // Because this media view (a TransitionLayout) is used to measure and layout the views
+ // in various states before being attached to its parent, we can't depend on the default
+ // LAYOUT_DIRECTION_INHERIT to correctly resolve the ltr direction.
+ itemView.layoutDirection = View.LAYOUT_DIRECTION_LOCALE
+ return RecommendationViewHolder(itemView)
+ }
+ }
+} \ No newline at end of file
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
index af677c9d9f64..73b0a6b9a11a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
@@ -210,16 +210,16 @@ public class MediaControlPanelTest : SysuiTestCase() {
fun bindWhenUnattached() {
val state = MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
emptyList(), PACKAGE, null, null, device, true, null)
- player.bind(state, PACKAGE)
+ player.bindPlayer(state, PACKAGE)
assertThat(player.isPlaying()).isFalse()
}
@Test
fun bindText() {
- player.attach(holder)
+ player.attachPlayer(holder)
val state = MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
emptyList(), PACKAGE, session.getSessionToken(), null, device, true, null)
- player.bind(state, PACKAGE)
+ player.bindPlayer(state, PACKAGE)
assertThat(appName.getText()).isEqualTo(APP)
assertThat(titleText.getText()).isEqualTo(TITLE)
assertThat(artistText.getText()).isEqualTo(ARTIST)
@@ -227,10 +227,10 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Test
fun bindBackgroundColor() {
- player.attach(holder)
+ player.attachPlayer(holder)
val state = MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
emptyList(), PACKAGE, session.getSessionToken(), null, device, true, null)
- player.bind(state, PACKAGE)
+ player.bindPlayer(state, PACKAGE)
val list = ArgumentCaptor.forClass(ColorStateList::class.java)
verify(view).setBackgroundTintList(list.capture())
assertThat(list.value).isEqualTo(ColorStateList.valueOf(BG_COLOR))
@@ -238,10 +238,10 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Test
fun bindDevice() {
- player.attach(holder)
+ player.attachPlayer(holder)
val state = MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
emptyList(), PACKAGE, session.getSessionToken(), null, device, true, null)
- player.bind(state, PACKAGE)
+ player.bindPlayer(state, PACKAGE)
assertThat(seamlessText.getText()).isEqualTo(DEVICE_NAME)
assertThat(seamless.isEnabled()).isTrue()
}
@@ -250,10 +250,10 @@ public class MediaControlPanelTest : SysuiTestCase() {
fun bindDisabledDevice() {
seamless.id = 1
seamlessFallback.id = 2
- player.attach(holder)
+ player.attachPlayer(holder)
val state = MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
emptyList(), PACKAGE, session.getSessionToken(), null, disabledDevice, true, null)
- player.bind(state, PACKAGE)
+ player.bindPlayer(state, PACKAGE)
verify(expandedSet).setVisibility(seamless.id, View.GONE)
verify(expandedSet).setVisibility(seamlessFallback.id, View.VISIBLE)
verify(collapsedSet).setVisibility(seamless.id, View.GONE)
@@ -262,10 +262,10 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Test
fun bindNullDevice() {
- player.attach(holder)
+ player.attachPlayer(holder)
val state = MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
emptyList(), PACKAGE, session.getSessionToken(), null, null, true, null)
- player.bind(state, PACKAGE)
+ player.bindPlayer(state, PACKAGE)
assertThat(seamless.isEnabled()).isTrue()
assertThat(seamlessText.getText()).isEqualTo(context.getResources().getString(
com.android.internal.R.string.ext_media_seamless_action))
@@ -273,18 +273,18 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Test
fun bindDeviceResumptionPlayer() {
- player.attach(holder)
+ player.attachPlayer(holder)
val state = MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
emptyList(), PACKAGE, session.getSessionToken(), null, device, true, null,
resumption = true)
- player.bind(state, PACKAGE)
+ player.bindPlayer(state, PACKAGE)
assertThat(seamlessText.getText()).isEqualTo(DEVICE_NAME)
assertThat(seamless.isEnabled()).isFalse()
}
@Test
fun longClick_gutsClosed() {
- player.attach(holder)
+ player.attachPlayer(holder)
whenever(mediaViewController.isGutsVisible).thenReturn(false)
val captor = ArgumentCaptor.forClass(View.OnLongClickListener::class.java)
@@ -296,7 +296,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Test
fun longClick_gutsOpen() {
- player.attach(holder)
+ player.attachPlayer(holder)
whenever(mediaViewController.isGutsVisible).thenReturn(true)
val captor = ArgumentCaptor.forClass(View.OnLongClickListener::class.java)
@@ -308,7 +308,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Test
fun cancelButtonClick_animation() {
- player.attach(holder)
+ player.attachPlayer(holder)
cancel.callOnClick()
@@ -317,7 +317,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Test
fun settingsButtonClick() {
- player.attach(holder)
+ player.attachPlayer(holder)
settings.callOnClick()
@@ -330,11 +330,11 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Test
fun dismissButtonClick() {
val mediaKey = "key for dismissal"
- player.attach(holder)
+ player.attachPlayer(holder)
val state = MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
emptyList(), PACKAGE, session.getSessionToken(), null, null, true, null,
notificationKey = KEY)
- player.bind(state, mediaKey)
+ player.bindPlayer(state, mediaKey)
assertThat(dismiss.isEnabled).isEqualTo(true)
dismiss.callOnClick()
@@ -348,11 +348,11 @@ public class MediaControlPanelTest : SysuiTestCase() {
@Test
fun dismissButtonDisabled() {
val mediaKey = "key for dismissal"
- player.attach(holder)
+ player.attachPlayer(holder)
val state = MediaData(USER_ID, true, BG_COLOR, APP, null, ARTIST, TITLE, null, emptyList(),
emptyList(), PACKAGE, session.getSessionToken(), null, null, true, null,
isClearable = false, notificationKey = KEY)
- player.bind(state, mediaKey)
+ player.bindPlayer(state, mediaKey)
assertThat(dismiss.isEnabled).isEqualTo(false)
}