Merge "Populate additional fields for smartspace logging" into sc-qpr1-dev
This commit is contained in:
@@ -212,14 +212,32 @@ class MediaCarouselController @Inject constructor(
|
|||||||
isSsReactivated: Boolean
|
isSsReactivated: Boolean
|
||||||
) {
|
) {
|
||||||
if (addOrUpdatePlayer(key, oldKey, data)) {
|
if (addOrUpdatePlayer(key, oldKey, data)) {
|
||||||
|
// Log card received if a new resumable media card is added
|
||||||
MediaPlayerData.getMediaPlayer(key)?.let {
|
MediaPlayerData.getMediaPlayer(key)?.let {
|
||||||
logSmartspaceCardReported(759, // SMARTSPACE_CARD_RECEIVED
|
logSmartspaceCardReported(759, // SMARTSPACE_CARD_RECEIVED
|
||||||
it.mInstanceId,
|
it.mInstanceId,
|
||||||
|
it.mUid,
|
||||||
/* isRecommendationCard */ false,
|
/* isRecommendationCard */ false,
|
||||||
it.surfaceForSmartspaceLogging,
|
it.surfaceForSmartspaceLogging,
|
||||||
rank = MediaPlayerData.getMediaPlayerIndex(key))
|
rank = MediaPlayerData.getMediaPlayerIndex(key))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (isSsReactivated) {
|
||||||
|
// If resumable media is reactivated by headphone connection, update instance
|
||||||
|
// id for each card and log a receive event.
|
||||||
|
MediaPlayerData.players().forEachIndexed { index, it ->
|
||||||
|
if (it.recommendationViewHolder == null) {
|
||||||
|
it.mInstanceId = SmallHash.hash(it.mUid +
|
||||||
|
systemClock.currentTimeMillis().toInt())
|
||||||
|
logSmartspaceCardReported(759, // SMARTSPACE_CARD_RECEIVED
|
||||||
|
it.mInstanceId,
|
||||||
|
it.mUid,
|
||||||
|
/* isRecommendationCard */ false,
|
||||||
|
it.surfaceForSmartspaceLogging,
|
||||||
|
rank = index)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
if (mediaCarouselScrollHandler.visibleToUser &&
|
if (mediaCarouselScrollHandler.visibleToUser &&
|
||||||
isSsReactivated && !mediaCarouselScrollHandler.qsExpanded) {
|
isSsReactivated && !mediaCarouselScrollHandler.qsExpanded) {
|
||||||
// It could happen that reactived media player isn't visible to user because
|
// It could happen that reactived media player isn't visible to user because
|
||||||
@@ -252,6 +270,7 @@ class MediaCarouselController @Inject constructor(
|
|||||||
MediaPlayerData.getMediaPlayer(key)?.let {
|
MediaPlayerData.getMediaPlayer(key)?.let {
|
||||||
logSmartspaceCardReported(759, // SMARTSPACE_CARD_RECEIVED
|
logSmartspaceCardReported(759, // SMARTSPACE_CARD_RECEIVED
|
||||||
it.mInstanceId,
|
it.mInstanceId,
|
||||||
|
it.mUid,
|
||||||
/* isRecommendationCard */ true,
|
/* isRecommendationCard */ true,
|
||||||
it.surfaceForSmartspaceLogging,
|
it.surfaceForSmartspaceLogging,
|
||||||
rank = MediaPlayerData.getMediaPlayerIndex(key))
|
rank = MediaPlayerData.getMediaPlayerIndex(key))
|
||||||
@@ -261,6 +280,7 @@ class MediaCarouselController @Inject constructor(
|
|||||||
MediaPlayerData.getMediaPlayerIndex(key)) {
|
MediaPlayerData.getMediaPlayerIndex(key)) {
|
||||||
logSmartspaceCardReported(800, // SMARTSPACE_CARD_SEEN
|
logSmartspaceCardReported(800, // SMARTSPACE_CARD_SEEN
|
||||||
it.mInstanceId,
|
it.mInstanceId,
|
||||||
|
it.mUid,
|
||||||
/* isRecommendationCard */ true,
|
/* isRecommendationCard */ true,
|
||||||
it.surfaceForSmartspaceLogging)
|
it.surfaceForSmartspaceLogging)
|
||||||
}
|
}
|
||||||
@@ -339,9 +359,9 @@ class MediaCarouselController @Inject constructor(
|
|||||||
if (activeMediaIndex != -1) {
|
if (activeMediaIndex != -1) {
|
||||||
previousVisiblePlayerKey?.let {
|
previousVisiblePlayerKey?.let {
|
||||||
val previousVisibleIndex = MediaPlayerData.playerKeys()
|
val previousVisibleIndex = MediaPlayerData.playerKeys()
|
||||||
.indexOfFirst { key -> it == key }
|
.indexOfFirst { key -> it == key }
|
||||||
mediaCarouselScrollHandler
|
mediaCarouselScrollHandler
|
||||||
.scrollToPlayer(previousVisibleIndex, activeMediaIndex)
|
.scrollToPlayer(previousVisibleIndex, activeMediaIndex)
|
||||||
} ?: {
|
} ?: {
|
||||||
mediaCarouselScrollHandler.scrollToPlayer(destIndex = activeMediaIndex)
|
mediaCarouselScrollHandler.scrollToPlayer(destIndex = activeMediaIndex)
|
||||||
}
|
}
|
||||||
@@ -355,11 +375,11 @@ class MediaCarouselController @Inject constructor(
|
|||||||
MediaPlayerData.moveIfExists(oldKey, key)
|
MediaPlayerData.moveIfExists(oldKey, key)
|
||||||
val existingPlayer = MediaPlayerData.getMediaPlayer(key)
|
val existingPlayer = MediaPlayerData.getMediaPlayer(key)
|
||||||
val curVisibleMediaKey = MediaPlayerData.playerKeys()
|
val curVisibleMediaKey = MediaPlayerData.playerKeys()
|
||||||
.elementAtOrNull(mediaCarouselScrollHandler.visibleMediaIndex)
|
.elementAtOrNull(mediaCarouselScrollHandler.visibleMediaIndex)
|
||||||
if (existingPlayer == null) {
|
if (existingPlayer == null) {
|
||||||
var newPlayer = mediaControlPanelFactory.get()
|
var newPlayer = mediaControlPanelFactory.get()
|
||||||
newPlayer.attachPlayer(
|
newPlayer.attachPlayer(
|
||||||
PlayerViewHolder.create(LayoutInflater.from(context), mediaContent))
|
PlayerViewHolder.create(LayoutInflater.from(context), mediaContent))
|
||||||
newPlayer.mediaViewController.sizeChangedListener = this::updateCarouselDimensions
|
newPlayer.mediaViewController.sizeChangedListener = this::updateCarouselDimensions
|
||||||
val lp = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
val lp = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT)
|
ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||||
@@ -407,14 +427,14 @@ class MediaCarouselController @Inject constructor(
|
|||||||
|
|
||||||
var newRecs = mediaControlPanelFactory.get()
|
var newRecs = mediaControlPanelFactory.get()
|
||||||
newRecs.attachRecommendation(
|
newRecs.attachRecommendation(
|
||||||
RecommendationViewHolder.create(LayoutInflater.from(context), mediaContent))
|
RecommendationViewHolder.create(LayoutInflater.from(context), mediaContent))
|
||||||
newRecs.mediaViewController.sizeChangedListener = this::updateCarouselDimensions
|
newRecs.mediaViewController.sizeChangedListener = this::updateCarouselDimensions
|
||||||
val lp = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
val lp = LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
ViewGroup.LayoutParams.WRAP_CONTENT)
|
ViewGroup.LayoutParams.WRAP_CONTENT)
|
||||||
newRecs.recommendationViewHolder?.recommendations?.setLayoutParams(lp)
|
newRecs.recommendationViewHolder?.recommendations?.setLayoutParams(lp)
|
||||||
newRecs.bindRecommendation(data.copy(backgroundColor = bgColor))
|
newRecs.bindRecommendation(data.copy(backgroundColor = bgColor))
|
||||||
val curVisibleMediaKey = MediaPlayerData.playerKeys()
|
val curVisibleMediaKey = MediaPlayerData.playerKeys()
|
||||||
.elementAtOrNull(mediaCarouselScrollHandler.visibleMediaIndex)
|
.elementAtOrNull(mediaCarouselScrollHandler.visibleMediaIndex)
|
||||||
MediaPlayerData.addMediaRecommendation(key, data, newRecs, shouldPrioritize, systemClock)
|
MediaPlayerData.addMediaRecommendation(key, data, newRecs, shouldPrioritize, systemClock)
|
||||||
updatePlayerToState(newRecs, noAnimation = true)
|
updatePlayerToState(newRecs, noAnimation = true)
|
||||||
reorderAllPlayers(curVisibleMediaKey)
|
reorderAllPlayers(curVisibleMediaKey)
|
||||||
@@ -462,7 +482,7 @@ class MediaCarouselController @Inject constructor(
|
|||||||
removePlayer(key, dismissMediaData = false, dismissRecommendation = false)
|
removePlayer(key, dismissMediaData = false, dismissRecommendation = false)
|
||||||
smartspaceMediaData?.let {
|
smartspaceMediaData?.let {
|
||||||
addSmartspaceMediaRecommendations(
|
addSmartspaceMediaRecommendations(
|
||||||
it.targetId, it, MediaPlayerData.shouldPrioritizeSs)
|
it.targetId, it, MediaPlayerData.shouldPrioritizeSs)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
removePlayer(key, dismissMediaData = false, dismissRecommendation = false)
|
removePlayer(key, dismissMediaData = false, dismissRecommendation = false)
|
||||||
@@ -585,7 +605,7 @@ class MediaCarouselController @Inject constructor(
|
|||||||
?: endShowsActive
|
?: endShowsActive
|
||||||
if (currentlyShowingOnlyActive != endShowsActive ||
|
if (currentlyShowingOnlyActive != endShowsActive ||
|
||||||
((currentTransitionProgress != 1.0f && currentTransitionProgress != 0.0f) &&
|
((currentTransitionProgress != 1.0f && currentTransitionProgress != 0.0f) &&
|
||||||
startShowsActive != endShowsActive)) {
|
startShowsActive != endShowsActive)) {
|
||||||
// Whenever we're transitioning from between differing states or the endstate differs
|
// Whenever we're transitioning from between differing states or the endstate differs
|
||||||
// we reset the translation
|
// we reset the translation
|
||||||
currentlyShowingOnlyActive = endShowsActive
|
currentlyShowingOnlyActive = endShowsActive
|
||||||
@@ -696,23 +716,43 @@ class MediaCarouselController @Inject constructor(
|
|||||||
}
|
}
|
||||||
logSmartspaceCardReported(800, // SMARTSPACE_CARD_SEEN
|
logSmartspaceCardReported(800, // SMARTSPACE_CARD_SEEN
|
||||||
mediaControlPanel.mInstanceId,
|
mediaControlPanel.mInstanceId,
|
||||||
|
mediaControlPanel.mUid,
|
||||||
isRecommendationCard,
|
isRecommendationCard,
|
||||||
mediaControlPanel.surfaceForSmartspaceLogging)
|
mediaControlPanel.surfaceForSmartspaceLogging)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmOverloads
|
@JvmOverloads
|
||||||
|
/**
|
||||||
|
* Log Smartspace events
|
||||||
|
*
|
||||||
|
* @param eventId UI event id (e.g. 800 for SMARTSPACE_CARD_SEEN)
|
||||||
|
* @param instanceId id to uniquely identify a card, e.g. each headphone generates a new
|
||||||
|
* instanceId
|
||||||
|
* @param uid uid for the application that media comes from
|
||||||
|
* @param isRecommendationCard whether the card is media recommendation
|
||||||
|
* @param surface which display surface the media card is on (e.g. lockscreen, shade)
|
||||||
|
* @param interactedSubcardRank the rank for interacted media item for recommendation card, -1
|
||||||
|
* for tapping on card but not on any media item, 0 for first media item, 1 for second, etc.
|
||||||
|
* @param interactedSubcardCardinality how many media items were shown to the user when there
|
||||||
|
* is user interaction
|
||||||
|
* @param rank the rank for media card in the media carousel, starting from 0
|
||||||
|
*
|
||||||
|
*/
|
||||||
fun logSmartspaceCardReported(
|
fun logSmartspaceCardReported(
|
||||||
eventId: Int,
|
eventId: Int,
|
||||||
instanceId: Int,
|
instanceId: Int,
|
||||||
|
uid: Int,
|
||||||
isRecommendationCard: Boolean,
|
isRecommendationCard: Boolean,
|
||||||
surface: Int,
|
surface: Int,
|
||||||
|
interactedSubcardRank: Int = 0,
|
||||||
|
interactedSubcardCardinality: Int = 0,
|
||||||
rank: Int = mediaCarouselScrollHandler.visibleMediaIndex
|
rank: Int = mediaCarouselScrollHandler.visibleMediaIndex
|
||||||
) {
|
) {
|
||||||
// Only log media resume card when Smartspace data is available
|
// Only log media resume card when Smartspace data is available
|
||||||
if (!isRecommendationCard &&
|
if (!isRecommendationCard &&
|
||||||
!mediaManager.smartspaceMediaData.isActive &&
|
!mediaManager.smartspaceMediaData.isActive &&
|
||||||
MediaPlayerData.smartspaceMediaData == null) {
|
MediaPlayerData.smartspaceMediaData == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -720,13 +760,20 @@ class MediaCarouselController @Inject constructor(
|
|||||||
SysUiStatsLog.write(SysUiStatsLog.SMARTSPACE_CARD_REPORTED,
|
SysUiStatsLog.write(SysUiStatsLog.SMARTSPACE_CARD_REPORTED,
|
||||||
eventId,
|
eventId,
|
||||||
instanceId,
|
instanceId,
|
||||||
if (isRecommendationCard)
|
// Deprecated, replaced with AiAi feature type so we don't need to create logging
|
||||||
SysUiStatsLog.SMART_SPACE_CARD_REPORTED__CARD_TYPE__HEADPHONE_MEDIA_RECOMMENDATIONS
|
// card type for each new feature.
|
||||||
else
|
SysUiStatsLog.SMART_SPACE_CARD_REPORTED__CARD_TYPE__UNKNOWN_CARD,
|
||||||
SysUiStatsLog.SMART_SPACE_CARD_REPORTED__CARD_TYPE__HEADPHONE_RESUME_MEDIA,
|
|
||||||
surface,
|
surface,
|
||||||
rank,
|
rank,
|
||||||
mediaContent.getChildCount())
|
mediaContent.getChildCount(),
|
||||||
|
if (isRecommendationCard)
|
||||||
|
15 // MEDIA_RECOMMENDATION
|
||||||
|
else
|
||||||
|
31, // MEDIA_RESUME
|
||||||
|
uid,
|
||||||
|
interactedSubcardRank,
|
||||||
|
interactedSubcardCardinality
|
||||||
|
)
|
||||||
/* ktlint-disable max-line-length */
|
/* ktlint-disable max-line-length */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -738,18 +785,20 @@ class MediaCarouselController @Inject constructor(
|
|||||||
if (!recommendation.isEmpty()) {
|
if (!recommendation.isEmpty()) {
|
||||||
logSmartspaceCardReported(761, // SMARTSPACE_CARD_DISMISS
|
logSmartspaceCardReported(761, // SMARTSPACE_CARD_DISMISS
|
||||||
recommendation.get(0).mInstanceId,
|
recommendation.get(0).mInstanceId,
|
||||||
|
recommendation.get(0).mUid,
|
||||||
true,
|
true,
|
||||||
recommendation.get(0).surfaceForSmartspaceLogging,
|
recommendation.get(0).surfaceForSmartspaceLogging,
|
||||||
/* rank */-1)
|
rank = -1)
|
||||||
} else {
|
} else {
|
||||||
val visibleMediaIndex = mediaCarouselScrollHandler.visibleMediaIndex
|
val visibleMediaIndex = mediaCarouselScrollHandler.visibleMediaIndex
|
||||||
if (MediaPlayerData.players().size > visibleMediaIndex) {
|
if (MediaPlayerData.players().size > visibleMediaIndex) {
|
||||||
val player = MediaPlayerData.players().elementAt(visibleMediaIndex)
|
val player = MediaPlayerData.players().elementAt(visibleMediaIndex)
|
||||||
logSmartspaceCardReported(761, // SMARTSPACE_CARD_DISMISS
|
logSmartspaceCardReported(761, // SMARTSPACE_CARD_DISMISS
|
||||||
player.mInstanceId,
|
player.mInstanceId,
|
||||||
false,
|
player.mUid,
|
||||||
|
false,
|
||||||
player.surfaceForSmartspaceLogging,
|
player.surfaceForSmartspaceLogging,
|
||||||
/* rank */-1)
|
rank = -1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mediaManager.onSwipeToDismiss()
|
mediaManager.onSwipeToDismiss()
|
||||||
@@ -768,7 +817,7 @@ class MediaCarouselController @Inject constructor(
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
internal object MediaPlayerData {
|
internal object MediaPlayerData {
|
||||||
private val EMPTY = MediaData(-1, false, 0, null, null, null, null, null,
|
private val EMPTY = MediaData(-1, false, 0, null, null, null, null, null,
|
||||||
emptyList(), emptyList(), "INVALID", null, null, null, true, null)
|
emptyList(), emptyList(), "INVALID", null, null, null, true, null)
|
||||||
// Whether should prioritize Smartspace card.
|
// Whether should prioritize Smartspace card.
|
||||||
internal var shouldPrioritizeSs: Boolean = false
|
internal var shouldPrioritizeSs: Boolean = false
|
||||||
private set
|
private set
|
||||||
@@ -776,18 +825,18 @@ internal object MediaPlayerData {
|
|||||||
private set
|
private set
|
||||||
|
|
||||||
data class MediaSortKey(
|
data class MediaSortKey(
|
||||||
// Whether the item represents a Smartspace media recommendation.
|
// Whether the item represents a Smartspace media recommendation.
|
||||||
val isSsMediaRec: Boolean,
|
val isSsMediaRec: Boolean,
|
||||||
val data: MediaData,
|
val data: MediaData,
|
||||||
val updateTime: Long = 0
|
val updateTime: Long = 0
|
||||||
)
|
)
|
||||||
|
|
||||||
private val comparator =
|
private val comparator =
|
||||||
compareByDescending<MediaSortKey> { it.data.isPlaying }
|
compareByDescending<MediaSortKey> { it.data.isPlaying }
|
||||||
.thenByDescending { if (shouldPrioritizeSs) it.isSsMediaRec else !it.isSsMediaRec }
|
.thenByDescending { if (shouldPrioritizeSs) it.isSsMediaRec else !it.isSsMediaRec }
|
||||||
.thenByDescending { it.data.isLocalSession }
|
.thenByDescending { it.data.isLocalSession }
|
||||||
.thenByDescending { !it.data.resumption }
|
.thenByDescending { !it.data.resumption }
|
||||||
.thenByDescending { it.updateTime }
|
.thenByDescending { it.updateTime }
|
||||||
|
|
||||||
private val mediaPlayers = TreeMap<MediaSortKey, MediaControlPanel>(comparator)
|
private val mediaPlayers = TreeMap<MediaSortKey, MediaControlPanel>(comparator)
|
||||||
private val mediaData: MutableMap<String, MediaSortKey> = mutableMapOf()
|
private val mediaData: MutableMap<String, MediaSortKey> = mutableMapOf()
|
||||||
@@ -888,4 +937,4 @@ internal object MediaPlayerData {
|
|||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -33,6 +33,7 @@ import android.graphics.drawable.Icon;
|
|||||||
import android.media.session.MediaController;
|
import android.media.session.MediaController;
|
||||||
import android.media.session.MediaSession;
|
import android.media.session.MediaSession;
|
||||||
import android.media.session.PlaybackState;
|
import android.media.session.PlaybackState;
|
||||||
|
import android.os.Process;
|
||||||
import android.text.Layout;
|
import android.text.Layout;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
@@ -111,6 +112,9 @@ public class MediaControlPanel {
|
|||||||
private int mAlbumArtSize;
|
private int mAlbumArtSize;
|
||||||
// Instance id for logging purpose.
|
// Instance id for logging purpose.
|
||||||
protected int mInstanceId = -1;
|
protected int mInstanceId = -1;
|
||||||
|
// Uid for the media app.
|
||||||
|
protected int mUid = Process.INVALID_UID;
|
||||||
|
private int mSmartspaceMediaItemsCount;
|
||||||
private MediaCarouselController mMediaCarouselController;
|
private MediaCarouselController mMediaCarouselController;
|
||||||
private final MediaOutputDialogFactory mMediaOutputDialogFactory;
|
private final MediaOutputDialogFactory mMediaOutputDialogFactory;
|
||||||
|
|
||||||
@@ -266,7 +270,13 @@ public class MediaControlPanel {
|
|||||||
}
|
}
|
||||||
mKey = key;
|
mKey = key;
|
||||||
MediaSession.Token token = data.getToken();
|
MediaSession.Token token = data.getToken();
|
||||||
mInstanceId = SmallHash.hash(data.getPackageName());
|
PackageManager packageManager = mContext.getPackageManager();
|
||||||
|
try {
|
||||||
|
mUid = packageManager.getApplicationInfo(data.getPackageName(), 0 /* flags */).uid;
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
Log.e(TAG, "Unable to look up package name", e);
|
||||||
|
}
|
||||||
|
mInstanceId = SmallHash.hash(mUid);
|
||||||
|
|
||||||
mBackgroundColor = data.getBackgroundColor();
|
mBackgroundColor = data.getBackgroundColor();
|
||||||
if (mToken == null || !mToken.equals(token)) {
|
if (mToken == null || !mToken.equals(token)) {
|
||||||
@@ -531,10 +541,11 @@ public class MediaControlPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Set up recommendation card's header.
|
// Set up recommendation card's header.
|
||||||
ApplicationInfo applicationInfo = null;
|
ApplicationInfo applicationInfo;
|
||||||
try {
|
try {
|
||||||
applicationInfo = mContext.getPackageManager()
|
applicationInfo = mContext.getPackageManager()
|
||||||
.getApplicationInfo(data.getPackageName(), 0 /* flags */);
|
.getApplicationInfo(data.getPackageName(), 0 /* flags */);
|
||||||
|
mUid = applicationInfo.uid;
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
Log.w(TAG, "Fail to get media recommendation's app info", e);
|
Log.w(TAG, "Fail to get media recommendation's app info", e);
|
||||||
return;
|
return;
|
||||||
@@ -553,7 +564,8 @@ public class MediaControlPanel {
|
|||||||
headerTitleText.setText(appLabel);
|
headerTitleText.setText(appLabel);
|
||||||
}
|
}
|
||||||
// Set up media rec card's tap action if applicable.
|
// Set up media rec card's tap action if applicable.
|
||||||
setSmartspaceRecItemOnClickListener(recommendationCard, data.getCardAction());
|
setSmartspaceRecItemOnClickListener(recommendationCard, data.getCardAction(),
|
||||||
|
/* interactedSubcardRank */ -1);
|
||||||
// Set up media rec card's accessibility label.
|
// Set up media rec card's accessibility label.
|
||||||
recommendationCard.setContentDescription(
|
recommendationCard.setContentDescription(
|
||||||
mContext.getString(R.string.controls_media_smartspace_rec_description, appLabel));
|
mContext.getString(R.string.controls_media_smartspace_rec_description, appLabel));
|
||||||
@@ -567,7 +579,8 @@ public class MediaControlPanel {
|
|||||||
ConstraintSet collapsedSet = mMediaViewController.getCollapsedLayout();
|
ConstraintSet collapsedSet = mMediaViewController.getCollapsedLayout();
|
||||||
int mediaRecommendationNum = Math.min(mediaRecommendationList.size(),
|
int mediaRecommendationNum = Math.min(mediaRecommendationList.size(),
|
||||||
MEDIA_RECOMMENDATION_MAX_NUM);
|
MEDIA_RECOMMENDATION_MAX_NUM);
|
||||||
for (int itemIndex = 0, uiComponentIndex = 0;
|
int uiComponentIndex = 0;
|
||||||
|
for (int itemIndex = 0;
|
||||||
itemIndex < mediaRecommendationNum && uiComponentIndex < mediaRecommendationNum;
|
itemIndex < mediaRecommendationNum && uiComponentIndex < mediaRecommendationNum;
|
||||||
itemIndex++) {
|
itemIndex++) {
|
||||||
SmartspaceAction recommendation = mediaRecommendationList.get(itemIndex);
|
SmartspaceAction recommendation = mediaRecommendationList.get(itemIndex);
|
||||||
@@ -582,7 +595,8 @@ public class MediaControlPanel {
|
|||||||
|
|
||||||
// Set up the media item's click listener if applicable.
|
// Set up the media item's click listener if applicable.
|
||||||
ViewGroup mediaCoverContainer = mediaCoverContainers.get(uiComponentIndex);
|
ViewGroup mediaCoverContainer = mediaCoverContainers.get(uiComponentIndex);
|
||||||
setSmartspaceRecItemOnClickListener(mediaCoverContainer, recommendation);
|
setSmartspaceRecItemOnClickListener(mediaCoverContainer, recommendation,
|
||||||
|
uiComponentIndex);
|
||||||
|
|
||||||
// Set up the accessibility label for the media item.
|
// Set up the accessibility label for the media item.
|
||||||
String artistName = recommendation.getExtras()
|
String artistName = recommendation.getExtras()
|
||||||
@@ -614,10 +628,10 @@ public class MediaControlPanel {
|
|||||||
mediaCoverItemsResIds.get(uiComponentIndex), true);
|
mediaCoverItemsResIds.get(uiComponentIndex), true);
|
||||||
setVisibleAndAlpha(expandedSet,
|
setVisibleAndAlpha(expandedSet,
|
||||||
mediaCoverContainersResIds.get(uiComponentIndex), true);
|
mediaCoverContainersResIds.get(uiComponentIndex), true);
|
||||||
|
|
||||||
uiComponentIndex++;
|
uiComponentIndex++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mSmartspaceMediaItemsCount = uiComponentIndex;
|
||||||
// Set up long press to show guts setting panel.
|
// Set up long press to show guts setting panel.
|
||||||
mRecommendationViewHolder.getDismiss().setOnClickListener(v -> {
|
mRecommendationViewHolder.getDismiss().setOnClickListener(v -> {
|
||||||
logSmartspaceCardReported(761, // SMARTSPACE_CARD_DISMISS
|
logSmartspaceCardReported(761, // SMARTSPACE_CARD_DISMISS
|
||||||
@@ -750,7 +764,8 @@ public class MediaControlPanel {
|
|||||||
|
|
||||||
private void setSmartspaceRecItemOnClickListener(
|
private void setSmartspaceRecItemOnClickListener(
|
||||||
@NonNull View view,
|
@NonNull View view,
|
||||||
@NonNull SmartspaceAction action) {
|
@NonNull SmartspaceAction action,
|
||||||
|
int interactedSubcardRank) {
|
||||||
if (view == null || action == null || action.getIntent() == null
|
if (view == null || action == null || action.getIntent() == null
|
||||||
|| action.getIntent().getExtras() == null) {
|
|| action.getIntent().getExtras() == null) {
|
||||||
Log.e(TAG, "No tap action can be set up");
|
Log.e(TAG, "No tap action can be set up");
|
||||||
@@ -758,9 +773,10 @@ public class MediaControlPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
view.setOnClickListener(v -> {
|
view.setOnClickListener(v -> {
|
||||||
// When media recommendation card is shown, it will always be the top card.
|
|
||||||
logSmartspaceCardReported(760, // SMARTSPACE_CARD_CLICK
|
logSmartspaceCardReported(760, // SMARTSPACE_CARD_CLICK
|
||||||
/* isRecommendationCard */ true);
|
/* isRecommendationCard */ true,
|
||||||
|
interactedSubcardRank,
|
||||||
|
getSmartspaceSubCardCardinality());
|
||||||
|
|
||||||
if (shouldSmartspaceRecItemOpenInForeground(action)) {
|
if (shouldSmartspaceRecItemOpenInForeground(action)) {
|
||||||
// Request to unlock the device if the activity needs to be opened in foreground.
|
// Request to unlock the device if the activity needs to be opened in foreground.
|
||||||
@@ -818,9 +834,28 @@ public class MediaControlPanel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void logSmartspaceCardReported(int eventId, boolean isRecommendationCard) {
|
private void logSmartspaceCardReported(int eventId, boolean isRecommendationCard) {
|
||||||
|
logSmartspaceCardReported(eventId, isRecommendationCard,
|
||||||
|
/* interactedSubcardRank */ 0,
|
||||||
|
/* interactedSubcardCardinality */ 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logSmartspaceCardReported(int eventId, boolean isRecommendationCard,
|
||||||
|
int interactedSubcardRank, int interactedSubcardCardinality) {
|
||||||
mMediaCarouselController.logSmartspaceCardReported(eventId,
|
mMediaCarouselController.logSmartspaceCardReported(eventId,
|
||||||
mInstanceId,
|
mInstanceId,
|
||||||
|
mUid,
|
||||||
isRecommendationCard,
|
isRecommendationCard,
|
||||||
getSurfaceForSmartspaceLogging());
|
getSurfaceForSmartspaceLogging(),
|
||||||
|
interactedSubcardRank,
|
||||||
|
interactedSubcardCardinality);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private int getSmartspaceSubCardCardinality() {
|
||||||
|
if (!mMediaCarouselController.getMediaCarouselScrollHandler().getQsExpanded()
|
||||||
|
&& mSmartspaceMediaItemsCount > 3) {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mSmartspaceMediaItemsCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user