[Media Recs] Don't show the recommendations if we have < 3
recommendations with albums. Bug: 230333302 Test: MediaControlPanelTest Test: manual: verified recommendations still appear Change-Id: I8c8ee82932e5cab8854e6ac15a5d06382c9fef9b
This commit is contained in:
@@ -18,6 +18,8 @@ package com.android.systemui.media;
|
||||
|
||||
import static android.provider.Settings.ACTION_MEDIA_CONTROLS_SETTINGS;
|
||||
|
||||
import static com.android.systemui.media.SmartspaceMediaDataKt.NUM_REQUIRED_RECOMMENDATIONS;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorInflater;
|
||||
import android.animation.AnimatorSet;
|
||||
@@ -102,7 +104,6 @@ public class MediaControlPanel {
|
||||
+ ".android.apps.gsa.staticplugins.opa.smartspace.ExportedSmartspaceTrampolineActivity";
|
||||
private static final String EXTRAS_SMARTSPACE_INTENT =
|
||||
"com.google.android.apps.gsa.smartspace.extra.SMARTSPACE_INTENT";
|
||||
private static final int MEDIA_RECOMMENDATION_MAX_NUM = 3;
|
||||
private static final String KEY_SMARTSPACE_ARTIST_NAME = "artist_name";
|
||||
private static final String KEY_SMARTSPACE_OPEN_IN_FOREGROUND = "KEY_OPEN_IN_FOREGROUND";
|
||||
private static final String KEY_SMARTSPACE_APP_NAME = "KEY_SMARTSPACE_APP_NAME";
|
||||
@@ -949,16 +950,14 @@ public class MediaControlPanel {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!data.isValid()) {
|
||||
Log.e(TAG, "Received an invalid recommendation list; returning");
|
||||
return;
|
||||
}
|
||||
|
||||
mSmartspaceId = SmallHash.hash(data.getTargetId());
|
||||
mPackageName = data.getPackageName();
|
||||
mInstanceId = data.getInstanceId();
|
||||
TransitionLayout recommendationCard = mRecommendationViewHolder.getRecommendations();
|
||||
|
||||
List<SmartspaceAction> mediaRecommendationList = data.getRecommendations();
|
||||
if (mediaRecommendationList == null || mediaRecommendationList.isEmpty()) {
|
||||
Log.w(TAG, "Empty media recommendations");
|
||||
return;
|
||||
}
|
||||
|
||||
// Set up recommendation card's header.
|
||||
ApplicationInfo applicationInfo;
|
||||
@@ -994,6 +993,7 @@ public class MediaControlPanel {
|
||||
}
|
||||
|
||||
// Set up media rec card's tap action if applicable.
|
||||
TransitionLayout recommendationCard = mRecommendationViewHolder.getRecommendations();
|
||||
setSmartspaceRecItemOnClickListener(recommendationCard, data.getCardAction(),
|
||||
/* interactedSubcardRank */ -1);
|
||||
// Set up media rec card's accessibility label.
|
||||
@@ -1002,29 +1002,20 @@ public class MediaControlPanel {
|
||||
|
||||
List<ImageView> mediaCoverItems = mRecommendationViewHolder.getMediaCoverItems();
|
||||
List<ViewGroup> mediaCoverContainers = mRecommendationViewHolder.getMediaCoverContainers();
|
||||
int mediaRecommendationNum = Math.min(mediaRecommendationList.size(),
|
||||
MEDIA_RECOMMENDATION_MAX_NUM);
|
||||
List<SmartspaceAction> recommendations = data.getValidRecommendations();
|
||||
|
||||
boolean hasTitle = false;
|
||||
boolean hasSubtitle = false;
|
||||
int uiComponentIndex = 0;
|
||||
for (int itemIndex = 0;
|
||||
itemIndex < mediaRecommendationNum && uiComponentIndex < mediaRecommendationNum;
|
||||
itemIndex++) {
|
||||
SmartspaceAction recommendation = mediaRecommendationList.get(itemIndex);
|
||||
if (recommendation.getIcon() == null) {
|
||||
Log.w(TAG, "No media cover is provided. Skipping this item...");
|
||||
continue;
|
||||
}
|
||||
for (int itemIndex = 0; itemIndex < NUM_REQUIRED_RECOMMENDATIONS; itemIndex++) {
|
||||
SmartspaceAction recommendation = recommendations.get(itemIndex);
|
||||
|
||||
// Set up media item cover.
|
||||
ImageView mediaCoverImageView = mediaCoverItems.get(uiComponentIndex);
|
||||
ImageView mediaCoverImageView = mediaCoverItems.get(itemIndex);
|
||||
mediaCoverImageView.setImageIcon(recommendation.getIcon());
|
||||
|
||||
// Set up the media item's click listener if applicable.
|
||||
ViewGroup mediaCoverContainer = mediaCoverContainers.get(uiComponentIndex);
|
||||
setSmartspaceRecItemOnClickListener(mediaCoverContainer, recommendation,
|
||||
uiComponentIndex);
|
||||
ViewGroup mediaCoverContainer = mediaCoverContainers.get(itemIndex);
|
||||
setSmartspaceRecItemOnClickListener(mediaCoverContainer, recommendation, itemIndex);
|
||||
// Bubble up the long-click event to the card.
|
||||
mediaCoverContainer.setOnLongClickListener(v -> {
|
||||
View parent = (View) v.getParent();
|
||||
@@ -1053,8 +1044,7 @@ public class MediaControlPanel {
|
||||
// Set up title
|
||||
CharSequence title = recommendation.getTitle();
|
||||
hasTitle |= !TextUtils.isEmpty(title);
|
||||
TextView titleView =
|
||||
mRecommendationViewHolder.getMediaTitles().get(uiComponentIndex);
|
||||
TextView titleView = mRecommendationViewHolder.getMediaTitles().get(itemIndex);
|
||||
titleView.setText(title);
|
||||
|
||||
// Set up subtitle
|
||||
@@ -1062,13 +1052,10 @@ public class MediaControlPanel {
|
||||
boolean shouldShowSubtitleText = !TextUtils.isEmpty(title);
|
||||
CharSequence subtitle = shouldShowSubtitleText ? recommendation.getSubtitle() : "";
|
||||
hasSubtitle |= !TextUtils.isEmpty(subtitle);
|
||||
TextView subtitleView =
|
||||
mRecommendationViewHolder.getMediaSubtitles().get(uiComponentIndex);
|
||||
TextView subtitleView = mRecommendationViewHolder.getMediaSubtitles().get(itemIndex);
|
||||
subtitleView.setText(subtitle);
|
||||
|
||||
uiComponentIndex++;
|
||||
}
|
||||
mSmartspaceMediaItemsCount = uiComponentIndex;
|
||||
mSmartspaceMediaItemsCount = NUM_REQUIRED_RECOMMENDATIONS;
|
||||
|
||||
// If there's no subtitles and/or titles for any of the albums, hide those views.
|
||||
ConstraintSet expandedSet = mMediaViewController.getExpandedLayout();
|
||||
|
||||
@@ -166,7 +166,7 @@ class MediaDataFilter @Inject constructor(
|
||||
shouldPrioritizeMutable = true
|
||||
}
|
||||
|
||||
if (!data.isValid) {
|
||||
if (!data.isValid()) {
|
||||
Log.d(TAG, "Invalid recommendation data. Skip showing the rec card")
|
||||
return
|
||||
}
|
||||
@@ -203,7 +203,6 @@ class MediaDataFilter @Inject constructor(
|
||||
if (smartspaceMediaData.isActive) {
|
||||
smartspaceMediaData = EMPTY_SMARTSPACE_MEDIA_DATA.copy(
|
||||
targetId = smartspaceMediaData.targetId,
|
||||
isValid = smartspaceMediaData.isValid,
|
||||
instanceId = smartspaceMediaData.instanceId)
|
||||
}
|
||||
listeners.forEach { it.onSmartspaceMediaDataRemoved(key, immediately) }
|
||||
@@ -260,7 +259,6 @@ class MediaDataFilter @Inject constructor(
|
||||
}
|
||||
smartspaceMediaData = EMPTY_SMARTSPACE_MEDIA_DATA.copy(
|
||||
targetId = smartspaceMediaData.targetId,
|
||||
isValid = smartspaceMediaData.isValid,
|
||||
instanceId = smartspaceMediaData.instanceId)
|
||||
mediaDataManager.dismissSmartspaceRecommendation(smartspaceMediaData.targetId,
|
||||
delay = 0L)
|
||||
@@ -272,13 +270,13 @@ class MediaDataFilter @Inject constructor(
|
||||
*/
|
||||
fun hasActiveMediaOrRecommendation() =
|
||||
userEntries.any { it.value.active } ||
|
||||
(smartspaceMediaData.isActive && smartspaceMediaData.isValid)
|
||||
(smartspaceMediaData.isActive && smartspaceMediaData.isValid())
|
||||
|
||||
/**
|
||||
* Are there any media entries we should display?
|
||||
*/
|
||||
fun hasAnyMediaOrRecommendation() = userEntries.isNotEmpty() ||
|
||||
(smartspaceMediaData.isActive && smartspaceMediaData.isValid)
|
||||
(smartspaceMediaData.isActive && smartspaceMediaData.isValid())
|
||||
|
||||
/**
|
||||
* Are there any media notifications active (excluding the recommendation)?
|
||||
|
||||
@@ -105,7 +105,6 @@ private val LOADING = MediaData(
|
||||
internal val EMPTY_SMARTSPACE_MEDIA_DATA = SmartspaceMediaData(
|
||||
targetId = "INVALID",
|
||||
isActive = false,
|
||||
isValid = false,
|
||||
packageName = "INVALID",
|
||||
cardAction = null,
|
||||
recommendations = emptyList(),
|
||||
@@ -534,7 +533,7 @@ class MediaDataManager(
|
||||
* connection session.
|
||||
*/
|
||||
fun dismissSmartspaceRecommendation(key: String, delay: Long) {
|
||||
if (smartspaceMediaData.targetId != key || !smartspaceMediaData.isValid) {
|
||||
if (smartspaceMediaData.targetId != key || !smartspaceMediaData.isValid()) {
|
||||
// If this doesn't match, or we've already invalidated the data, no action needed
|
||||
return
|
||||
}
|
||||
@@ -1222,7 +1221,6 @@ class MediaDataManager(
|
||||
return SmartspaceMediaData(
|
||||
targetId = target.smartspaceTargetId,
|
||||
isActive = isActive,
|
||||
isValid = true,
|
||||
packageName = it,
|
||||
cardAction = target.baseAction,
|
||||
recommendations = target.iconGrid,
|
||||
|
||||
@@ -30,10 +30,6 @@ data class SmartspaceMediaData(
|
||||
* Indicates if the status is active.
|
||||
*/
|
||||
val isActive: Boolean,
|
||||
/**
|
||||
* Indicates if all the required data field is valid.
|
||||
*/
|
||||
val isValid: Boolean,
|
||||
/**
|
||||
* Package name of the media recommendations' provider-app.
|
||||
*/
|
||||
@@ -58,4 +54,19 @@ data class SmartspaceMediaData(
|
||||
* Instance ID for [MediaUiEventLogger]
|
||||
*/
|
||||
val instanceId: InstanceId
|
||||
)
|
||||
) {
|
||||
/**
|
||||
* Indicates if all the data is valid.
|
||||
*
|
||||
* TODO(b/230333302): Make MediaControlPanel more flexible so that we can display fewer than
|
||||
* [NUM_REQUIRED_RECOMMENDATIONS].
|
||||
*/
|
||||
fun isValid() = getValidRecommendations().size >= NUM_REQUIRED_RECOMMENDATIONS
|
||||
|
||||
/**
|
||||
* Returns the list of [recommendations] that have valid data.
|
||||
*/
|
||||
fun getValidRecommendations() = recommendations.filter { it.icon != null }
|
||||
}
|
||||
|
||||
const val NUM_REQUIRED_RECOMMENDATIONS = 3
|
||||
|
||||
@@ -270,7 +270,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
smartspaceData = EMPTY_SMARTSPACE_MEDIA_DATA.copy(
|
||||
packageName = PACKAGE,
|
||||
instanceId = instanceId,
|
||||
recommendations = listOf(smartspaceAction),
|
||||
recommendations = listOf(smartspaceAction, smartspaceAction, smartspaceAction),
|
||||
cardAction = smartspaceAction
|
||||
)
|
||||
}
|
||||
@@ -1447,6 +1447,66 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
verify(logger).logRecommendationItemTap(eq(PACKAGE), eq(instanceId), eq(0))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun bindRecommendation_listHasTooFewRecs_notDisplayed() {
|
||||
player.attachRecommendation(recommendationViewHolder)
|
||||
val icon = Icon.createWithResource(context, R.drawable.ic_1x_mobiledata)
|
||||
val data = smartspaceData.copy(
|
||||
recommendations = listOf(
|
||||
SmartspaceAction.Builder("id1", "title1")
|
||||
.setSubtitle("subtitle1")
|
||||
.setIcon(icon)
|
||||
.setExtras(Bundle.EMPTY)
|
||||
.build(),
|
||||
SmartspaceAction.Builder("id2", "title2")
|
||||
.setSubtitle("subtitle2")
|
||||
.setIcon(icon)
|
||||
.setExtras(Bundle.EMPTY)
|
||||
.build(),
|
||||
)
|
||||
)
|
||||
|
||||
player.bindRecommendation(data)
|
||||
|
||||
assertThat(recTitle1.text).isEqualTo("")
|
||||
verify(mediaViewController, never()).refreshState()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun bindRecommendation_listHasTooFewRecsWithIcons_notDisplayed() {
|
||||
player.attachRecommendation(recommendationViewHolder)
|
||||
val icon = Icon.createWithResource(context, R.drawable.ic_1x_mobiledata)
|
||||
val data = smartspaceData.copy(
|
||||
recommendations = listOf(
|
||||
SmartspaceAction.Builder("id1", "title1")
|
||||
.setSubtitle("subtitle1")
|
||||
.setIcon(icon)
|
||||
.setExtras(Bundle.EMPTY)
|
||||
.build(),
|
||||
SmartspaceAction.Builder("id2", "title2")
|
||||
.setSubtitle("subtitle2")
|
||||
.setIcon(icon)
|
||||
.setExtras(Bundle.EMPTY)
|
||||
.build(),
|
||||
SmartspaceAction.Builder("id2", "empty icon 1")
|
||||
.setSubtitle("subtitle2")
|
||||
.setIcon(null)
|
||||
.setExtras(Bundle.EMPTY)
|
||||
.build(),
|
||||
SmartspaceAction.Builder("id2", "empty icon 2")
|
||||
.setSubtitle("subtitle2")
|
||||
.setIcon(null)
|
||||
.setExtras(Bundle.EMPTY)
|
||||
.build(),
|
||||
)
|
||||
)
|
||||
|
||||
player.bindRecommendation(data)
|
||||
|
||||
assertThat(recTitle1.text).isEqualTo("")
|
||||
verify(mediaViewController, never()).refreshState()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun bindRecommendation_hasTitlesAndSubtitles() {
|
||||
player.attachRecommendation(recommendationViewHolder)
|
||||
|
||||
@@ -110,7 +110,7 @@ class MediaDataFilterTest : SysuiTestCase() {
|
||||
|
||||
`when`(smartspaceData.targetId).thenReturn(SMARTSPACE_KEY)
|
||||
`when`(smartspaceData.isActive).thenReturn(true)
|
||||
`when`(smartspaceData.isValid).thenReturn(true)
|
||||
`when`(smartspaceData.isValid()).thenReturn(true)
|
||||
`when`(smartspaceData.packageName).thenReturn(SMARTSPACE_PACKAGE)
|
||||
`when`(smartspaceData.recommendations).thenReturn(listOf(smartspaceMediaRecommendationItem))
|
||||
`when`(smartspaceData.headphoneConnectionTimeMillis).thenReturn(
|
||||
@@ -196,24 +196,110 @@ class MediaDataFilterTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testHasAnyMediaOrRecommendation() {
|
||||
assertThat(mediaDataFilter.hasAnyMediaOrRecommendation()).isFalse()
|
||||
fun hasAnyMedia_noMediaSet_returnsFalse() {
|
||||
assertThat(mediaDataFilter.hasAnyMedia()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun hasAnyMedia_mediaSet_returnsTrue() {
|
||||
mediaDataFilter.onMediaDataLoaded(KEY, oldKey = null, data = dataMain)
|
||||
assertThat(mediaDataFilter.hasAnyMediaOrRecommendation()).isTrue()
|
||||
|
||||
assertThat(mediaDataFilter.hasAnyMedia()).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testHasActiveMediaOrRecommendation() {
|
||||
assertThat(mediaDataFilter.hasActiveMediaOrRecommendation()).isFalse()
|
||||
val data = dataMain.copy(active = true)
|
||||
fun hasAnyMedia_recommendationSet_returnsFalse() {
|
||||
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
|
||||
|
||||
assertThat(mediaDataFilter.hasAnyMedia()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun hasAnyMediaOrRecommendation_noMediaSet_returnsFalse() {
|
||||
assertThat(mediaDataFilter.hasAnyMediaOrRecommendation()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun hasAnyMediaOrRecommendation_mediaSet_returnsTrue() {
|
||||
mediaDataFilter.onMediaDataLoaded(KEY, oldKey = null, data = dataMain)
|
||||
|
||||
assertThat(mediaDataFilter.hasAnyMediaOrRecommendation()).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun hasAnyMediaOrRecommendation_recommendationSet_returnsTrue() {
|
||||
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
|
||||
|
||||
assertThat(mediaDataFilter.hasAnyMediaOrRecommendation()).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun hasActiveMedia_noMediaSet_returnsFalse() {
|
||||
assertThat(mediaDataFilter.hasActiveMedia()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun hasActiveMedia_inactiveMediaSet_returnsFalse() {
|
||||
val data = dataMain.copy(active = false)
|
||||
mediaDataFilter.onMediaDataLoaded(KEY, oldKey = null, data = data)
|
||||
assertThat(mediaDataFilter.hasActiveMediaOrRecommendation()).isTrue()
|
||||
|
||||
assertThat(mediaDataFilter.hasActiveMedia()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun hasActiveMedia_activeMediaSet_returnsTrue() {
|
||||
val data = dataMain.copy(active = true)
|
||||
mediaDataFilter.onMediaDataLoaded(KEY, oldKey = null, data = data)
|
||||
|
||||
assertThat(mediaDataFilter.hasActiveMedia()).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun hasActiveMediaOrRecommendation_nothingSet_returnsFalse() {
|
||||
assertThat(mediaDataFilter.hasActiveMediaOrRecommendation()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun hasActiveMediaOrRecommendation_inactiveMediaSet_returnsFalse() {
|
||||
val data = dataMain.copy(active = false)
|
||||
mediaDataFilter.onMediaDataLoaded(KEY, oldKey = null, data = data)
|
||||
|
||||
assertThat(mediaDataFilter.hasActiveMediaOrRecommendation()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun hasActiveMediaOrRecommendation_activeMediaSet_returnsTrue() {
|
||||
val data = dataMain.copy(active = true)
|
||||
mediaDataFilter.onMediaDataLoaded(KEY, oldKey = null, data = data)
|
||||
|
||||
assertThat(mediaDataFilter.hasActiveMediaOrRecommendation()).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun hasActiveMediaOrRecommendation_inactiveRecommendationSet_returnsFalse() {
|
||||
`when`(smartspaceData.isActive).thenReturn(false)
|
||||
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
|
||||
|
||||
assertThat(mediaDataFilter.hasActiveMediaOrRecommendation()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun hasActiveMediaOrRecommendation_invalidRecommendationSet_returnsFalse() {
|
||||
`when`(smartspaceData.isValid()).thenReturn(false)
|
||||
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
|
||||
|
||||
assertThat(mediaDataFilter.hasActiveMediaOrRecommendation()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun hasActiveMediaOrRecommendation_activeAndValidRecommendationSet_returnsTrue() {
|
||||
`when`(smartspaceData.isActive).thenReturn(true)
|
||||
`when`(smartspaceData.isValid()).thenReturn(true)
|
||||
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
|
||||
|
||||
assertThat(mediaDataFilter.hasActiveMediaOrRecommendation()).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testHasAnyMediaOrRecommendation_onlyCurrentUser() {
|
||||
assertThat(mediaDataFilter.hasAnyMediaOrRecommendation()).isFalse()
|
||||
@@ -332,7 +418,7 @@ class MediaDataFilterTest : SysuiTestCase() {
|
||||
|
||||
@Test
|
||||
fun testOnSmartspaceMediaDataLoaded_hasRecentMedia_activeInvalidRec_usesMedia() {
|
||||
`when`(smartspaceData.isValid).thenReturn(false)
|
||||
`when`(smartspaceData.isValid()).thenReturn(false)
|
||||
|
||||
// WHEN we have media that was recently played, but not currently active
|
||||
val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
|
||||
|
||||
@@ -7,6 +7,7 @@ import android.app.smartspace.SmartspaceAction
|
||||
import android.app.smartspace.SmartspaceTarget
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.drawable.Icon
|
||||
import android.media.MediaDescription
|
||||
import android.media.MediaMetadata
|
||||
import android.media.session.MediaController
|
||||
@@ -95,6 +96,7 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
lateinit var smartspaceMediaDataProvider: SmartspaceMediaDataProvider
|
||||
@Mock lateinit var mediaSmartspaceTarget: SmartspaceTarget
|
||||
@Mock private lateinit var mediaRecommendationItem: SmartspaceAction
|
||||
lateinit var validRecommendationList: List<SmartspaceAction>
|
||||
@Mock private lateinit var mediaSmartspaceBaseAction: SmartspaceAction
|
||||
@Mock private lateinit var mediaFlags: MediaFlags
|
||||
@Mock private lateinit var logger: MediaUiEventLogger
|
||||
@@ -170,12 +172,17 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
putString("package_name", PACKAGE_NAME)
|
||||
putParcelable("dismiss_intent", DISMISS_INTENT)
|
||||
}
|
||||
val icon = Icon.createWithResource(context, android.R.drawable.ic_media_play)
|
||||
whenever(mediaSmartspaceBaseAction.extras).thenReturn(recommendationExtras)
|
||||
whenever(mediaSmartspaceTarget.baseAction).thenReturn(mediaSmartspaceBaseAction)
|
||||
whenever(mediaRecommendationItem.extras).thenReturn(recommendationExtras)
|
||||
whenever(mediaRecommendationItem.icon).thenReturn(icon)
|
||||
validRecommendationList = listOf(
|
||||
mediaRecommendationItem, mediaRecommendationItem, mediaRecommendationItem
|
||||
)
|
||||
whenever(mediaSmartspaceTarget.smartspaceTargetId).thenReturn(KEY_MEDIA_SMARTSPACE)
|
||||
whenever(mediaSmartspaceTarget.featureType).thenReturn(SmartspaceTarget.FEATURE_MEDIA)
|
||||
whenever(mediaSmartspaceTarget.iconGrid).thenReturn(listOf(mediaRecommendationItem))
|
||||
whenever(mediaSmartspaceTarget.iconGrid).thenReturn(validRecommendationList)
|
||||
whenever(mediaSmartspaceTarget.creationTimeMillis).thenReturn(1234L)
|
||||
whenever(mediaFlags.areMediaSessionActionsEnabled(any(), any())).thenReturn(false)
|
||||
whenever(logger.getNewInstanceId()).thenReturn(instanceIdSequence.newInstanceId())
|
||||
@@ -505,10 +512,9 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
eq(SmartspaceMediaData(
|
||||
targetId = KEY_MEDIA_SMARTSPACE,
|
||||
isActive = true,
|
||||
isValid = true,
|
||||
packageName = PACKAGE_NAME,
|
||||
cardAction = mediaSmartspaceBaseAction,
|
||||
recommendations = listOf(mediaRecommendationItem),
|
||||
recommendations = validRecommendationList,
|
||||
dismissIntent = DISMISS_INTENT,
|
||||
headphoneConnectionTimeMillis = 1234L,
|
||||
instanceId = InstanceId.fakeInstanceId(instanceId))),
|
||||
@@ -527,7 +533,6 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
eq(EMPTY_SMARTSPACE_MEDIA_DATA.copy(
|
||||
targetId = KEY_MEDIA_SMARTSPACE,
|
||||
isActive = true,
|
||||
isValid = false,
|
||||
dismissIntent = DISMISS_INTENT,
|
||||
headphoneConnectionTimeMillis = 1234L,
|
||||
instanceId = InstanceId.fakeInstanceId(instanceId))),
|
||||
@@ -553,7 +558,6 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
eq(EMPTY_SMARTSPACE_MEDIA_DATA.copy(
|
||||
targetId = KEY_MEDIA_SMARTSPACE,
|
||||
isActive = true,
|
||||
isValid = false,
|
||||
dismissIntent = null,
|
||||
headphoneConnectionTimeMillis = 1234L,
|
||||
instanceId = InstanceId.fakeInstanceId(instanceId))),
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
package com.android.systemui.media
|
||||
|
||||
import android.app.smartspace.SmartspaceAction
|
||||
import android.graphics.drawable.Icon
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.internal.logging.InstanceId
|
||||
import com.android.systemui.R
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import org.junit.Test
|
||||
|
||||
@SmallTest
|
||||
class SmartspaceMediaDataTest : SysuiTestCase() {
|
||||
|
||||
private val icon: Icon = Icon.createWithResource(context, R.drawable.ic_media_play)
|
||||
|
||||
@Test
|
||||
fun getValidRecommendations_onlyReturnsRecsWithIcons() {
|
||||
val withIcon1 = SmartspaceAction.Builder("id", "title").setIcon(icon).build()
|
||||
val withIcon2 = SmartspaceAction.Builder("id", "title").setIcon(icon).build()
|
||||
val withoutIcon1 = SmartspaceAction.Builder("id", "title").setIcon(null).build()
|
||||
val withoutIcon2 = SmartspaceAction.Builder("id", "title").setIcon(null).build()
|
||||
val recommendations = listOf(withIcon1, withoutIcon1, withIcon2, withoutIcon2)
|
||||
|
||||
val data = DEFAULT_DATA.copy(recommendations = recommendations)
|
||||
|
||||
assertThat(data.getValidRecommendations()).isEqualTo(listOf(withIcon1, withIcon2))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isValid_emptyList_returnsFalse() {
|
||||
val data = DEFAULT_DATA.copy(recommendations = listOf())
|
||||
|
||||
assertThat(data.isValid()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isValid_tooFewRecs_returnsFalse() {
|
||||
val data = DEFAULT_DATA.copy(
|
||||
recommendations = listOf(
|
||||
SmartspaceAction.Builder("id", "title").setIcon(icon).build()
|
||||
)
|
||||
)
|
||||
|
||||
assertThat(data.isValid()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isValid_tooFewRecsWithIcons_returnsFalse() {
|
||||
val recommendations = mutableListOf<SmartspaceAction>()
|
||||
// Add one fewer recommendation w/ icon than the number required
|
||||
for (i in 1 until NUM_REQUIRED_RECOMMENDATIONS) {
|
||||
recommendations.add(
|
||||
SmartspaceAction.Builder("id", "title").setIcon(icon).build()
|
||||
)
|
||||
}
|
||||
for (i in 1 until 3) {
|
||||
recommendations.add(
|
||||
SmartspaceAction.Builder("id", "title").setIcon(null).build()
|
||||
)
|
||||
}
|
||||
|
||||
val data = DEFAULT_DATA.copy(recommendations = recommendations)
|
||||
|
||||
assertThat(data.isValid()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isValid_enoughRecsWithIcons_returnsTrue() {
|
||||
val recommendations = mutableListOf<SmartspaceAction>()
|
||||
// Add the number of required recommendations
|
||||
for (i in 0 until NUM_REQUIRED_RECOMMENDATIONS) {
|
||||
recommendations.add(
|
||||
SmartspaceAction.Builder("id", "title").setIcon(icon).build()
|
||||
)
|
||||
}
|
||||
|
||||
val data = DEFAULT_DATA.copy(recommendations = recommendations)
|
||||
|
||||
assertThat(data.isValid()).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isValid_manyRecsWithIcons_returnsTrue() {
|
||||
val recommendations = mutableListOf<SmartspaceAction>()
|
||||
// Add more than enough recommendations
|
||||
for (i in 0 until NUM_REQUIRED_RECOMMENDATIONS + 3) {
|
||||
recommendations.add(
|
||||
SmartspaceAction.Builder("id", "title").setIcon(icon).build()
|
||||
)
|
||||
}
|
||||
|
||||
val data = DEFAULT_DATA.copy(recommendations = recommendations)
|
||||
|
||||
assertThat(data.isValid()).isTrue()
|
||||
}
|
||||
}
|
||||
|
||||
private val DEFAULT_DATA = SmartspaceMediaData(
|
||||
targetId = "INVALID",
|
||||
isActive = false,
|
||||
packageName = "INVALID",
|
||||
cardAction = null,
|
||||
recommendations = emptyList(),
|
||||
dismissIntent = null,
|
||||
headphoneConnectionTimeMillis = 0,
|
||||
instanceId = InstanceId.fakeInstanceId(-1)
|
||||
)
|
||||
Reference in New Issue
Block a user