[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:
Caitlin Cassidy
2022-04-25 21:30:59 +00:00
parent 3c7d69d9f3
commit c024662af2
8 changed files with 310 additions and 58 deletions

View File

@@ -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();

View File

@@ -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)?

View File

@@ -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,

View File

@@ -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

View File

@@ -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)

View File

@@ -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())

View File

@@ -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))),

View File

@@ -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)
)