Fix Smartspace media logging bugs
1. Log media card received event for both LS and SHADE 2. Log dismiss event for all impressed media card 3. Fix latency logging for media card 4. Fix instance id for media resume card Bug: 202552118 Test: manual, https://paste.googleplex.com/4995063781261312 Change-Id: Ie47db39a5aaae79a3a6c60b109877e4caebcf9ea
This commit is contained in:
@@ -37,7 +37,7 @@ import javax.inject.Provider
|
||||
|
||||
private const val TAG = "MediaCarouselController"
|
||||
private val settingsIntent = Intent().setAction(ACTION_MEDIA_CONTROLS_SETTINGS)
|
||||
private const val DEBUG = false
|
||||
private val DEBUG = Log.isLoggable(TAG, Log.DEBUG)
|
||||
|
||||
/**
|
||||
* Class that is responsible for keeping the view carousel up to date.
|
||||
@@ -209,41 +209,56 @@ class MediaCarouselController @Inject constructor(
|
||||
oldKey: String?,
|
||||
data: MediaData,
|
||||
immediately: Boolean,
|
||||
isSsReactivated: Boolean
|
||||
receivedSmartspaceCardLatency: Int
|
||||
) {
|
||||
if (addOrUpdatePlayer(key, oldKey, data)) {
|
||||
// Log card received if a new resumable media card is added
|
||||
MediaPlayerData.getMediaPlayer(key)?.let {
|
||||
/* ktlint-disable max-line-length */
|
||||
logSmartspaceCardReported(759, // SMARTSPACE_CARD_RECEIVED
|
||||
it.mInstanceId,
|
||||
it.mUid,
|
||||
/* isRecommendationCard */ false,
|
||||
it.surfaceForSmartspaceLogging,
|
||||
intArrayOf(
|
||||
SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__SHADE,
|
||||
SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__LOCKSCREEN),
|
||||
rank = MediaPlayerData.getMediaPlayerIndex(key))
|
||||
/* ktlint-disable max-line-length */
|
||||
}
|
||||
}
|
||||
if (isSsReactivated) {
|
||||
// If resumable media is reactivated by headphone connection, update instance
|
||||
// id for each card and log a receive event.
|
||||
if (mediaCarouselScrollHandler.visibleToUser &&
|
||||
mediaCarouselScrollHandler.visibleMediaIndex
|
||||
== MediaPlayerData.getMediaPlayerIndex(key)) {
|
||||
logSmartspaceImpression(mediaCarouselScrollHandler.qsExpanded)
|
||||
}
|
||||
} else if (receivedSmartspaceCardLatency != 0) {
|
||||
// Log resume card received if resumable media card is reactivated and
|
||||
// resume card is ranked first
|
||||
MediaPlayerData.players().forEachIndexed { index, it ->
|
||||
if (it.recommendationViewHolder == null) {
|
||||
it.mInstanceId = SmallHash.hash(it.mUid +
|
||||
systemClock.currentTimeMillis().toInt())
|
||||
it.mIsImpressed = false
|
||||
/* ktlint-disable max-line-length */
|
||||
logSmartspaceCardReported(759, // SMARTSPACE_CARD_RECEIVED
|
||||
it.mInstanceId,
|
||||
it.mUid,
|
||||
/* isRecommendationCard */ false,
|
||||
it.surfaceForSmartspaceLogging,
|
||||
rank = index)
|
||||
intArrayOf(
|
||||
SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__SHADE,
|
||||
SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__LOCKSCREEN),
|
||||
rank = index,
|
||||
receivedLatencyMillis = receivedSmartspaceCardLatency)
|
||||
/* ktlint-disable max-line-length */
|
||||
}
|
||||
}
|
||||
// If media container area already visible to the user, log impression for
|
||||
// reactivated card.
|
||||
if (mediaCarouselScrollHandler.visibleToUser &&
|
||||
!mediaCarouselScrollHandler.qsExpanded) {
|
||||
logSmartspaceImpression(mediaCarouselScrollHandler.qsExpanded)
|
||||
}
|
||||
}
|
||||
if (mediaCarouselScrollHandler.visibleToUser &&
|
||||
isSsReactivated && !mediaCarouselScrollHandler.qsExpanded) {
|
||||
// It could happen that reactived media player isn't visible to user because
|
||||
// of it is a resumption card.
|
||||
logSmartspaceImpression(mediaCarouselScrollHandler.qsExpanded)
|
||||
}
|
||||
|
||||
val canRemove = data.isPlaying?.let { !it } ?: data.isClearable && !data.active
|
||||
if (canRemove && !Utils.useMediaResumption(context)) {
|
||||
// This view isn't playing, let's remove this! This happens e.g when
|
||||
@@ -262,28 +277,51 @@ class MediaCarouselController @Inject constructor(
|
||||
override fun onSmartspaceMediaDataLoaded(
|
||||
key: String,
|
||||
data: SmartspaceMediaData,
|
||||
shouldPrioritize: Boolean
|
||||
shouldPrioritize: Boolean,
|
||||
isSsReactivated: Boolean
|
||||
) {
|
||||
if (DEBUG) Log.d(TAG, "Loading Smartspace media update")
|
||||
if (data.isActive) {
|
||||
if (isSsReactivated && shouldPrioritize) {
|
||||
// Log resume card received if resumable media card is reactivated and
|
||||
// recommendation card is valid and ranked first
|
||||
MediaPlayerData.players().forEachIndexed { index, it ->
|
||||
if (it.recommendationViewHolder == null) {
|
||||
it.mInstanceId = SmallHash.hash(it.mUid +
|
||||
systemClock.currentTimeMillis().toInt())
|
||||
it.mIsImpressed = false
|
||||
/* ktlint-disable max-line-length */
|
||||
logSmartspaceCardReported(759, // SMARTSPACE_CARD_RECEIVED
|
||||
it.mInstanceId,
|
||||
it.mUid,
|
||||
/* isRecommendationCard */ false,
|
||||
intArrayOf(
|
||||
SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__SHADE,
|
||||
SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__LOCKSCREEN),
|
||||
rank = index,
|
||||
receivedLatencyMillis = (systemClock.currentTimeMillis() - data.headphoneConnectionTimeMillis).toInt())
|
||||
/* ktlint-disable max-line-length */
|
||||
}
|
||||
}
|
||||
}
|
||||
addSmartspaceMediaRecommendations(key, data, shouldPrioritize)
|
||||
MediaPlayerData.getMediaPlayer(key)?.let {
|
||||
/* ktlint-disable max-line-length */
|
||||
logSmartspaceCardReported(759, // SMARTSPACE_CARD_RECEIVED
|
||||
it.mInstanceId,
|
||||
it.mUid,
|
||||
/* isRecommendationCard */ true,
|
||||
it.surfaceForSmartspaceLogging,
|
||||
rank = MediaPlayerData.getMediaPlayerIndex(key))
|
||||
|
||||
if (mediaCarouselScrollHandler.visibleToUser &&
|
||||
mediaCarouselScrollHandler.visibleMediaIndex ==
|
||||
MediaPlayerData.getMediaPlayerIndex(key)) {
|
||||
logSmartspaceCardReported(800, // SMARTSPACE_CARD_SEEN
|
||||
it.mInstanceId,
|
||||
it.mUid,
|
||||
/* isRecommendationCard */ true,
|
||||
it.surfaceForSmartspaceLogging)
|
||||
}
|
||||
intArrayOf(
|
||||
SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__SHADE,
|
||||
SysUiStatsLog.SMART_SPACE_CARD_REPORTED__DISPLAY_SURFACE__LOCKSCREEN),
|
||||
rank = MediaPlayerData.getMediaPlayerIndex(key),
|
||||
receivedLatencyMillis = (systemClock.currentTimeMillis() - data.headphoneConnectionTimeMillis).toInt())
|
||||
/* ktlint-disable max-line-length */
|
||||
}
|
||||
if (mediaCarouselScrollHandler.visibleToUser &&
|
||||
mediaCarouselScrollHandler.visibleMediaIndex
|
||||
== MediaPlayerData.getMediaPlayerIndex(key)) {
|
||||
logSmartspaceImpression(mediaCarouselScrollHandler.qsExpanded)
|
||||
}
|
||||
} else {
|
||||
onSmartspaceMediaDataRemoved(data.targetId, immediately = true)
|
||||
@@ -718,7 +756,8 @@ class MediaCarouselController @Inject constructor(
|
||||
mediaControlPanel.mInstanceId,
|
||||
mediaControlPanel.mUid,
|
||||
isRecommendationCard,
|
||||
mediaControlPanel.surfaceForSmartspaceLogging)
|
||||
intArrayOf(mediaControlPanel.surfaceForSmartspaceLogging))
|
||||
mediaControlPanel.mIsImpressed = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -731,12 +770,15 @@ class MediaCarouselController @Inject constructor(
|
||||
* 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 surfaces list of display surfaces the media card is on (e.g. lockscreen, shade) when
|
||||
* the event happened
|
||||
* @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
|
||||
* @param receivedLatencyMillis latency in milliseconds for card received events. E.g. latency
|
||||
* between headphone connection to sysUI displays media recommendation card
|
||||
*
|
||||
*/
|
||||
fun logSmartspaceCardReported(
|
||||
@@ -744,10 +786,11 @@ class MediaCarouselController @Inject constructor(
|
||||
instanceId: Int,
|
||||
uid: Int,
|
||||
isRecommendationCard: Boolean,
|
||||
surface: Int,
|
||||
surfaces: IntArray,
|
||||
interactedSubcardRank: Int = 0,
|
||||
interactedSubcardCardinality: Int = 0,
|
||||
rank: Int = mediaCarouselScrollHandler.visibleMediaIndex
|
||||
rank: Int = mediaCarouselScrollHandler.visibleMediaIndex,
|
||||
receivedLatencyMillis: Int = 0
|
||||
) {
|
||||
// Only log media resume card when Smartspace data is available
|
||||
if (!isRecommendationCard &&
|
||||
@@ -756,50 +799,52 @@ class MediaCarouselController @Inject constructor(
|
||||
return
|
||||
}
|
||||
|
||||
/* ktlint-disable max-line-length */
|
||||
SysUiStatsLog.write(SysUiStatsLog.SMARTSPACE_CARD_REPORTED,
|
||||
eventId,
|
||||
instanceId,
|
||||
// Deprecated, replaced with AiAi feature type so we don't need to create logging
|
||||
// card type for each new feature.
|
||||
SysUiStatsLog.SMART_SPACE_CARD_REPORTED__CARD_TYPE__UNKNOWN_CARD,
|
||||
surface,
|
||||
rank,
|
||||
mediaContent.getChildCount(),
|
||||
if (isRecommendationCard)
|
||||
15 // MEDIA_RECOMMENDATION
|
||||
else
|
||||
31, // MEDIA_RESUME
|
||||
uid,
|
||||
interactedSubcardRank,
|
||||
interactedSubcardCardinality,
|
||||
0 // received_latency_millis
|
||||
)
|
||||
/* ktlint-disable max-line-length */
|
||||
val cardinality = mediaContent.getChildCount()
|
||||
surfaces.forEach { surface ->
|
||||
/* ktlint-disable max-line-length */
|
||||
SysUiStatsLog.write(SysUiStatsLog.SMARTSPACE_CARD_REPORTED,
|
||||
eventId,
|
||||
instanceId,
|
||||
// Deprecated, replaced with AiAi feature type so we don't need to create logging
|
||||
// card type for each new feature.
|
||||
SysUiStatsLog.SMART_SPACE_CARD_REPORTED__CARD_TYPE__UNKNOWN_CARD,
|
||||
surface,
|
||||
rank,
|
||||
cardinality,
|
||||
if (isRecommendationCard)
|
||||
15 // MEDIA_RECOMMENDATION
|
||||
else
|
||||
31, // MEDIA_RESUME
|
||||
uid,
|
||||
interactedSubcardRank,
|
||||
interactedSubcardCardinality,
|
||||
receivedLatencyMillis
|
||||
)
|
||||
/* ktlint-disable max-line-length */
|
||||
if (DEBUG) {
|
||||
Log.d(TAG, "Log Smartspace card event id: $eventId instance id: $instanceId" +
|
||||
" surface: $surface rank: $rank cardinality: $cardinality " +
|
||||
"isRecommendationCard: $isRecommendationCard uid: $uid " +
|
||||
"interactedSubcardRank: $interactedSubcardRank " +
|
||||
"interactedSubcardCardinality: $interactedSubcardCardinality " +
|
||||
"received_latency_millis: $receivedLatencyMillis")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun onSwipeToDismiss() {
|
||||
val recommendation = MediaPlayerData.players().filter {
|
||||
it.recommendationViewHolder != null
|
||||
}
|
||||
// Use -1 as rank value to indicate user swipe to dismiss the card
|
||||
if (!recommendation.isEmpty()) {
|
||||
logSmartspaceCardReported(761, // SMARTSPACE_CARD_DISMISS
|
||||
recommendation.get(0).mInstanceId,
|
||||
recommendation.get(0).mUid,
|
||||
true,
|
||||
recommendation.get(0).surfaceForSmartspaceLogging,
|
||||
rank = -1)
|
||||
} else {
|
||||
val visibleMediaIndex = mediaCarouselScrollHandler.visibleMediaIndex
|
||||
if (MediaPlayerData.players().size > visibleMediaIndex) {
|
||||
val player = MediaPlayerData.players().elementAt(visibleMediaIndex)
|
||||
MediaPlayerData.players().forEachIndexed {
|
||||
index, it ->
|
||||
if (it.mIsImpressed) {
|
||||
logSmartspaceCardReported(761, // SMARTSPACE_CARD_DISMISS
|
||||
player.mInstanceId,
|
||||
player.mUid,
|
||||
false,
|
||||
player.surfaceForSmartspaceLogging,
|
||||
it.mInstanceId,
|
||||
it.mUid,
|
||||
it.recommendationViewHolder != null,
|
||||
intArrayOf(it.surfaceForSmartspaceLogging),
|
||||
// Use -1 as rank value to indicate user swipe to dismiss the card
|
||||
rank = -1)
|
||||
// Reset card impressed state when swipe to dismissed
|
||||
it.mIsImpressed = false
|
||||
}
|
||||
}
|
||||
mediaManager.onSwipeToDismiss()
|
||||
|
||||
@@ -59,6 +59,7 @@ import com.android.systemui.plugins.FalsingManager;
|
||||
import com.android.systemui.shared.system.SysUiStatsLog;
|
||||
import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
|
||||
import com.android.systemui.util.animation.TransitionLayout;
|
||||
import com.android.systemui.util.time.SystemClock;
|
||||
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.List;
|
||||
@@ -121,6 +122,9 @@ public class MediaControlPanel {
|
||||
private MediaCarouselController mMediaCarouselController;
|
||||
private final MediaOutputDialogFactory mMediaOutputDialogFactory;
|
||||
private final FalsingManager mFalsingManager;
|
||||
// Used for swipe-to-dismiss logging.
|
||||
protected boolean mIsImpressed = false;
|
||||
private SystemClock mSystemClock;
|
||||
|
||||
/**
|
||||
* Initialize a new control panel
|
||||
@@ -134,7 +138,7 @@ public class MediaControlPanel {
|
||||
SeekBarViewModel seekBarViewModel, Lazy<MediaDataManager> lazyMediaDataManager,
|
||||
KeyguardDismissUtil keyguardDismissUtil, MediaOutputDialogFactory
|
||||
mediaOutputDialogFactory, MediaCarouselController mediaCarouselController,
|
||||
FalsingManager falsingManager) {
|
||||
FalsingManager falsingManager, SystemClock systemClock) {
|
||||
mContext = context;
|
||||
mBackgroundExecutor = backgroundExecutor;
|
||||
mActivityStarter = activityStarter;
|
||||
@@ -145,6 +149,8 @@ public class MediaControlPanel {
|
||||
mMediaOutputDialogFactory = mediaOutputDialogFactory;
|
||||
mMediaCarouselController = mediaCarouselController;
|
||||
mFalsingManager = falsingManager;
|
||||
mSystemClock = systemClock;
|
||||
|
||||
loadDimens();
|
||||
|
||||
mSeekBarViewModel.setLogSmartspaceClick(() -> {
|
||||
@@ -291,7 +297,10 @@ public class MediaControlPanel {
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.e(TAG, "Unable to look up package name", e);
|
||||
}
|
||||
mInstanceId = SmallHash.hash(mUid);
|
||||
// Only assigns instance id if it's unassigned.
|
||||
if (mInstanceId == -1) {
|
||||
mInstanceId = SmallHash.hash(mUid + (int) mSystemClock.currentTimeMillis());
|
||||
}
|
||||
|
||||
mBackgroundColor = data.getBackgroundColor();
|
||||
if (mToken == null || !mToken.equals(token)) {
|
||||
@@ -885,7 +894,7 @@ public class MediaControlPanel {
|
||||
mInstanceId,
|
||||
mUid,
|
||||
isRecommendationCard,
|
||||
getSurfaceForSmartspaceLogging(),
|
||||
new int[]{getSurfaceForSmartspaceLogging()},
|
||||
interactedSubcardRank,
|
||||
interactedSubcardCardinality);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ class MediaDataCombineLatest @Inject constructor() : MediaDataManager.Listener,
|
||||
oldKey: String?,
|
||||
data: MediaData,
|
||||
immediately: Boolean,
|
||||
isSsReactivated: Boolean
|
||||
receivedSmartspaceCardLatency: Int
|
||||
) {
|
||||
if (oldKey != null && oldKey != key && entries.contains(oldKey)) {
|
||||
entries[key] = data to entries.remove(oldKey)?.second
|
||||
@@ -46,7 +46,8 @@ class MediaDataCombineLatest @Inject constructor() : MediaDataManager.Listener,
|
||||
override fun onSmartspaceMediaDataLoaded(
|
||||
key: String,
|
||||
data: SmartspaceMediaData,
|
||||
shouldPrioritize: Boolean
|
||||
shouldPrioritize: Boolean,
|
||||
isSsReactivated: Boolean
|
||||
) {
|
||||
listeners.toSet().forEach { it.onSmartspaceMediaDataLoaded(key, data) }
|
||||
}
|
||||
|
||||
@@ -56,7 +56,6 @@ internal val SMARTSPACE_MAX_AGE = SystemProperties
|
||||
class MediaDataFilter @Inject constructor(
|
||||
private val context: Context,
|
||||
private val broadcastDispatcher: BroadcastDispatcher,
|
||||
private val mediaResumeListener: MediaResumeListener,
|
||||
private val lockscreenUserManager: NotificationLockscreenUserManager,
|
||||
@Main private val executor: Executor,
|
||||
private val systemClock: SystemClock
|
||||
@@ -88,7 +87,7 @@ class MediaDataFilter @Inject constructor(
|
||||
oldKey: String?,
|
||||
data: MediaData,
|
||||
immediately: Boolean,
|
||||
isSsReactivated: Boolean
|
||||
receivedSmartspaceCardLatency: Int
|
||||
) {
|
||||
if (oldKey != null && oldKey != key) {
|
||||
allEntries.remove(oldKey)
|
||||
@@ -106,14 +105,15 @@ class MediaDataFilter @Inject constructor(
|
||||
|
||||
// Notify listeners
|
||||
listeners.forEach {
|
||||
it.onMediaDataLoaded(key, oldKey, data, isSsReactivated = isSsReactivated)
|
||||
it.onMediaDataLoaded(key, oldKey, data)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSmartspaceMediaDataLoaded(
|
||||
key: String,
|
||||
data: SmartspaceMediaData,
|
||||
shouldPrioritize: Boolean
|
||||
shouldPrioritize: Boolean,
|
||||
isSsReactivated: Boolean
|
||||
) {
|
||||
if (!data.isActive) {
|
||||
Log.d(TAG, "Inactive recommendation data. Skip triggering.")
|
||||
@@ -123,8 +123,6 @@ class MediaDataFilter @Inject constructor(
|
||||
// Override the pass-in value here, as the order of Smartspace card is only determined here.
|
||||
var shouldPrioritizeMutable = false
|
||||
smartspaceMediaData = data
|
||||
// Override the pass-in value here, as the Smartspace reactivation could only happen here.
|
||||
var isSsReactivated = false
|
||||
|
||||
// Before forwarding the smartspace target, first check if we have recently inactive media
|
||||
val sorted = userEntries.toSortedMap(compareBy {
|
||||
@@ -139,18 +137,25 @@ class MediaDataFilter @Inject constructor(
|
||||
smartspaceMaxAgeMillis = TimeUnit.SECONDS.toMillis(smartspaceMaxAgeSeconds)
|
||||
}
|
||||
}
|
||||
|
||||
val activeMedia = userEntries.filter { (key, value) -> value.active }
|
||||
var isSsReactivatedMutable = activeMedia.isEmpty() && userEntries.isNotEmpty()
|
||||
|
||||
if (timeSinceActive < smartspaceMaxAgeMillis) {
|
||||
val lastActiveKey = sorted.lastKey() // most recently active
|
||||
// Notify listeners to consider this media active
|
||||
Log.d(TAG, "reactivating $lastActiveKey instead of smartspace")
|
||||
reactivatedKey = lastActiveKey
|
||||
if (MediaPlayerData.firstActiveMediaIndex() == -1) {
|
||||
isSsReactivated = true
|
||||
}
|
||||
val mediaData = sorted.get(lastActiveKey)!!.copy(active = true)
|
||||
listeners.forEach {
|
||||
it.onMediaDataLoaded(lastActiveKey, lastActiveKey, mediaData,
|
||||
isSsReactivated = isSsReactivated)
|
||||
// It could happen there are existing active media resume cards, then we don't need to
|
||||
// reactivate.
|
||||
if (isSsReactivatedMutable) {
|
||||
val lastActiveKey = sorted.lastKey() // most recently active
|
||||
// Notify listeners to consider this media active
|
||||
Log.d(TAG, "reactivating $lastActiveKey instead of smartspace")
|
||||
reactivatedKey = lastActiveKey
|
||||
val mediaData = sorted.get(lastActiveKey)!!.copy(active = true)
|
||||
listeners.forEach {
|
||||
it.onMediaDataLoaded(lastActiveKey, lastActiveKey, mediaData,
|
||||
receivedSmartspaceCardLatency =
|
||||
(systemClock.currentTimeMillis() - data.headphoneConnectionTimeMillis)
|
||||
.toInt())
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Mark to prioritize Smartspace card if no recent media.
|
||||
@@ -161,7 +166,8 @@ class MediaDataFilter @Inject constructor(
|
||||
Log.d(TAG, "Invalid recommendation data. Skip showing the rec card")
|
||||
return
|
||||
}
|
||||
listeners.forEach { it.onSmartspaceMediaDataLoaded(key, data, shouldPrioritizeMutable) }
|
||||
listeners.forEach { it.onSmartspaceMediaDataLoaded(key, data, shouldPrioritizeMutable,
|
||||
isSsReactivatedMutable) }
|
||||
}
|
||||
|
||||
override fun onMediaDataRemoved(key: String) {
|
||||
|
||||
@@ -84,7 +84,7 @@ private val LOADING = MediaData(-1, false, 0, null, null, null, null, null,
|
||||
emptyList(), emptyList(), "INVALID", null, null, null, true, null)
|
||||
@VisibleForTesting
|
||||
internal val EMPTY_SMARTSPACE_MEDIA_DATA = SmartspaceMediaData("INVALID", false, false,
|
||||
"INVALID", null, emptyList(), null, 0)
|
||||
"INVALID", null, emptyList(), null, 0, 0)
|
||||
|
||||
fun isMediaNotification(sbn: StatusBarNotification): Boolean {
|
||||
return sbn.notification.isMediaNotification()
|
||||
@@ -852,15 +852,16 @@ class MediaDataManager(
|
||||
* until the next refresh-round before UI becomes visible. True by default to take in place
|
||||
* immediately.
|
||||
*
|
||||
* @param isSsReactivated indicates transition from a state with no active media players to
|
||||
* a state with active media players upon receiving Smartspace media data.
|
||||
* @param receivedSmartspaceCardLatency is the latency between headphone connects and sysUI
|
||||
* displays Smartspace media targets. Will be 0 if the data is not activated by Smartspace
|
||||
* signal.
|
||||
*/
|
||||
fun onMediaDataLoaded(
|
||||
key: String,
|
||||
oldKey: String?,
|
||||
data: MediaData,
|
||||
immediately: Boolean = true,
|
||||
isSsReactivated: Boolean = false
|
||||
receivedSmartspaceCardLatency: Int = 0
|
||||
) {}
|
||||
|
||||
/**
|
||||
@@ -869,11 +870,15 @@ class MediaDataManager(
|
||||
* @param shouldPrioritize indicates the sorting priority of the Smartspace card. If true,
|
||||
* it will be prioritized as the first card. Otherwise, it will show up as the last card as
|
||||
* default.
|
||||
*
|
||||
* @param isSsReactivated indicates resume media card is reactivated by Smartspace
|
||||
* recommendation signal
|
||||
*/
|
||||
fun onSmartspaceMediaDataLoaded(
|
||||
key: String,
|
||||
data: SmartspaceMediaData,
|
||||
shouldPrioritize: Boolean = false
|
||||
shouldPrioritize: Boolean = false,
|
||||
isSsReactivated: Boolean = false
|
||||
) {}
|
||||
|
||||
/** Called whenever a previously existing Media notification was removed. */
|
||||
@@ -909,12 +914,13 @@ class MediaDataManager(
|
||||
packageName(target)?.let {
|
||||
return SmartspaceMediaData(target.smartspaceTargetId, isActive, true, it,
|
||||
target.baseAction, target.iconGrid,
|
||||
dismissIntent, 0)
|
||||
dismissIntent, 0, target.creationTimeMillis)
|
||||
}
|
||||
return EMPTY_SMARTSPACE_MEDIA_DATA
|
||||
.copy(targetId = target.smartspaceTargetId,
|
||||
isActive = isActive,
|
||||
dismissIntent = dismissIntent)
|
||||
isActive = isActive,
|
||||
dismissIntent = dismissIntent,
|
||||
headphoneConnectionTimeMillis = target.creationTimeMillis)
|
||||
}
|
||||
|
||||
private fun packageName(target: SmartspaceTarget): String? {
|
||||
|
||||
@@ -68,7 +68,7 @@ class MediaDeviceManager @Inject constructor(
|
||||
oldKey: String?,
|
||||
data: MediaData,
|
||||
immediately: Boolean,
|
||||
isSsReactivated: Boolean
|
||||
receivedSmartspaceCardLatency: Int
|
||||
) {
|
||||
if (oldKey != null && oldKey != key) {
|
||||
val oldEntry = entries.remove(oldKey)
|
||||
@@ -200,7 +200,7 @@ class MediaDeviceManager @Inject constructor(
|
||||
@WorkerThread
|
||||
private fun updateCurrent() {
|
||||
val device = localMediaManager.currentConnectedDevice
|
||||
val route = controller?.let { mr2manager.getRoutingSessionForMediaController(it)}
|
||||
val route = controller?.let { mr2manager.getRoutingSessionForMediaController(it) }
|
||||
|
||||
// If we have a controller but get a null route, then don't trust the device
|
||||
val enabled = device != null && (controller == null || route != null)
|
||||
|
||||
@@ -61,7 +61,7 @@ class MediaHost constructor(
|
||||
oldKey: String?,
|
||||
data: MediaData,
|
||||
immediately: Boolean,
|
||||
isSsReactivated: Boolean
|
||||
receivedSmartspaceCardLatency: Int
|
||||
) {
|
||||
if (immediately) {
|
||||
updateViewVisibility()
|
||||
@@ -71,7 +71,8 @@ class MediaHost constructor(
|
||||
override fun onSmartspaceMediaDataLoaded(
|
||||
key: String,
|
||||
data: SmartspaceMediaData,
|
||||
shouldPrioritize: Boolean
|
||||
shouldPrioritize: Boolean,
|
||||
isSsReactivated: Boolean
|
||||
) {
|
||||
updateViewVisibility()
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ class MediaResumeListener @Inject constructor(
|
||||
oldKey: String?,
|
||||
data: MediaData,
|
||||
immediately: Boolean,
|
||||
isSsReactivated: Boolean
|
||||
receivedSmartspaceCardLatency: Int
|
||||
) {
|
||||
if (useMediaResumption) {
|
||||
// If this had been started from a resume state, disconnect now that it's live
|
||||
|
||||
@@ -96,7 +96,7 @@ class MediaSessionBasedFilter @Inject constructor(
|
||||
oldKey: String?,
|
||||
data: MediaData,
|
||||
immediately: Boolean,
|
||||
isSsReactivated: Boolean
|
||||
receivedSmartspaceCardLatency: Int
|
||||
) {
|
||||
backgroundExecutor.execute {
|
||||
data.token?.let {
|
||||
@@ -143,7 +143,8 @@ class MediaSessionBasedFilter @Inject constructor(
|
||||
override fun onSmartspaceMediaDataLoaded(
|
||||
key: String,
|
||||
data: SmartspaceMediaData,
|
||||
shouldPrioritize: Boolean
|
||||
shouldPrioritize: Boolean,
|
||||
isSsReactivated: Boolean
|
||||
) {
|
||||
backgroundExecutor.execute {
|
||||
dispatchSmartspaceMediaDataLoaded(key, data)
|
||||
|
||||
@@ -63,7 +63,7 @@ class MediaTimeoutListener @Inject constructor(
|
||||
oldKey: String?,
|
||||
data: MediaData,
|
||||
immediately: Boolean,
|
||||
isSsReactivated: Boolean
|
||||
receivedSmartspaceCardLatency: Int
|
||||
) {
|
||||
var reusedListener: PlaybackStateListener? = null
|
||||
|
||||
|
||||
@@ -52,5 +52,9 @@ data class SmartspaceMediaData(
|
||||
/**
|
||||
* View's background color.
|
||||
*/
|
||||
val backgroundColor: Int
|
||||
val backgroundColor: Int,
|
||||
/**
|
||||
* The timestamp in milliseconds that headphone is connected.
|
||||
*/
|
||||
val headphoneConnectionTimeMillis: Long
|
||||
)
|
||||
|
||||
@@ -242,12 +242,13 @@ public class NotificationMediaManager implements Dumpable {
|
||||
@Override
|
||||
public void onMediaDataLoaded(@NonNull String key,
|
||||
@Nullable String oldKey, @NonNull MediaData data, boolean immediately,
|
||||
boolean isSsReactivated) {
|
||||
int receivedSmartspaceCardLatency) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSmartspaceMediaDataLoaded(@NonNull String key,
|
||||
@NonNull SmartspaceMediaData data, boolean shouldPrioritize) {
|
||||
@NonNull SmartspaceMediaData data, boolean shouldPrioritize,
|
||||
boolean isSsReactivated) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -316,12 +317,13 @@ public class NotificationMediaManager implements Dumpable {
|
||||
@Override
|
||||
public void onMediaDataLoaded(@NonNull String key,
|
||||
@Nullable String oldKey, @NonNull MediaData data, boolean immediately,
|
||||
boolean isSsReactivated) {
|
||||
int receivedSmartspaceCardLatency) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSmartspaceMediaDataLoaded(@NonNull String key,
|
||||
@NonNull SmartspaceMediaData data, boolean shouldPrioritize) {
|
||||
@NonNull SmartspaceMediaData data, boolean shouldPrioritize,
|
||||
boolean isSsReactivated) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -123,6 +123,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
private lateinit var session: MediaSession
|
||||
private val device = MediaDeviceData(true, null, DEVICE_NAME)
|
||||
private val disabledDevice = MediaDeviceData(false, null, "Disabled Device")
|
||||
private val clock = FakeSystemClock()
|
||||
|
||||
@JvmField @Rule val mockito = MockitoJUnit.rule()
|
||||
|
||||
@@ -134,7 +135,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
|
||||
|
||||
player = MediaControlPanel(context, bgExecutor, activityStarter, mediaViewController,
|
||||
seekBarViewModel, Lazy { mediaDataManager }, keyguardDismissUtil,
|
||||
mediaOutputDialogFactory, mediaCarouselController, falsingManager)
|
||||
mediaOutputDialogFactory, mediaCarouselController, falsingManager, clock)
|
||||
whenever(seekBarViewModel.progress).thenReturn(seekBarData)
|
||||
|
||||
// Mock out a view holder for the player to attach to.
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.android.systemui.media;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.anyBoolean;
|
||||
import static org.mockito.Mockito.eq;
|
||||
@@ -83,10 +84,10 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
|
||||
public void eventNotEmittedWithoutDevice() {
|
||||
// WHEN data source emits an event without device data
|
||||
mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */,
|
||||
false /* isSsReactivated */);
|
||||
0 /* receivedSmartspaceCardLatency */);
|
||||
// THEN an event isn't emitted
|
||||
verify(mListener, never()).onMediaDataLoaded(eq(KEY), any(), any(), anyBoolean(),
|
||||
anyBoolean());
|
||||
anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -95,7 +96,7 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
|
||||
mManager.onMediaDeviceChanged(KEY, null, mDeviceData);
|
||||
// THEN an event isn't emitted
|
||||
verify(mListener, never()).onMediaDataLoaded(eq(KEY), any(), any(), anyBoolean(),
|
||||
anyBoolean());
|
||||
anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -104,11 +105,11 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
|
||||
mManager.onMediaDeviceChanged(KEY, null, mDeviceData);
|
||||
// WHEN media event is received
|
||||
mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */,
|
||||
false /* isSsReactivated */);
|
||||
0 /* receivedSmartspaceCardLatency */);
|
||||
// THEN the listener receives a combined event
|
||||
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
|
||||
verify(mListener).onMediaDataLoaded(eq(KEY), any(), captor.capture(), anyBoolean(),
|
||||
anyBoolean());
|
||||
anyInt());
|
||||
assertThat(captor.getValue().getDevice()).isNotNull();
|
||||
}
|
||||
|
||||
@@ -116,13 +117,13 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
|
||||
public void emitEventAfterMediaFirst() {
|
||||
// GIVEN that media event has already been received
|
||||
mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */,
|
||||
false /* isSsReactivated */);
|
||||
0 /* receivedSmartspaceCardLatency */);
|
||||
// WHEN device event is received
|
||||
mManager.onMediaDeviceChanged(KEY, null, mDeviceData);
|
||||
// THEN the listener receives a combined event
|
||||
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
|
||||
verify(mListener).onMediaDataLoaded(eq(KEY), any(), captor.capture(), anyBoolean(),
|
||||
anyBoolean());
|
||||
anyInt());
|
||||
assertThat(captor.getValue().getDevice()).isNotNull();
|
||||
}
|
||||
|
||||
@@ -130,16 +131,16 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
|
||||
public void migrateKeyMediaFirst() {
|
||||
// GIVEN that media and device info has already been received
|
||||
mManager.onMediaDataLoaded(OLD_KEY, null, mMediaData, true /* immediately */,
|
||||
false /* isSsReactivated */);
|
||||
0 /* receivedSmartspaceCardLatency */);
|
||||
mManager.onMediaDeviceChanged(OLD_KEY, null, mDeviceData);
|
||||
reset(mListener);
|
||||
// WHEN a key migration event is received
|
||||
mManager.onMediaDataLoaded(KEY, OLD_KEY, mMediaData, true /* immediately */,
|
||||
false /* isSsReactivated */);
|
||||
0 /* receivedSmartspaceCardLatency */);
|
||||
// THEN the listener receives a combined event
|
||||
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
|
||||
verify(mListener).onMediaDataLoaded(eq(KEY), eq(OLD_KEY), captor.capture(), anyBoolean(),
|
||||
anyBoolean());
|
||||
anyInt());
|
||||
assertThat(captor.getValue().getDevice()).isNotNull();
|
||||
}
|
||||
|
||||
@@ -147,7 +148,7 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
|
||||
public void migrateKeyDeviceFirst() {
|
||||
// GIVEN that media and device info has already been received
|
||||
mManager.onMediaDataLoaded(OLD_KEY, null, mMediaData, true /* immediately */,
|
||||
false /* isSsReactivated */);
|
||||
0 /* receivedSmartspaceCardLatency */);
|
||||
mManager.onMediaDeviceChanged(OLD_KEY, null, mDeviceData);
|
||||
reset(mListener);
|
||||
// WHEN a key migration event is received
|
||||
@@ -155,7 +156,7 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
|
||||
// THEN the listener receives a combined event
|
||||
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
|
||||
verify(mListener).onMediaDataLoaded(eq(KEY), eq(OLD_KEY), captor.capture(), anyBoolean(),
|
||||
anyBoolean());
|
||||
anyInt());
|
||||
assertThat(captor.getValue().getDevice()).isNotNull();
|
||||
}
|
||||
|
||||
@@ -163,17 +164,17 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
|
||||
public void migrateKeyMediaAfter() {
|
||||
// GIVEN that media and device info has already been received
|
||||
mManager.onMediaDataLoaded(OLD_KEY, null, mMediaData, true /* immediately */,
|
||||
false /* isSsReactivated */);
|
||||
0 /* receivedSmartspaceCardLatency */);
|
||||
mManager.onMediaDeviceChanged(OLD_KEY, null, mDeviceData);
|
||||
mManager.onMediaDeviceChanged(KEY, OLD_KEY, mDeviceData);
|
||||
reset(mListener);
|
||||
// WHEN a second key migration event is received for media
|
||||
mManager.onMediaDataLoaded(KEY, OLD_KEY, mMediaData, true /* immediately */,
|
||||
false /* isSsReactivated */);
|
||||
0 /* receivedSmartspaceCardLatency */);
|
||||
// THEN the key has already been migrated
|
||||
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
|
||||
verify(mListener).onMediaDataLoaded(eq(KEY), eq(KEY), captor.capture(), anyBoolean(),
|
||||
anyBoolean());
|
||||
anyInt());
|
||||
assertThat(captor.getValue().getDevice()).isNotNull();
|
||||
}
|
||||
|
||||
@@ -181,17 +182,17 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
|
||||
public void migrateKeyDeviceAfter() {
|
||||
// GIVEN that media and device info has already been received
|
||||
mManager.onMediaDataLoaded(OLD_KEY, null, mMediaData, true /* immediately */,
|
||||
false /* isSsReactivated */);
|
||||
0 /* receivedSmartspaceCardLatency */);
|
||||
mManager.onMediaDeviceChanged(OLD_KEY, null, mDeviceData);
|
||||
mManager.onMediaDataLoaded(KEY, OLD_KEY, mMediaData, true /* immediately */,
|
||||
false /* isSsReactivated */);
|
||||
0 /* receivedSmartspaceCardLatency */);
|
||||
reset(mListener);
|
||||
// WHEN a second key migration event is received for the device
|
||||
mManager.onMediaDeviceChanged(KEY, OLD_KEY, mDeviceData);
|
||||
// THEN the key has already be migrated
|
||||
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
|
||||
verify(mListener).onMediaDataLoaded(eq(KEY), eq(KEY), captor.capture(), anyBoolean(),
|
||||
anyBoolean());
|
||||
anyInt());
|
||||
assertThat(captor.getValue().getDevice()).isNotNull();
|
||||
}
|
||||
|
||||
@@ -206,7 +207,7 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void mediaDataRemovedAfterMediaEvent() {
|
||||
mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */,
|
||||
false /* isSsReactivated */);
|
||||
0 /* receivedSmartspaceCardLatency */);
|
||||
mManager.onMediaDataRemoved(KEY);
|
||||
verify(mListener).onMediaDataRemoved(eq(KEY));
|
||||
}
|
||||
@@ -222,14 +223,14 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
|
||||
public void mediaDataKeyUpdated() {
|
||||
// GIVEN that device and media events have already been received
|
||||
mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */,
|
||||
false /* isSsReactivated */);
|
||||
0 /* receivedSmartspaceCardLatency */);
|
||||
mManager.onMediaDeviceChanged(KEY, null, mDeviceData);
|
||||
// WHEN the key is changed
|
||||
mManager.onMediaDataLoaded("NEW_KEY", KEY, mMediaData, true /* immediately */,
|
||||
false /* isSsReactivated */);
|
||||
0 /* receivedSmartspaceCardLatency */);
|
||||
// THEN the listener gets a load event with the correct keys
|
||||
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
|
||||
verify(mListener).onMediaDataLoaded(
|
||||
eq("NEW_KEY"), any(), captor.capture(), anyBoolean(), anyBoolean());
|
||||
eq("NEW_KEY"), any(), captor.capture(), anyBoolean(), anyInt());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ class MediaDataFilterTest : SysuiTestCase() {
|
||||
fun setup() {
|
||||
MockitoAnnotations.initMocks(this)
|
||||
MediaPlayerData.clear()
|
||||
mediaDataFilter = MediaDataFilter(context, broadcastDispatcher, mediaResumeListener,
|
||||
mediaDataFilter = MediaDataFilter(context, broadcastDispatcher,
|
||||
lockscreenUserManager, executor, clock)
|
||||
mediaDataFilter.mediaDataManager = mediaDataManager
|
||||
mediaDataFilter.addListener(listener)
|
||||
@@ -107,6 +107,8 @@ class MediaDataFilterTest : SysuiTestCase() {
|
||||
`when`(smartspaceData.isValid).thenReturn(true)
|
||||
`when`(smartspaceData.packageName).thenReturn(PACKAGE)
|
||||
`when`(smartspaceData.recommendations).thenReturn(listOf(smartspaceMediaRecommendationItem))
|
||||
`when`(smartspaceData.headphoneConnectionTimeMillis).thenReturn(
|
||||
clock.currentTimeMillis() - 100)
|
||||
}
|
||||
|
||||
private fun setUser(id: Int) {
|
||||
@@ -122,7 +124,7 @@ class MediaDataFilterTest : SysuiTestCase() {
|
||||
|
||||
// THEN we should tell the listener
|
||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataMain), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -131,7 +133,7 @@ class MediaDataFilterTest : SysuiTestCase() {
|
||||
mediaDataFilter.onMediaDataLoaded(KEY, null, dataGuest)
|
||||
|
||||
// THEN we should NOT tell the listener
|
||||
verify(listener, never()).onMediaDataLoaded(any(), any(), any(), anyBoolean(), anyBoolean())
|
||||
verify(listener, never()).onMediaDataLoaded(any(), any(), any(), anyBoolean(), anyInt())
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -178,11 +180,11 @@ class MediaDataFilterTest : SysuiTestCase() {
|
||||
|
||||
// THEN we should add back the guest user media
|
||||
verify(listener).onMediaDataLoaded(eq(KEY_ALT), eq(null), eq(dataGuest), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
|
||||
// but not the main user's
|
||||
verify(listener, never()).onMediaDataLoaded(eq(KEY), any(), eq(dataMain), anyBoolean(),
|
||||
anyBoolean())
|
||||
anyInt())
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -239,7 +241,8 @@ class MediaDataFilterTest : SysuiTestCase() {
|
||||
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
|
||||
|
||||
verify(listener)
|
||||
.onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(true))
|
||||
.onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(true),
|
||||
eq(false))
|
||||
assertThat(mediaDataFilter.hasActiveMedia()).isTrue()
|
||||
}
|
||||
|
||||
@@ -249,8 +252,9 @@ class MediaDataFilterTest : SysuiTestCase() {
|
||||
|
||||
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
|
||||
|
||||
verify(listener, never()).onMediaDataLoaded(any(), any(), any(), anyBoolean(), anyBoolean())
|
||||
verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
|
||||
verify(listener, never()).onMediaDataLoaded(any(), any(), any(), anyBoolean(), anyInt())
|
||||
verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean(),
|
||||
anyBoolean())
|
||||
assertThat(mediaDataFilter.hasActiveMedia()).isFalse()
|
||||
}
|
||||
|
||||
@@ -262,7 +266,8 @@ class MediaDataFilterTest : SysuiTestCase() {
|
||||
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
|
||||
|
||||
verify(listener)
|
||||
.onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(true))
|
||||
.onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(true),
|
||||
eq(true))
|
||||
assertThat(mediaDataFilter.hasActiveMedia()).isTrue()
|
||||
}
|
||||
|
||||
@@ -275,7 +280,8 @@ class MediaDataFilterTest : SysuiTestCase() {
|
||||
clock.advanceTime(SMARTSPACE_MAX_AGE + 100)
|
||||
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
|
||||
|
||||
verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
|
||||
verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean(),
|
||||
anyBoolean())
|
||||
assertThat(mediaDataFilter.hasActiveMedia()).isFalse()
|
||||
}
|
||||
|
||||
@@ -287,15 +293,16 @@ class MediaDataFilterTest : SysuiTestCase() {
|
||||
val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
|
||||
mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
|
||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
|
||||
// AND we get a smartspace signal
|
||||
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
|
||||
|
||||
// THEN we should tell listeners to treat the media as not active instead
|
||||
verify(listener, never()).onMediaDataLoaded(eq(KEY), eq(KEY), any(), anyBoolean(),
|
||||
anyInt())
|
||||
verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean(),
|
||||
anyBoolean())
|
||||
verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
|
||||
assertThat(mediaDataFilter.hasActiveMedia()).isFalse()
|
||||
}
|
||||
|
||||
@@ -307,7 +314,7 @@ class MediaDataFilterTest : SysuiTestCase() {
|
||||
val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
|
||||
mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
|
||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
|
||||
// AND we get a smartspace signal
|
||||
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
|
||||
@@ -315,10 +322,11 @@ class MediaDataFilterTest : SysuiTestCase() {
|
||||
// THEN we should tell listeners to treat the media as active instead
|
||||
val dataCurrentAndActive = dataCurrent.copy(active = true)
|
||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY), eq(dataCurrentAndActive), eq(true),
|
||||
eq(true))
|
||||
eq(100))
|
||||
assertThat(mediaDataFilter.hasActiveMedia()).isTrue()
|
||||
// Smartspace update shouldn't be propagated for the empty rec list.
|
||||
verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
|
||||
verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean(),
|
||||
anyBoolean())
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -327,7 +335,7 @@ class MediaDataFilterTest : SysuiTestCase() {
|
||||
val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
|
||||
mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
|
||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
|
||||
// AND we get a smartspace signal
|
||||
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
|
||||
@@ -335,11 +343,12 @@ class MediaDataFilterTest : SysuiTestCase() {
|
||||
// THEN we should tell listeners to treat the media as active instead
|
||||
val dataCurrentAndActive = dataCurrent.copy(active = true)
|
||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY), eq(dataCurrentAndActive), eq(true),
|
||||
eq(true))
|
||||
eq(100))
|
||||
assertThat(mediaDataFilter.hasActiveMedia()).isTrue()
|
||||
// Smartspace update should also be propagated but not prioritized.
|
||||
verify(listener)
|
||||
.onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false))
|
||||
.onSmartspaceMediaDataLoaded(eq(SMARTSPACE_KEY), eq(smartspaceData), eq(false),
|
||||
eq(true))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -356,13 +365,13 @@ class MediaDataFilterTest : SysuiTestCase() {
|
||||
val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
|
||||
mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
|
||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
|
||||
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
|
||||
|
||||
val dataCurrentAndActive = dataCurrent.copy(active = true)
|
||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY), eq(dataCurrentAndActive), eq(true),
|
||||
eq(true))
|
||||
eq(100))
|
||||
|
||||
mediaDataFilter.onSmartspaceMediaDataRemoved(SMARTSPACE_KEY)
|
||||
|
||||
|
||||
@@ -160,6 +160,7 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
whenever(mediaSmartspaceTarget.smartspaceTargetId).thenReturn(KEY_MEDIA_SMARTSPACE)
|
||||
whenever(mediaSmartspaceTarget.featureType).thenReturn(SmartspaceTarget.FEATURE_MEDIA)
|
||||
whenever(mediaSmartspaceTarget.iconGrid).thenReturn(listOf(mediaRecommendationItem))
|
||||
whenever(mediaSmartspaceTarget.creationTimeMillis).thenReturn(1234L)
|
||||
}
|
||||
|
||||
@After
|
||||
@@ -213,7 +214,7 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
mediaDataManager.onNotificationAdded(KEY, mediaNotification)
|
||||
mediaDataManager.onMediaDataLoaded(KEY, oldKey = null, data = mock(MediaData::class.java))
|
||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), anyObject(), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -225,7 +226,7 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
|
||||
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
|
||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
assertThat(mediaDataCaptor.value!!.active).isTrue()
|
||||
}
|
||||
|
||||
@@ -248,7 +249,7 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
|
||||
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
|
||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
assertThat(mediaDataCaptor.value!!.playbackLocation).isEqualTo(
|
||||
MediaData.PLAYBACK_CAST_REMOTE)
|
||||
}
|
||||
@@ -269,7 +270,7 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
|
||||
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
|
||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
val data = mediaDataCaptor.value
|
||||
assertThat(data.resumption).isFalse()
|
||||
mediaDataManager.onMediaDataLoaded(KEY, null, data.copy(resumeAction = Runnable {}))
|
||||
@@ -278,7 +279,7 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
// THEN the media data indicates that it is for resumption
|
||||
verify(listener)
|
||||
.onMediaDataLoaded(eq(PACKAGE_NAME), eq(KEY), capture(mediaDataCaptor), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
assertThat(mediaDataCaptor.value.resumption).isTrue()
|
||||
assertThat(mediaDataCaptor.value.isPlaying).isFalse()
|
||||
}
|
||||
@@ -293,7 +294,7 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
assertThat(foregroundExecutor.runAllReady()).isEqualTo(2)
|
||||
verify(listener)
|
||||
.onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
val data = mediaDataCaptor.value
|
||||
assertThat(data.resumption).isFalse()
|
||||
val resumableData = data.copy(resumeAction = Runnable {})
|
||||
@@ -305,7 +306,7 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
// THEN the data is for resumption and the key is migrated to the package name
|
||||
verify(listener)
|
||||
.onMediaDataLoaded(eq(PACKAGE_NAME), eq(KEY), capture(mediaDataCaptor), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
assertThat(mediaDataCaptor.value.resumption).isTrue()
|
||||
verify(listener, never()).onMediaDataRemoved(eq(KEY))
|
||||
// WHEN the second is removed
|
||||
@@ -314,7 +315,7 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
verify(listener)
|
||||
.onMediaDataLoaded(
|
||||
eq(PACKAGE_NAME), eq(PACKAGE_NAME), capture(mediaDataCaptor), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
assertThat(mediaDataCaptor.value.resumption).isTrue()
|
||||
verify(listener).onMediaDataRemoved(eq(KEY_2))
|
||||
}
|
||||
@@ -329,7 +330,7 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
|
||||
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
|
||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
val data = mediaDataCaptor.value
|
||||
val dataRemoteWithResume = data.copy(resumeAction = Runnable {},
|
||||
playbackLocation = MediaData.PLAYBACK_CAST_LOCAL)
|
||||
@@ -357,7 +358,7 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
// THEN the media data indicates that it is for resumption
|
||||
verify(listener)
|
||||
.onMediaDataLoaded(eq(PACKAGE_NAME), eq(null), capture(mediaDataCaptor), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
val data = mediaDataCaptor.value
|
||||
assertThat(data.resumption).isTrue()
|
||||
assertThat(data.song).isEqualTo(SESSION_TITLE)
|
||||
@@ -405,7 +406,7 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
|
||||
verify(listener)
|
||||
.onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -415,8 +416,8 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
eq(KEY_MEDIA_SMARTSPACE),
|
||||
eq(SmartspaceMediaData(KEY_MEDIA_SMARTSPACE, true /* isActive */, true /*isValid */,
|
||||
PACKAGE_NAME, mediaSmartspaceBaseAction, listOf(mediaRecommendationItem),
|
||||
DISMISS_INTENT, 0)),
|
||||
eq(false))
|
||||
DISMISS_INTENT, 0, 1234L)),
|
||||
eq(false), eq(false))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -427,8 +428,9 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
eq(KEY_MEDIA_SMARTSPACE),
|
||||
eq(EMPTY_SMARTSPACE_MEDIA_DATA
|
||||
.copy(targetId = KEY_MEDIA_SMARTSPACE, isActive = true,
|
||||
isValid = false, dismissIntent = DISMISS_INTENT)),
|
||||
eq(false))
|
||||
isValid = false, dismissIntent = DISMISS_INTENT,
|
||||
headphoneConnectionTimeMillis = 1234L)),
|
||||
eq(false), eq(false))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -447,15 +449,15 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
eq(KEY_MEDIA_SMARTSPACE),
|
||||
eq(EMPTY_SMARTSPACE_MEDIA_DATA
|
||||
.copy(targetId = KEY_MEDIA_SMARTSPACE, isActive = true,
|
||||
isValid = false, dismissIntent = null)),
|
||||
eq(false))
|
||||
isValid = false, dismissIntent = null, headphoneConnectionTimeMillis = 1234L)),
|
||||
eq(false), eq(false))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnSmartspaceMediaDataLoaded_hasNoneMediaTarget_notCallsListener() {
|
||||
smartspaceMediaDataProvider.onTargetsAvailable(listOf())
|
||||
verify(listener, never())
|
||||
.onSmartspaceMediaDataLoaded(anyObject(), anyObject(), anyBoolean())
|
||||
.onSmartspaceMediaDataLoaded(anyObject(), anyObject(), anyBoolean(), anyBoolean())
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -479,7 +481,7 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
|
||||
// THEN smartspace signal is ignored
|
||||
verify(listener, never())
|
||||
.onSmartspaceMediaDataLoaded(anyObject(), anyObject(), anyBoolean())
|
||||
.onSmartspaceMediaDataLoaded(anyObject(), anyObject(), anyBoolean(), anyBoolean())
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -487,7 +489,7 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
// GIVEN a media recommendation card is present
|
||||
smartspaceMediaDataProvider.onTargetsAvailable(listOf(mediaSmartspaceTarget))
|
||||
verify(listener).onSmartspaceMediaDataLoaded(eq(KEY_MEDIA_SMARTSPACE), anyObject(),
|
||||
anyBoolean())
|
||||
anyBoolean(), anyBoolean())
|
||||
|
||||
// WHEN the media recommendation setting is turned off
|
||||
Settings.Secure.putInt(context.contentResolver,
|
||||
@@ -507,7 +509,7 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
|
||||
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
|
||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
assertThat(mediaDataCaptor.value!!.lastActive).isAtLeast(currentTime)
|
||||
}
|
||||
|
||||
@@ -525,7 +527,7 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
|
||||
// THEN the last active time is not changed
|
||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY), capture(mediaDataCaptor), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
assertThat(mediaDataCaptor.value.lastActive).isLessThan(currentTime)
|
||||
}
|
||||
|
||||
@@ -537,7 +539,7 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
|
||||
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
|
||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
val data = mediaDataCaptor.value
|
||||
assertThat(data.resumption).isFalse()
|
||||
mediaDataManager.onMediaDataLoaded(KEY, null, data.copy(resumeAction = Runnable {}))
|
||||
@@ -550,7 +552,7 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
// THEN the last active time is not changed
|
||||
verify(listener)
|
||||
.onMediaDataLoaded(eq(PACKAGE_NAME), eq(KEY), capture(mediaDataCaptor), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
assertThat(mediaDataCaptor.value.resumption).isTrue()
|
||||
assertThat(mediaDataCaptor.value.lastActive).isLessThan(currentTime)
|
||||
}
|
||||
@@ -577,7 +579,7 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
|
||||
// THEN only the first MAX_COMPACT_ACTIONS are actually set
|
||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
assertThat(mediaDataCaptor.value.actionsToShowInCompact.size).isEqualTo(
|
||||
MediaDataManager.MAX_COMPACT_ACTIONS)
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.ArgumentCaptor
|
||||
import org.mockito.ArgumentMatchers.anyBoolean
|
||||
import org.mockito.ArgumentMatchers.anyInt
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito
|
||||
import org.mockito.Mockito.any
|
||||
@@ -186,7 +187,7 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
|
||||
bgExecutor.runAllReady()
|
||||
fgExecutor.runAllReady()
|
||||
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -209,7 +210,7 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
|
||||
fgExecutor.runAllReady()
|
||||
// THEN the event is not filtered
|
||||
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -239,7 +240,7 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
|
||||
fgExecutor.runAllReady()
|
||||
// THEN the event is not filtered
|
||||
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -255,14 +256,14 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
|
||||
fgExecutor.runAllReady()
|
||||
// THEN the event is not filtered
|
||||
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
// WHEN a loaded event is received that matches the local session
|
||||
filter.onMediaDataLoaded(KEY, null, mediaData2)
|
||||
bgExecutor.runAllReady()
|
||||
fgExecutor.runAllReady()
|
||||
// THEN the event is filtered
|
||||
verify(mediaListener, never()).onMediaDataLoaded(
|
||||
eq(KEY), eq(null), eq(mediaData2), anyBoolean(), anyBoolean())
|
||||
eq(KEY), eq(null), eq(mediaData2), anyBoolean(), anyInt())
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -279,7 +280,7 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
|
||||
// THEN the event is not filtered because there isn't a notification for the remote
|
||||
// session.
|
||||
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -297,14 +298,14 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
|
||||
fgExecutor.runAllReady()
|
||||
// THEN the event is not filtered
|
||||
verify(mediaListener).onMediaDataLoaded(eq(key1), eq(null), eq(mediaData1), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
// WHEN a loaded event is received that matches the local session
|
||||
filter.onMediaDataLoaded(key2, null, mediaData2)
|
||||
bgExecutor.runAllReady()
|
||||
fgExecutor.runAllReady()
|
||||
// THEN the event is filtered
|
||||
verify(mediaListener, never())
|
||||
.onMediaDataLoaded(eq(key2), eq(null), eq(mediaData2), anyBoolean(), anyBoolean())
|
||||
.onMediaDataLoaded(eq(key2), eq(null), eq(mediaData2), anyBoolean(), anyInt())
|
||||
// AND there should be a removed event for key2
|
||||
verify(mediaListener).onMediaDataRemoved(eq(key2))
|
||||
}
|
||||
@@ -324,14 +325,14 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
|
||||
fgExecutor.runAllReady()
|
||||
// THEN the event is not filtered
|
||||
verify(mediaListener).onMediaDataLoaded(eq(key1), eq(null), eq(mediaData1), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
// WHEN a loaded event is received that matches the remote session
|
||||
filter.onMediaDataLoaded(key2, null, mediaData2)
|
||||
bgExecutor.runAllReady()
|
||||
fgExecutor.runAllReady()
|
||||
// THEN the event is not filtered
|
||||
verify(mediaListener).onMediaDataLoaded(eq(key2), eq(null), eq(mediaData2), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -348,14 +349,14 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
|
||||
fgExecutor.runAllReady()
|
||||
// THEN the event is not filtered
|
||||
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
// WHEN a loaded event is received that matches the local session
|
||||
filter.onMediaDataLoaded(KEY, null, mediaData2)
|
||||
bgExecutor.runAllReady()
|
||||
fgExecutor.runAllReady()
|
||||
// THEN the event is not filtered
|
||||
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData2), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -374,7 +375,7 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
|
||||
fgExecutor.runAllReady()
|
||||
// THEN the event is not filtered
|
||||
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -397,7 +398,7 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
|
||||
fgExecutor.runAllReady()
|
||||
// THEN the key migration event is fired
|
||||
verify(mediaListener).onMediaDataLoaded(eq(key2), eq(key1), eq(mediaData2), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -427,13 +428,13 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
|
||||
fgExecutor.runAllReady()
|
||||
// THEN the key migration event is filtered
|
||||
verify(mediaListener, never())
|
||||
.onMediaDataLoaded(eq(key2), eq(null), eq(mediaData2), anyBoolean(), anyBoolean())
|
||||
.onMediaDataLoaded(eq(key2), eq(null), eq(mediaData2), anyBoolean(), anyInt())
|
||||
// WHEN a loaded event is received that matches the remote session
|
||||
filter.onMediaDataLoaded(key2, null, mediaData1)
|
||||
bgExecutor.runAllReady()
|
||||
fgExecutor.runAllReady()
|
||||
// THEN the key migration event is fired
|
||||
verify(mediaListener).onMediaDataLoaded(eq(key2), eq(null), eq(mediaData1), eq(true),
|
||||
eq(false))
|
||||
eq(0))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user