Merge "Media impression logging bug fix" into sc-dev am: b247011e66
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14728374 Change-Id: Ice6737a1073077981a1a48e96a0601a4eac8c288
This commit is contained in:
@@ -156,6 +156,12 @@ class MediaCarouselController @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update MediaCarouselScrollHandler.visibleToUser to reflect media card container visibility.
|
||||||
|
* It will be called when the container is out of view.
|
||||||
|
*/
|
||||||
|
lateinit var updateUserVisibility: () -> Unit
|
||||||
|
|
||||||
init {
|
init {
|
||||||
mediaFrame = inflateMediaCarousel()
|
mediaFrame = inflateMediaCarousel()
|
||||||
mediaCarousel = mediaFrame.requireViewById(R.id.media_carousel_scroller)
|
mediaCarousel = mediaFrame.requireViewById(R.id.media_carousel_scroller)
|
||||||
@@ -177,6 +183,12 @@ class MediaCarouselController @Inject constructor(
|
|||||||
keysNeedRemoval.forEach { removePlayer(it) }
|
keysNeedRemoval.forEach { removePlayer(it) }
|
||||||
keysNeedRemoval.clear()
|
keysNeedRemoval.clear()
|
||||||
|
|
||||||
|
// Update user visibility so that no extra impression will be logged when
|
||||||
|
// activeMediaIndex resets to 0
|
||||||
|
if (this::updateUserVisibility.isInitialized) {
|
||||||
|
updateUserVisibility()
|
||||||
|
}
|
||||||
|
|
||||||
// Let's reset our scroll position
|
// Let's reset our scroll position
|
||||||
mediaCarouselScrollHandler.scrollToStart()
|
mediaCarouselScrollHandler.scrollToStart()
|
||||||
}
|
}
|
||||||
@@ -187,16 +199,24 @@ class MediaCarouselController @Inject constructor(
|
|||||||
key: String,
|
key: String,
|
||||||
oldKey: String?,
|
oldKey: String?,
|
||||||
data: MediaData,
|
data: MediaData,
|
||||||
immediately: Boolean
|
immediately: Boolean,
|
||||||
|
isSsReactivated: Boolean
|
||||||
) {
|
) {
|
||||||
if (addOrUpdatePlayer(key, oldKey, data)) {
|
if (addOrUpdatePlayer(key, oldKey, data)) {
|
||||||
MediaPlayerData.getMediaPlayer(key, null)?.let {
|
MediaPlayerData.getMediaPlayer(key, null)?.let {
|
||||||
logSmartspaceCardReported(759, // SMARTSPACE_CARD_RECEIVED
|
logSmartspaceCardReported(759, // SMARTSPACE_CARD_RECEIVED
|
||||||
it.mInstanceId,
|
it.mInstanceId,
|
||||||
/* isRecommendationCard */ false,
|
/* isRecommendationCard */ false,
|
||||||
it.surfaceForSmartspaceLogging)
|
it.surfaceForSmartspaceLogging,
|
||||||
|
rank = MediaPlayerData.getMediaPlayerIndex(key))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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
|
val canRemove = data.isPlaying?.let { !it } ?: data.isClearable && !data.active
|
||||||
if (canRemove && !Utils.useMediaResumption(context)) {
|
if (canRemove && !Utils.useMediaResumption(context)) {
|
||||||
// This view isn't playing, let's remove this! This happens e.g when
|
// This view isn't playing, let's remove this! This happens e.g when
|
||||||
@@ -222,12 +242,19 @@ class MediaCarouselController @Inject constructor(
|
|||||||
addSmartspaceMediaRecommendations(key, data, shouldPrioritize)
|
addSmartspaceMediaRecommendations(key, data, shouldPrioritize)
|
||||||
MediaPlayerData.getMediaPlayer(key, null)?.let {
|
MediaPlayerData.getMediaPlayer(key, null)?.let {
|
||||||
logSmartspaceCardReported(759, // SMARTSPACE_CARD_RECEIVED
|
logSmartspaceCardReported(759, // SMARTSPACE_CARD_RECEIVED
|
||||||
|
it.mInstanceId,
|
||||||
|
/* isRecommendationCard */ true,
|
||||||
|
it.surfaceForSmartspaceLogging,
|
||||||
|
rank = MediaPlayerData.getMediaPlayerIndex(key))
|
||||||
|
|
||||||
|
if (mediaCarouselScrollHandler.visibleToUser &&
|
||||||
|
mediaCarouselScrollHandler.visibleMediaIndex ==
|
||||||
|
MediaPlayerData.getMediaPlayerIndex(key)) {
|
||||||
|
logSmartspaceCardReported(800, // SMARTSPACE_CARD_SEEN
|
||||||
it.mInstanceId,
|
it.mInstanceId,
|
||||||
/* isRecommendationCard */ true,
|
/* isRecommendationCard */ true,
|
||||||
it.surfaceForSmartspaceLogging)
|
it.surfaceForSmartspaceLogging)
|
||||||
}
|
}
|
||||||
if (mediaCarouselScrollHandler.visibleToUser) {
|
|
||||||
logSmartspaceImpression()
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
onSmartspaceMediaDataRemoved(data.targetId, immediately = true)
|
onSmartspaceMediaDataRemoved(data.targetId, immediately = true)
|
||||||
@@ -644,17 +671,17 @@ class MediaCarouselController @Inject constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Log the user impression for media card.
|
* Log the user impression for media card at visibleMediaIndex.
|
||||||
*/
|
*/
|
||||||
fun logSmartspaceImpression() {
|
fun logSmartspaceImpression(qsExpanded: Boolean) {
|
||||||
val visibleMediaIndex = mediaCarouselScrollHandler.visibleMediaIndex
|
val visibleMediaIndex = mediaCarouselScrollHandler.visibleMediaIndex
|
||||||
if (MediaPlayerData.players().size > visibleMediaIndex) {
|
if (MediaPlayerData.players().size > visibleMediaIndex) {
|
||||||
val mediaControlPanel = MediaPlayerData.players().elementAt(visibleMediaIndex)
|
val mediaControlPanel = MediaPlayerData.players().elementAt(visibleMediaIndex)
|
||||||
val isMediaActive =
|
val hasActiveMediaOrRecommendationCard =
|
||||||
MediaPlayerData.playerKeys().elementAt(visibleMediaIndex).data?.active
|
MediaPlayerData.hasActiveMediaOrRecommendationCard()
|
||||||
val isRecommendationCard = mediaControlPanel.recommendationViewHolder != null
|
val isRecommendationCard = mediaControlPanel.recommendationViewHolder != null
|
||||||
if (!isRecommendationCard && !isMediaActive) {
|
if (!hasActiveMediaOrRecommendationCard && !qsExpanded) {
|
||||||
// Media control card time out or swiped away
|
// Skip logging if on LS or QQS, and there is no active media card
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
logSmartspaceCardReported(800, // SMARTSPACE_CARD_SEEN
|
logSmartspaceCardReported(800, // SMARTSPACE_CARD_SEEN
|
||||||
@@ -672,6 +699,13 @@ class MediaCarouselController @Inject constructor(
|
|||||||
surface: Int,
|
surface: Int,
|
||||||
rank: Int = mediaCarouselScrollHandler.visibleMediaIndex
|
rank: Int = mediaCarouselScrollHandler.visibleMediaIndex
|
||||||
) {
|
) {
|
||||||
|
// Only log media resume card when Smartspace data is available
|
||||||
|
if (!isRecommendationCard &&
|
||||||
|
!mediaManager.smartspaceMediaData.isActive &&
|
||||||
|
MediaPlayerData.smartspaceMediaData == null) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
/* ktlint-disable max-line-length */
|
/* ktlint-disable max-line-length */
|
||||||
SysUiStatsLog.write(SysUiStatsLog.SMARTSPACE_CARD_REPORTED,
|
SysUiStatsLog.write(SysUiStatsLog.SMARTSPACE_CARD_REPORTED,
|
||||||
eventId,
|
eventId,
|
||||||
@@ -770,6 +804,16 @@ internal object MediaPlayerData {
|
|||||||
return mediaData.get(key)?.let { mediaPlayers.get(it) }
|
return mediaData.get(key)?.let { mediaPlayers.get(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getMediaPlayerIndex(key: String): Int {
|
||||||
|
val sortKey = mediaData.get(key)
|
||||||
|
mediaPlayers.entries.forEachIndexed { index, e ->
|
||||||
|
if (e.key == sortKey) {
|
||||||
|
return index
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
fun removeMediaPlayer(key: String) = mediaData.remove(key)?.let {
|
fun removeMediaPlayer(key: String) = mediaData.remove(key)?.let {
|
||||||
if (it.isSsMediaRec) {
|
if (it.isSsMediaRec) {
|
||||||
smartspaceMediaData = null
|
smartspaceMediaData = null
|
||||||
@@ -808,4 +852,15 @@ internal object MediaPlayerData {
|
|||||||
mediaData.clear()
|
mediaData.clear()
|
||||||
mediaPlayers.clear()
|
mediaPlayers.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Returns true if there is active media player card or recommendation card */
|
||||||
|
fun hasActiveMediaOrRecommendationCard(): Boolean {
|
||||||
|
if (smartspaceMediaData != null && smartspaceMediaData?.isActive!!) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if (firstActiveMediaIndex() != -1) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ class MediaCarouselScrollHandler(
|
|||||||
private val closeGuts: (immediate: Boolean) -> Unit,
|
private val closeGuts: (immediate: Boolean) -> Unit,
|
||||||
private val falsingCollector: FalsingCollector,
|
private val falsingCollector: FalsingCollector,
|
||||||
private val falsingManager: FalsingManager,
|
private val falsingManager: FalsingManager,
|
||||||
private val logSmartspaceImpression: () -> Unit
|
private val logSmartspaceImpression: (Boolean) -> Unit
|
||||||
) {
|
) {
|
||||||
/**
|
/**
|
||||||
* Is the view in RTL
|
* Is the view in RTL
|
||||||
@@ -195,18 +195,22 @@ class MediaCarouselScrollHandler(
|
|||||||
if (playerWidthPlusPadding == 0) {
|
if (playerWidthPlusPadding == 0) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val relativeScrollX = scrollView.relativeScrollX
|
val relativeScrollX = scrollView.relativeScrollX
|
||||||
onMediaScrollingChanged(relativeScrollX / playerWidthPlusPadding,
|
onMediaScrollingChanged(relativeScrollX / playerWidthPlusPadding,
|
||||||
relativeScrollX % playerWidthPlusPadding)
|
relativeScrollX % playerWidthPlusPadding)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the media card is visible to user if any
|
||||||
|
*/
|
||||||
var visibleToUser: Boolean = false
|
var visibleToUser: Boolean = false
|
||||||
set(value) {
|
|
||||||
if (field != value) {
|
/**
|
||||||
field = value
|
* Whether the quick setting is expanded or not
|
||||||
}
|
*/
|
||||||
}
|
var qsExpanded: Boolean = false
|
||||||
|
|
||||||
init {
|
init {
|
||||||
gestureDetector = GestureDetectorCompat(scrollView.context, gestureListener)
|
gestureDetector = GestureDetectorCompat(scrollView.context, gestureListener)
|
||||||
@@ -471,7 +475,7 @@ class MediaCarouselScrollHandler(
|
|||||||
val oldIndex = visibleMediaIndex
|
val oldIndex = visibleMediaIndex
|
||||||
visibleMediaIndex = newIndex
|
visibleMediaIndex = newIndex
|
||||||
if (oldIndex != visibleMediaIndex && visibleToUser) {
|
if (oldIndex != visibleMediaIndex && visibleToUser) {
|
||||||
logSmartspaceImpression()
|
logSmartspaceImpression(qsExpanded)
|
||||||
}
|
}
|
||||||
closeGuts(false)
|
closeGuts(false)
|
||||||
updatePlayerVisibilities()
|
updatePlayerVisibilities()
|
||||||
|
|||||||
@@ -266,7 +266,7 @@ public class MediaControlPanel {
|
|||||||
}
|
}
|
||||||
mKey = key;
|
mKey = key;
|
||||||
MediaSession.Token token = data.getToken();
|
MediaSession.Token token = data.getToken();
|
||||||
mInstanceId = data.getPackageName().hashCode();
|
mInstanceId = SmallHash.hash(data.getPackageName());
|
||||||
|
|
||||||
mBackgroundColor = data.getBackgroundColor();
|
mBackgroundColor = data.getBackgroundColor();
|
||||||
if (mToken == null || !mToken.equals(token)) {
|
if (mToken == null || !mToken.equals(token)) {
|
||||||
@@ -504,7 +504,7 @@ public class MediaControlPanel {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mInstanceId = data.getTargetId().hashCode();
|
mInstanceId = SmallHash.hash(data.getTargetId());
|
||||||
mBackgroundColor = data.getBackgroundColor();
|
mBackgroundColor = data.getBackgroundColor();
|
||||||
TransitionLayout recommendationCard = mRecommendationViewHolder.getRecommendations();
|
TransitionLayout recommendationCard = mRecommendationViewHolder.getRecommendations();
|
||||||
recommendationCard.setBackgroundTintList(ColorStateList.valueOf(mBackgroundColor));
|
recommendationCard.setBackgroundTintList(ColorStateList.valueOf(mBackgroundColor));
|
||||||
|
|||||||
@@ -31,7 +31,8 @@ class MediaDataCombineLatest @Inject constructor() : MediaDataManager.Listener,
|
|||||||
key: String,
|
key: String,
|
||||||
oldKey: String?,
|
oldKey: String?,
|
||||||
data: MediaData,
|
data: MediaData,
|
||||||
immediately: Boolean
|
immediately: Boolean,
|
||||||
|
isSsReactivated: Boolean
|
||||||
) {
|
) {
|
||||||
if (oldKey != null && oldKey != key && entries.contains(oldKey)) {
|
if (oldKey != null && oldKey != key && entries.contains(oldKey)) {
|
||||||
entries[key] = data to entries.remove(oldKey)?.second
|
entries[key] = data to entries.remove(oldKey)?.second
|
||||||
|
|||||||
@@ -83,7 +83,8 @@ class MediaDataFilter @Inject constructor(
|
|||||||
key: String,
|
key: String,
|
||||||
oldKey: String?,
|
oldKey: String?,
|
||||||
data: MediaData,
|
data: MediaData,
|
||||||
immediately: Boolean
|
immediately: Boolean,
|
||||||
|
isSsReactivated: Boolean
|
||||||
) {
|
) {
|
||||||
if (oldKey != null && oldKey != key) {
|
if (oldKey != null && oldKey != key) {
|
||||||
allEntries.remove(oldKey)
|
allEntries.remove(oldKey)
|
||||||
@@ -101,7 +102,7 @@ class MediaDataFilter @Inject constructor(
|
|||||||
|
|
||||||
// Notify listeners
|
// Notify listeners
|
||||||
listeners.forEach {
|
listeners.forEach {
|
||||||
it.onMediaDataLoaded(key, oldKey, data)
|
it.onMediaDataLoaded(key, oldKey, data, isSsReactivated = isSsReactivated)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,6 +119,8 @@ class MediaDataFilter @Inject constructor(
|
|||||||
// Override the pass-in value here, as the order of Smartspace card is only determined here.
|
// Override the pass-in value here, as the order of Smartspace card is only determined here.
|
||||||
var shouldPrioritizeMutable = false
|
var shouldPrioritizeMutable = false
|
||||||
smartspaceMediaData = data
|
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
|
// Before forwarding the smartspace target, first check if we have recently inactive media
|
||||||
val sorted = userEntries.toSortedMap(compareBy {
|
val sorted = userEntries.toSortedMap(compareBy {
|
||||||
@@ -137,9 +140,13 @@ class MediaDataFilter @Inject constructor(
|
|||||||
// Notify listeners to consider this media active
|
// Notify listeners to consider this media active
|
||||||
Log.d(TAG, "reactivating $lastActiveKey instead of smartspace")
|
Log.d(TAG, "reactivating $lastActiveKey instead of smartspace")
|
||||||
reactivatedKey = lastActiveKey
|
reactivatedKey = lastActiveKey
|
||||||
|
if (MediaPlayerData.firstActiveMediaIndex() == -1) {
|
||||||
|
isSsReactivated = true
|
||||||
|
}
|
||||||
val mediaData = sorted.get(lastActiveKey)!!.copy(active = true)
|
val mediaData = sorted.get(lastActiveKey)!!.copy(active = true)
|
||||||
listeners.forEach {
|
listeners.forEach {
|
||||||
it.onMediaDataLoaded(lastActiveKey, lastActiveKey, mediaData)
|
it.onMediaDataLoaded(lastActiveKey, lastActiveKey, mediaData,
|
||||||
|
isSsReactivated = isSsReactivated)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Mark to prioritize Smartspace card if no recent media.
|
// Mark to prioritize Smartspace card if no recent media.
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ class MediaDataManager(
|
|||||||
private val internalListeners: MutableSet<Listener> = mutableSetOf()
|
private val internalListeners: MutableSet<Listener> = mutableSetOf()
|
||||||
private val mediaEntries: LinkedHashMap<String, MediaData> = LinkedHashMap()
|
private val mediaEntries: LinkedHashMap<String, MediaData> = LinkedHashMap()
|
||||||
// There should ONLY be at most one Smartspace media recommendation.
|
// There should ONLY be at most one Smartspace media recommendation.
|
||||||
private var smartspaceMediaData: SmartspaceMediaData = EMPTY_SMARTSPACE_MEDIA_DATA
|
var smartspaceMediaData: SmartspaceMediaData = EMPTY_SMARTSPACE_MEDIA_DATA
|
||||||
private var smartspaceSession: SmartspaceSession? = null
|
private var smartspaceSession: SmartspaceSession? = null
|
||||||
private var allowMediaRecommendations = Utils.allowMediaRecommendations(context)
|
private var allowMediaRecommendations = Utils.allowMediaRecommendations(context)
|
||||||
|
|
||||||
@@ -824,12 +824,16 @@ class MediaDataManager(
|
|||||||
* @param immediately indicates should apply the UI changes immediately, otherwise wait
|
* @param immediately indicates should apply the UI changes immediately, otherwise wait
|
||||||
* until the next refresh-round before UI becomes visible. True by default to take in place
|
* until the next refresh-round before UI becomes visible. True by default to take in place
|
||||||
* immediately.
|
* 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.
|
||||||
*/
|
*/
|
||||||
fun onMediaDataLoaded(
|
fun onMediaDataLoaded(
|
||||||
key: String,
|
key: String,
|
||||||
oldKey: String?,
|
oldKey: String?,
|
||||||
data: MediaData,
|
data: MediaData,
|
||||||
immediately: Boolean = true
|
immediately: Boolean = true,
|
||||||
|
isSsReactivated: Boolean = false
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -67,7 +67,8 @@ class MediaDeviceManager @Inject constructor(
|
|||||||
key: String,
|
key: String,
|
||||||
oldKey: String?,
|
oldKey: String?,
|
||||||
data: MediaData,
|
data: MediaData,
|
||||||
immediately: Boolean
|
immediately: Boolean,
|
||||||
|
isSsReactivated: Boolean
|
||||||
) {
|
) {
|
||||||
if (oldKey != null && oldKey != key) {
|
if (oldKey != null && oldKey != key) {
|
||||||
val oldEntry = entries.remove(oldKey)
|
val oldEntry = entries.remove(oldKey)
|
||||||
|
|||||||
@@ -220,14 +220,11 @@ class MediaHierarchyManager @Inject constructor(
|
|||||||
set(value) {
|
set(value) {
|
||||||
if (field != value) {
|
if (field != value) {
|
||||||
field = value
|
field = value
|
||||||
|
mediaCarouselController.mediaCarouselScrollHandler.qsExpanded = value
|
||||||
}
|
}
|
||||||
// qs is expanded on LS shade and HS shade
|
// qs is expanded on LS shade and HS shade
|
||||||
if (value && (isLockScreenShadeVisibleToUser() || isHomeScreenShadeVisibleToUser())) {
|
if (value && (isLockScreenShadeVisibleToUser() || isHomeScreenShadeVisibleToUser())) {
|
||||||
mediaCarouselController.logSmartspaceImpression()
|
mediaCarouselController.logSmartspaceImpression(value)
|
||||||
}
|
|
||||||
// Release shade and back to lock screen
|
|
||||||
if (isLockScreenVisibleToUser()) {
|
|
||||||
mediaCarouselController.logSmartspaceImpression()
|
|
||||||
}
|
}
|
||||||
mediaCarouselController.mediaCarouselScrollHandler.visibleToUser = isVisibleToUser()
|
mediaCarouselController.mediaCarouselScrollHandler.visibleToUser = isVisibleToUser()
|
||||||
}
|
}
|
||||||
@@ -409,7 +406,7 @@ class MediaHierarchyManager @Inject constructor(
|
|||||||
updateTargetState()
|
updateTargetState()
|
||||||
// Enters shade from lock screen
|
// Enters shade from lock screen
|
||||||
if (newState == StatusBarState.SHADE_LOCKED && isLockScreenShadeVisibleToUser()) {
|
if (newState == StatusBarState.SHADE_LOCKED && isLockScreenShadeVisibleToUser()) {
|
||||||
mediaCarouselController.logSmartspaceImpression()
|
mediaCarouselController.logSmartspaceImpression(qsExpanded)
|
||||||
}
|
}
|
||||||
mediaCarouselController.mediaCarouselScrollHandler.visibleToUser = isVisibleToUser()
|
mediaCarouselController.mediaCarouselScrollHandler.visibleToUser = isVisibleToUser()
|
||||||
}
|
}
|
||||||
@@ -423,7 +420,7 @@ class MediaHierarchyManager @Inject constructor(
|
|||||||
dozeAnimationRunning = false
|
dozeAnimationRunning = false
|
||||||
// Enters lock screen from screen off
|
// Enters lock screen from screen off
|
||||||
if (isLockScreenVisibleToUser()) {
|
if (isLockScreenVisibleToUser()) {
|
||||||
mediaCarouselController.logSmartspaceImpression()
|
mediaCarouselController.logSmartspaceImpression(qsExpanded)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
updateDesiredLocation()
|
updateDesiredLocation()
|
||||||
@@ -436,11 +433,7 @@ class MediaHierarchyManager @Inject constructor(
|
|||||||
override fun onExpandedChanged(isExpanded: Boolean) {
|
override fun onExpandedChanged(isExpanded: Boolean) {
|
||||||
// Enters shade from home screen
|
// Enters shade from home screen
|
||||||
if (isHomeScreenShadeVisibleToUser()) {
|
if (isHomeScreenShadeVisibleToUser()) {
|
||||||
mediaCarouselController.logSmartspaceImpression()
|
mediaCarouselController.logSmartspaceImpression(qsExpanded)
|
||||||
}
|
|
||||||
// Back to lock screen from bouncer
|
|
||||||
if (isLockScreenVisibleToUser()) {
|
|
||||||
mediaCarouselController.logSmartspaceImpression()
|
|
||||||
}
|
}
|
||||||
mediaCarouselController.mediaCarouselScrollHandler.visibleToUser = isVisibleToUser()
|
mediaCarouselController.mediaCarouselScrollHandler.visibleToUser = isVisibleToUser()
|
||||||
}
|
}
|
||||||
@@ -465,6 +458,10 @@ class MediaHierarchyManager @Inject constructor(
|
|||||||
goingToSleep = false
|
goingToSleep = false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
mediaCarouselController.updateUserVisibility = {
|
||||||
|
mediaCarouselController.mediaCarouselScrollHandler.visibleToUser = isVisibleToUser()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateConfiguration() {
|
private fun updateConfiguration() {
|
||||||
|
|||||||
@@ -60,7 +60,8 @@ class MediaHost constructor(
|
|||||||
key: String,
|
key: String,
|
||||||
oldKey: String?,
|
oldKey: String?,
|
||||||
data: MediaData,
|
data: MediaData,
|
||||||
immediately: Boolean
|
immediately: Boolean,
|
||||||
|
isSsReactivated: Boolean
|
||||||
) {
|
) {
|
||||||
if (immediately) {
|
if (immediately) {
|
||||||
updateViewVisibility()
|
updateViewVisibility()
|
||||||
|
|||||||
@@ -159,7 +159,8 @@ class MediaResumeListener @Inject constructor(
|
|||||||
key: String,
|
key: String,
|
||||||
oldKey: String?,
|
oldKey: String?,
|
||||||
data: MediaData,
|
data: MediaData,
|
||||||
immediately: Boolean
|
immediately: Boolean,
|
||||||
|
isSsReactivated: Boolean
|
||||||
) {
|
) {
|
||||||
if (useMediaResumption) {
|
if (useMediaResumption) {
|
||||||
// If this had been started from a resume state, disconnect now that it's live
|
// If this had been started from a resume state, disconnect now that it's live
|
||||||
|
|||||||
@@ -95,7 +95,8 @@ class MediaSessionBasedFilter @Inject constructor(
|
|||||||
key: String,
|
key: String,
|
||||||
oldKey: String?,
|
oldKey: String?,
|
||||||
data: MediaData,
|
data: MediaData,
|
||||||
immediately: Boolean
|
immediately: Boolean,
|
||||||
|
isSsReactivated: Boolean
|
||||||
) {
|
) {
|
||||||
backgroundExecutor.execute {
|
backgroundExecutor.execute {
|
||||||
data.token?.let {
|
data.token?.let {
|
||||||
|
|||||||
@@ -54,7 +54,8 @@ class MediaTimeoutListener @Inject constructor(
|
|||||||
key: String,
|
key: String,
|
||||||
oldKey: String?,
|
oldKey: String?,
|
||||||
data: MediaData,
|
data: MediaData,
|
||||||
immediately: Boolean
|
immediately: Boolean,
|
||||||
|
isSsReactivated: Boolean
|
||||||
) {
|
) {
|
||||||
var reusedListener: PlaybackStateListener? = null
|
var reusedListener: PlaybackStateListener? = null
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2021 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.android.systemui.media;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple hash function for use in privacy-sensitive logging.
|
||||||
|
*/
|
||||||
|
public final class SmallHash {
|
||||||
|
// Hashes will be in the range [0, MAX_HASH).
|
||||||
|
public static final int MAX_HASH = (1 << 13);
|
||||||
|
|
||||||
|
/** Return Small hash of the string, if non-null, or 0 otherwise. */
|
||||||
|
public static int hash(String in) {
|
||||||
|
return hash(Objects.hashCode(in));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Maps in to the range [0, MAX_HASH), keeping similar values distinct.
|
||||||
|
*
|
||||||
|
* @param in An arbitrary integer.
|
||||||
|
* @return in mod MAX_HASH, signs chosen to stay in the range [0, MAX_HASH).
|
||||||
|
*/
|
||||||
|
public static int hash(int in) {
|
||||||
|
return Math.abs(Math.floorMod(in, MAX_HASH));
|
||||||
|
}
|
||||||
|
|
||||||
|
private SmallHash() {}
|
||||||
|
}
|
||||||
@@ -245,7 +245,8 @@ public class NotificationMediaManager implements Dumpable {
|
|||||||
mMediaDataManager.addListener(new MediaDataManager.Listener() {
|
mMediaDataManager.addListener(new MediaDataManager.Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void onMediaDataLoaded(@NonNull String key,
|
public void onMediaDataLoaded(@NonNull String key,
|
||||||
@Nullable String oldKey, @NonNull MediaData data, boolean immediately) {
|
@Nullable String oldKey, @NonNull MediaData data, boolean immediately,
|
||||||
|
boolean isSsReactivated) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -318,7 +319,8 @@ public class NotificationMediaManager implements Dumpable {
|
|||||||
mMediaDataManager.addListener(new MediaDataManager.Listener() {
|
mMediaDataManager.addListener(new MediaDataManager.Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void onMediaDataLoaded(@NonNull String key,
|
public void onMediaDataLoaded(@NonNull String key,
|
||||||
@Nullable String oldKey, @NonNull MediaData data, boolean immediately) {
|
@Nullable String oldKey, @NonNull MediaData data, boolean immediately,
|
||||||
|
boolean isSsReactivated) {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -82,9 +82,11 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void eventNotEmittedWithoutDevice() {
|
public void eventNotEmittedWithoutDevice() {
|
||||||
// WHEN data source emits an event without device data
|
// WHEN data source emits an event without device data
|
||||||
mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */);
|
mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */,
|
||||||
|
false /* isSsReactivated */);
|
||||||
// THEN an event isn't emitted
|
// THEN an event isn't emitted
|
||||||
verify(mListener, never()).onMediaDataLoaded(eq(KEY), any(), any(), anyBoolean());
|
verify(mListener, never()).onMediaDataLoaded(eq(KEY), any(), any(), anyBoolean(),
|
||||||
|
anyBoolean());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -92,7 +94,8 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
|
|||||||
// WHEN device source emits an event without media data
|
// WHEN device source emits an event without media data
|
||||||
mManager.onMediaDeviceChanged(KEY, null, mDeviceData);
|
mManager.onMediaDeviceChanged(KEY, null, mDeviceData);
|
||||||
// THEN an event isn't emitted
|
// THEN an event isn't emitted
|
||||||
verify(mListener, never()).onMediaDataLoaded(eq(KEY), any(), any(), anyBoolean());
|
verify(mListener, never()).onMediaDataLoaded(eq(KEY), any(), any(), anyBoolean(),
|
||||||
|
anyBoolean());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -100,80 +103,95 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
|
|||||||
// GIVEN that a device event has already been received
|
// GIVEN that a device event has already been received
|
||||||
mManager.onMediaDeviceChanged(KEY, null, mDeviceData);
|
mManager.onMediaDeviceChanged(KEY, null, mDeviceData);
|
||||||
// WHEN media event is received
|
// WHEN media event is received
|
||||||
mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */);
|
mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */,
|
||||||
|
false /* isSsReactivated */);
|
||||||
// THEN the listener receives a combined event
|
// THEN the listener receives a combined event
|
||||||
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
|
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
|
||||||
verify(mListener).onMediaDataLoaded(eq(KEY), any(), captor.capture(), anyBoolean());
|
verify(mListener).onMediaDataLoaded(eq(KEY), any(), captor.capture(), anyBoolean(),
|
||||||
|
anyBoolean());
|
||||||
assertThat(captor.getValue().getDevice()).isNotNull();
|
assertThat(captor.getValue().getDevice()).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void emitEventAfterMediaFirst() {
|
public void emitEventAfterMediaFirst() {
|
||||||
// GIVEN that media event has already been received
|
// GIVEN that media event has already been received
|
||||||
mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */);
|
mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */,
|
||||||
|
false /* isSsReactivated */);
|
||||||
// WHEN device event is received
|
// WHEN device event is received
|
||||||
mManager.onMediaDeviceChanged(KEY, null, mDeviceData);
|
mManager.onMediaDeviceChanged(KEY, null, mDeviceData);
|
||||||
// THEN the listener receives a combined event
|
// THEN the listener receives a combined event
|
||||||
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
|
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
|
||||||
verify(mListener).onMediaDataLoaded(eq(KEY), any(), captor.capture(), anyBoolean());
|
verify(mListener).onMediaDataLoaded(eq(KEY), any(), captor.capture(), anyBoolean(),
|
||||||
|
anyBoolean());
|
||||||
assertThat(captor.getValue().getDevice()).isNotNull();
|
assertThat(captor.getValue().getDevice()).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void migrateKeyMediaFirst() {
|
public void migrateKeyMediaFirst() {
|
||||||
// GIVEN that media and device info has already been received
|
// GIVEN that media and device info has already been received
|
||||||
mManager.onMediaDataLoaded(OLD_KEY, null, mMediaData, true /* immediately */);
|
mManager.onMediaDataLoaded(OLD_KEY, null, mMediaData, true /* immediately */,
|
||||||
|
false /* isSsReactivated */);
|
||||||
mManager.onMediaDeviceChanged(OLD_KEY, null, mDeviceData);
|
mManager.onMediaDeviceChanged(OLD_KEY, null, mDeviceData);
|
||||||
reset(mListener);
|
reset(mListener);
|
||||||
// WHEN a key migration event is received
|
// WHEN a key migration event is received
|
||||||
mManager.onMediaDataLoaded(KEY, OLD_KEY, mMediaData, true /* immediately */);
|
mManager.onMediaDataLoaded(KEY, OLD_KEY, mMediaData, true /* immediately */,
|
||||||
|
false /* isSsReactivated */);
|
||||||
// THEN the listener receives a combined event
|
// THEN the listener receives a combined event
|
||||||
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
|
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
|
||||||
verify(mListener).onMediaDataLoaded(eq(KEY), eq(OLD_KEY), captor.capture(), anyBoolean());
|
verify(mListener).onMediaDataLoaded(eq(KEY), eq(OLD_KEY), captor.capture(), anyBoolean(),
|
||||||
|
anyBoolean());
|
||||||
assertThat(captor.getValue().getDevice()).isNotNull();
|
assertThat(captor.getValue().getDevice()).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void migrateKeyDeviceFirst() {
|
public void migrateKeyDeviceFirst() {
|
||||||
// GIVEN that media and device info has already been received
|
// GIVEN that media and device info has already been received
|
||||||
mManager.onMediaDataLoaded(OLD_KEY, null, mMediaData, true /* immediately */);
|
mManager.onMediaDataLoaded(OLD_KEY, null, mMediaData, true /* immediately */,
|
||||||
|
false /* isSsReactivated */);
|
||||||
mManager.onMediaDeviceChanged(OLD_KEY, null, mDeviceData);
|
mManager.onMediaDeviceChanged(OLD_KEY, null, mDeviceData);
|
||||||
reset(mListener);
|
reset(mListener);
|
||||||
// WHEN a key migration event is received
|
// WHEN a key migration event is received
|
||||||
mManager.onMediaDeviceChanged(KEY, OLD_KEY, mDeviceData);
|
mManager.onMediaDeviceChanged(KEY, OLD_KEY, mDeviceData);
|
||||||
// THEN the listener receives a combined event
|
// THEN the listener receives a combined event
|
||||||
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
|
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
|
||||||
verify(mListener).onMediaDataLoaded(eq(KEY), eq(OLD_KEY), captor.capture(), anyBoolean());
|
verify(mListener).onMediaDataLoaded(eq(KEY), eq(OLD_KEY), captor.capture(), anyBoolean(),
|
||||||
|
anyBoolean());
|
||||||
assertThat(captor.getValue().getDevice()).isNotNull();
|
assertThat(captor.getValue().getDevice()).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void migrateKeyMediaAfter() {
|
public void migrateKeyMediaAfter() {
|
||||||
// GIVEN that media and device info has already been received
|
// GIVEN that media and device info has already been received
|
||||||
mManager.onMediaDataLoaded(OLD_KEY, null, mMediaData, true /* immediately */);
|
mManager.onMediaDataLoaded(OLD_KEY, null, mMediaData, true /* immediately */,
|
||||||
|
false /* isSsReactivated */);
|
||||||
mManager.onMediaDeviceChanged(OLD_KEY, null, mDeviceData);
|
mManager.onMediaDeviceChanged(OLD_KEY, null, mDeviceData);
|
||||||
mManager.onMediaDeviceChanged(KEY, OLD_KEY, mDeviceData);
|
mManager.onMediaDeviceChanged(KEY, OLD_KEY, mDeviceData);
|
||||||
reset(mListener);
|
reset(mListener);
|
||||||
// WHEN a second key migration event is received for media
|
// WHEN a second key migration event is received for media
|
||||||
mManager.onMediaDataLoaded(KEY, OLD_KEY, mMediaData, true /* immediately */);
|
mManager.onMediaDataLoaded(KEY, OLD_KEY, mMediaData, true /* immediately */,
|
||||||
|
false /* isSsReactivated */);
|
||||||
// THEN the key has already been migrated
|
// THEN the key has already been migrated
|
||||||
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
|
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
|
||||||
verify(mListener).onMediaDataLoaded(eq(KEY), eq(KEY), captor.capture(), anyBoolean());
|
verify(mListener).onMediaDataLoaded(eq(KEY), eq(KEY), captor.capture(), anyBoolean(),
|
||||||
|
anyBoolean());
|
||||||
assertThat(captor.getValue().getDevice()).isNotNull();
|
assertThat(captor.getValue().getDevice()).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void migrateKeyDeviceAfter() {
|
public void migrateKeyDeviceAfter() {
|
||||||
// GIVEN that media and device info has already been received
|
// GIVEN that media and device info has already been received
|
||||||
mManager.onMediaDataLoaded(OLD_KEY, null, mMediaData, true /* immediately */);
|
mManager.onMediaDataLoaded(OLD_KEY, null, mMediaData, true /* immediately */,
|
||||||
|
false /* isSsReactivated */);
|
||||||
mManager.onMediaDeviceChanged(OLD_KEY, null, mDeviceData);
|
mManager.onMediaDeviceChanged(OLD_KEY, null, mDeviceData);
|
||||||
mManager.onMediaDataLoaded(KEY, OLD_KEY, mMediaData, true /* immediately */);
|
mManager.onMediaDataLoaded(KEY, OLD_KEY, mMediaData, true /* immediately */,
|
||||||
|
false /* isSsReactivated */);
|
||||||
reset(mListener);
|
reset(mListener);
|
||||||
// WHEN a second key migration event is received for the device
|
// WHEN a second key migration event is received for the device
|
||||||
mManager.onMediaDeviceChanged(KEY, OLD_KEY, mDeviceData);
|
mManager.onMediaDeviceChanged(KEY, OLD_KEY, mDeviceData);
|
||||||
// THEN the key has already be migrated
|
// THEN the key has already be migrated
|
||||||
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
|
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
|
||||||
verify(mListener).onMediaDataLoaded(eq(KEY), eq(KEY), captor.capture(), anyBoolean());
|
verify(mListener).onMediaDataLoaded(eq(KEY), eq(KEY), captor.capture(), anyBoolean(),
|
||||||
|
anyBoolean());
|
||||||
assertThat(captor.getValue().getDevice()).isNotNull();
|
assertThat(captor.getValue().getDevice()).isNotNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,7 +205,8 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void mediaDataRemovedAfterMediaEvent() {
|
public void mediaDataRemovedAfterMediaEvent() {
|
||||||
mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */);
|
mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */,
|
||||||
|
false /* isSsReactivated */);
|
||||||
mManager.onMediaDataRemoved(KEY);
|
mManager.onMediaDataRemoved(KEY);
|
||||||
verify(mListener).onMediaDataRemoved(eq(KEY));
|
verify(mListener).onMediaDataRemoved(eq(KEY));
|
||||||
}
|
}
|
||||||
@@ -202,13 +221,15 @@ public class MediaDataCombineLatestTest extends SysuiTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void mediaDataKeyUpdated() {
|
public void mediaDataKeyUpdated() {
|
||||||
// GIVEN that device and media events have already been received
|
// GIVEN that device and media events have already been received
|
||||||
mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */);
|
mManager.onMediaDataLoaded(KEY, null, mMediaData, true /* immediately */,
|
||||||
|
false /* isSsReactivated */);
|
||||||
mManager.onMediaDeviceChanged(KEY, null, mDeviceData);
|
mManager.onMediaDeviceChanged(KEY, null, mDeviceData);
|
||||||
// WHEN the key is changed
|
// WHEN the key is changed
|
||||||
mManager.onMediaDataLoaded("NEW_KEY", KEY, mMediaData, true /* immediately */);
|
mManager.onMediaDataLoaded("NEW_KEY", KEY, mMediaData, true /* immediately */,
|
||||||
|
false /* isSsReactivated */);
|
||||||
// THEN the listener gets a load event with the correct keys
|
// THEN the listener gets a load event with the correct keys
|
||||||
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
|
ArgumentCaptor<MediaData> captor = ArgumentCaptor.forClass(MediaData.class);
|
||||||
verify(mListener).onMediaDataLoaded(
|
verify(mListener).onMediaDataLoaded(
|
||||||
eq("NEW_KEY"), any(), captor.capture(), anyBoolean());
|
eq("NEW_KEY"), any(), captor.capture(), anyBoolean(), anyBoolean());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,7 +120,8 @@ class MediaDataFilterTest : SysuiTestCase() {
|
|||||||
mediaDataFilter.onMediaDataLoaded(KEY, null, dataMain)
|
mediaDataFilter.onMediaDataLoaded(KEY, null, dataMain)
|
||||||
|
|
||||||
// THEN we should tell the listener
|
// THEN we should tell the listener
|
||||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataMain), eq(true))
|
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataMain), eq(true),
|
||||||
|
eq(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -129,7 +130,7 @@ class MediaDataFilterTest : SysuiTestCase() {
|
|||||||
mediaDataFilter.onMediaDataLoaded(KEY, null, dataGuest)
|
mediaDataFilter.onMediaDataLoaded(KEY, null, dataGuest)
|
||||||
|
|
||||||
// THEN we should NOT tell the listener
|
// THEN we should NOT tell the listener
|
||||||
verify(listener, never()).onMediaDataLoaded(any(), any(), any(), anyBoolean())
|
verify(listener, never()).onMediaDataLoaded(any(), any(), any(), anyBoolean(), anyBoolean())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -175,10 +176,12 @@ class MediaDataFilterTest : SysuiTestCase() {
|
|||||||
setUser(USER_GUEST)
|
setUser(USER_GUEST)
|
||||||
|
|
||||||
// THEN we should add back the guest user media
|
// THEN we should add back the guest user media
|
||||||
verify(listener).onMediaDataLoaded(eq(KEY_ALT), eq(null), eq(dataGuest), eq(true))
|
verify(listener).onMediaDataLoaded(eq(KEY_ALT), eq(null), eq(dataGuest), eq(true),
|
||||||
|
eq(false))
|
||||||
|
|
||||||
// but not the main user's
|
// but not the main user's
|
||||||
verify(listener, never()).onMediaDataLoaded(eq(KEY), any(), eq(dataMain), anyBoolean())
|
verify(listener, never()).onMediaDataLoaded(eq(KEY), any(), eq(dataMain), anyBoolean(),
|
||||||
|
anyBoolean())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -245,7 +248,7 @@ class MediaDataFilterTest : SysuiTestCase() {
|
|||||||
|
|
||||||
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
|
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
|
||||||
|
|
||||||
verify(listener, never()).onMediaDataLoaded(any(), any(), any(), anyBoolean())
|
verify(listener, never()).onMediaDataLoaded(any(), any(), any(), anyBoolean(), anyBoolean())
|
||||||
verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
|
verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
|
||||||
assertThat(mediaDataFilter.hasActiveMedia()).isFalse()
|
assertThat(mediaDataFilter.hasActiveMedia()).isFalse()
|
||||||
}
|
}
|
||||||
@@ -282,12 +285,15 @@ class MediaDataFilterTest : SysuiTestCase() {
|
|||||||
// WHEN we have media that was recently played, but not currently active
|
// WHEN we have media that was recently played, but not currently active
|
||||||
val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
|
val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
|
||||||
mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
|
mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
|
||||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true))
|
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true),
|
||||||
|
eq(false))
|
||||||
|
|
||||||
// AND we get a smartspace signal
|
// AND we get a smartspace signal
|
||||||
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
|
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
|
||||||
|
|
||||||
// THEN we should tell listeners to treat the media as active instead
|
// THEN we should tell listeners to treat the media as not active instead
|
||||||
|
verify(listener, never()).onMediaDataLoaded(eq(KEY), eq(KEY), any(), anyBoolean(),
|
||||||
|
anyBoolean())
|
||||||
verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
|
verify(listener, never()).onSmartspaceMediaDataLoaded(any(), any(), anyBoolean())
|
||||||
assertThat(mediaDataFilter.hasActiveMedia()).isFalse()
|
assertThat(mediaDataFilter.hasActiveMedia()).isFalse()
|
||||||
}
|
}
|
||||||
@@ -299,14 +305,16 @@ class MediaDataFilterTest : SysuiTestCase() {
|
|||||||
// WHEN we have media that was recently played, but not currently active
|
// WHEN we have media that was recently played, but not currently active
|
||||||
val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
|
val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
|
||||||
mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
|
mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
|
||||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true))
|
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true),
|
||||||
|
eq(false))
|
||||||
|
|
||||||
// AND we get a smartspace signal
|
// AND we get a smartspace signal
|
||||||
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
|
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
|
||||||
|
|
||||||
// THEN we should tell listeners to treat the media as active instead
|
// THEN we should tell listeners to treat the media as active instead
|
||||||
val dataCurrentAndActive = dataCurrent.copy(active = true)
|
val dataCurrentAndActive = dataCurrent.copy(active = true)
|
||||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY), eq(dataCurrentAndActive), eq(true))
|
verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY), eq(dataCurrentAndActive), eq(true),
|
||||||
|
eq(true))
|
||||||
assertThat(mediaDataFilter.hasActiveMedia()).isTrue()
|
assertThat(mediaDataFilter.hasActiveMedia()).isTrue()
|
||||||
// Smartspace update shouldn't be propagated for the empty rec list.
|
// 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())
|
||||||
@@ -317,14 +325,16 @@ class MediaDataFilterTest : SysuiTestCase() {
|
|||||||
// WHEN we have media that was recently played, but not currently active
|
// WHEN we have media that was recently played, but not currently active
|
||||||
val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
|
val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
|
||||||
mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
|
mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
|
||||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true))
|
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true),
|
||||||
|
eq(false))
|
||||||
|
|
||||||
// AND we get a smartspace signal
|
// AND we get a smartspace signal
|
||||||
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
|
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
|
||||||
|
|
||||||
// THEN we should tell listeners to treat the media as active instead
|
// THEN we should tell listeners to treat the media as active instead
|
||||||
val dataCurrentAndActive = dataCurrent.copy(active = true)
|
val dataCurrentAndActive = dataCurrent.copy(active = true)
|
||||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY), eq(dataCurrentAndActive), eq(true))
|
verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY), eq(dataCurrentAndActive), eq(true),
|
||||||
|
eq(true))
|
||||||
assertThat(mediaDataFilter.hasActiveMedia()).isTrue()
|
assertThat(mediaDataFilter.hasActiveMedia()).isTrue()
|
||||||
// Smartspace update should also be propagated but not prioritized.
|
// Smartspace update should also be propagated but not prioritized.
|
||||||
verify(listener)
|
verify(listener)
|
||||||
@@ -344,11 +354,17 @@ class MediaDataFilterTest : SysuiTestCase() {
|
|||||||
fun testOnSmartspaceMediaDataRemoved_usedMediaAndSmartspace_clearsBoth() {
|
fun testOnSmartspaceMediaDataRemoved_usedMediaAndSmartspace_clearsBoth() {
|
||||||
val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
|
val dataCurrent = dataMain.copy(active = false, lastActive = clock.elapsedRealtime())
|
||||||
mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
|
mediaDataFilter.onMediaDataLoaded(KEY, null, dataCurrent)
|
||||||
|
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), eq(dataCurrent), eq(true),
|
||||||
|
eq(false))
|
||||||
|
|
||||||
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
|
mediaDataFilter.onSmartspaceMediaDataLoaded(SMARTSPACE_KEY, smartspaceData)
|
||||||
|
|
||||||
|
val dataCurrentAndActive = dataCurrent.copy(active = true)
|
||||||
|
verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY), eq(dataCurrentAndActive), eq(true),
|
||||||
|
eq(true))
|
||||||
|
|
||||||
mediaDataFilter.onSmartspaceMediaDataRemoved(SMARTSPACE_KEY)
|
mediaDataFilter.onSmartspaceMediaDataRemoved(SMARTSPACE_KEY)
|
||||||
|
|
||||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY), eq(dataCurrent), eq(true))
|
|
||||||
verify(listener).onSmartspaceMediaDataRemoved(SMARTSPACE_KEY)
|
verify(listener).onSmartspaceMediaDataRemoved(SMARTSPACE_KEY)
|
||||||
assertThat(mediaDataFilter.hasActiveMedia()).isFalse()
|
assertThat(mediaDataFilter.hasActiveMedia()).isFalse()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -185,7 +185,8 @@ class MediaDataManagerTest : SysuiTestCase() {
|
|||||||
fun testOnMetaDataLoaded_callsListener() {
|
fun testOnMetaDataLoaded_callsListener() {
|
||||||
mediaDataManager.onNotificationAdded(KEY, mediaNotification)
|
mediaDataManager.onNotificationAdded(KEY, mediaNotification)
|
||||||
mediaDataManager.onMediaDataLoaded(KEY, oldKey = null, data = mock(MediaData::class.java))
|
mediaDataManager.onMediaDataLoaded(KEY, oldKey = null, data = mock(MediaData::class.java))
|
||||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), anyObject(), eq(true))
|
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), anyObject(), eq(true),
|
||||||
|
eq(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -196,7 +197,8 @@ class MediaDataManagerTest : SysuiTestCase() {
|
|||||||
mediaDataManager.onNotificationAdded(KEY, mediaNotification)
|
mediaDataManager.onNotificationAdded(KEY, mediaNotification)
|
||||||
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
|
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
|
||||||
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
|
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
|
||||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true))
|
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
|
||||||
|
eq(false))
|
||||||
assertThat(mediaDataCaptor.value!!.active).isTrue()
|
assertThat(mediaDataCaptor.value!!.active).isTrue()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,7 +217,8 @@ class MediaDataManagerTest : SysuiTestCase() {
|
|||||||
mediaDataManager.onNotificationAdded(KEY, mediaNotification)
|
mediaDataManager.onNotificationAdded(KEY, mediaNotification)
|
||||||
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
|
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
|
||||||
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
|
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
|
||||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true))
|
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
|
||||||
|
eq(false))
|
||||||
val data = mediaDataCaptor.value
|
val data = mediaDataCaptor.value
|
||||||
assertThat(data.resumption).isFalse()
|
assertThat(data.resumption).isFalse()
|
||||||
mediaDataManager.onMediaDataLoaded(KEY, null, data.copy(resumeAction = Runnable {}))
|
mediaDataManager.onMediaDataLoaded(KEY, null, data.copy(resumeAction = Runnable {}))
|
||||||
@@ -223,7 +226,8 @@ class MediaDataManagerTest : SysuiTestCase() {
|
|||||||
mediaDataManager.onNotificationRemoved(KEY)
|
mediaDataManager.onNotificationRemoved(KEY)
|
||||||
// THEN the media data indicates that it is for resumption
|
// THEN the media data indicates that it is for resumption
|
||||||
verify(listener)
|
verify(listener)
|
||||||
.onMediaDataLoaded(eq(PACKAGE_NAME), eq(KEY), capture(mediaDataCaptor), eq(true))
|
.onMediaDataLoaded(eq(PACKAGE_NAME), eq(KEY), capture(mediaDataCaptor), eq(true),
|
||||||
|
eq(false))
|
||||||
assertThat(mediaDataCaptor.value.resumption).isTrue()
|
assertThat(mediaDataCaptor.value.resumption).isTrue()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,7 +240,8 @@ class MediaDataManagerTest : SysuiTestCase() {
|
|||||||
assertThat(backgroundExecutor.runAllReady()).isEqualTo(2)
|
assertThat(backgroundExecutor.runAllReady()).isEqualTo(2)
|
||||||
assertThat(foregroundExecutor.runAllReady()).isEqualTo(2)
|
assertThat(foregroundExecutor.runAllReady()).isEqualTo(2)
|
||||||
verify(listener)
|
verify(listener)
|
||||||
.onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true))
|
.onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
|
||||||
|
eq(false))
|
||||||
val data = mediaDataCaptor.value
|
val data = mediaDataCaptor.value
|
||||||
assertThat(data.resumption).isFalse()
|
assertThat(data.resumption).isFalse()
|
||||||
val resumableData = data.copy(resumeAction = Runnable {})
|
val resumableData = data.copy(resumeAction = Runnable {})
|
||||||
@@ -247,7 +252,8 @@ class MediaDataManagerTest : SysuiTestCase() {
|
|||||||
mediaDataManager.onNotificationRemoved(KEY)
|
mediaDataManager.onNotificationRemoved(KEY)
|
||||||
// THEN the data is for resumption and the key is migrated to the package name
|
// THEN the data is for resumption and the key is migrated to the package name
|
||||||
verify(listener)
|
verify(listener)
|
||||||
.onMediaDataLoaded(eq(PACKAGE_NAME), eq(KEY), capture(mediaDataCaptor), eq(true))
|
.onMediaDataLoaded(eq(PACKAGE_NAME), eq(KEY), capture(mediaDataCaptor), eq(true),
|
||||||
|
eq(false))
|
||||||
assertThat(mediaDataCaptor.value.resumption).isTrue()
|
assertThat(mediaDataCaptor.value.resumption).isTrue()
|
||||||
verify(listener, never()).onMediaDataRemoved(eq(KEY))
|
verify(listener, never()).onMediaDataRemoved(eq(KEY))
|
||||||
// WHEN the second is removed
|
// WHEN the second is removed
|
||||||
@@ -255,7 +261,8 @@ class MediaDataManagerTest : SysuiTestCase() {
|
|||||||
// THEN the data is for resumption and the second key is removed
|
// THEN the data is for resumption and the second key is removed
|
||||||
verify(listener)
|
verify(listener)
|
||||||
.onMediaDataLoaded(
|
.onMediaDataLoaded(
|
||||||
eq(PACKAGE_NAME), eq(PACKAGE_NAME), capture(mediaDataCaptor), eq(true))
|
eq(PACKAGE_NAME), eq(PACKAGE_NAME), capture(mediaDataCaptor), eq(true),
|
||||||
|
eq(false))
|
||||||
assertThat(mediaDataCaptor.value.resumption).isTrue()
|
assertThat(mediaDataCaptor.value.resumption).isTrue()
|
||||||
verify(listener).onMediaDataRemoved(eq(KEY_2))
|
verify(listener).onMediaDataRemoved(eq(KEY_2))
|
||||||
}
|
}
|
||||||
@@ -269,7 +276,8 @@ class MediaDataManagerTest : SysuiTestCase() {
|
|||||||
mediaDataManager.onNotificationAdded(KEY, mediaNotification)
|
mediaDataManager.onNotificationAdded(KEY, mediaNotification)
|
||||||
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
|
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
|
||||||
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
|
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
|
||||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true))
|
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
|
||||||
|
eq(false))
|
||||||
val data = mediaDataCaptor.value
|
val data = mediaDataCaptor.value
|
||||||
val dataRemoteWithResume = data.copy(resumeAction = Runnable {}, isLocalSession = false)
|
val dataRemoteWithResume = data.copy(resumeAction = Runnable {}, isLocalSession = false)
|
||||||
mediaDataManager.onMediaDataLoaded(KEY, null, dataRemoteWithResume)
|
mediaDataManager.onMediaDataLoaded(KEY, null, dataRemoteWithResume)
|
||||||
@@ -295,7 +303,8 @@ class MediaDataManagerTest : SysuiTestCase() {
|
|||||||
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
|
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
|
||||||
// THEN the media data indicates that it is for resumption
|
// THEN the media data indicates that it is for resumption
|
||||||
verify(listener)
|
verify(listener)
|
||||||
.onMediaDataLoaded(eq(PACKAGE_NAME), eq(null), capture(mediaDataCaptor), eq(true))
|
.onMediaDataLoaded(eq(PACKAGE_NAME), eq(null), capture(mediaDataCaptor), eq(true),
|
||||||
|
eq(false))
|
||||||
val data = mediaDataCaptor.value
|
val data = mediaDataCaptor.value
|
||||||
assertThat(data.resumption).isTrue()
|
assertThat(data.resumption).isTrue()
|
||||||
assertThat(data.song).isEqualTo(SESSION_TITLE)
|
assertThat(data.song).isEqualTo(SESSION_TITLE)
|
||||||
@@ -335,7 +344,8 @@ class MediaDataManagerTest : SysuiTestCase() {
|
|||||||
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
|
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
|
||||||
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
|
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
|
||||||
verify(listener)
|
verify(listener)
|
||||||
.onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true))
|
.onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
|
||||||
|
eq(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -414,7 +424,8 @@ class MediaDataManagerTest : SysuiTestCase() {
|
|||||||
mediaDataManager.onNotificationAdded(KEY, mediaNotification)
|
mediaDataManager.onNotificationAdded(KEY, mediaNotification)
|
||||||
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
|
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
|
||||||
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
|
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
|
||||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true))
|
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
|
||||||
|
eq(false))
|
||||||
assertThat(mediaDataCaptor.value!!.lastActive).isAtLeast(currentTime)
|
assertThat(mediaDataCaptor.value!!.lastActive).isAtLeast(currentTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,7 +442,8 @@ class MediaDataManagerTest : SysuiTestCase() {
|
|||||||
mediaDataManager.setTimedOut(KEY, true, true)
|
mediaDataManager.setTimedOut(KEY, true, true)
|
||||||
|
|
||||||
// THEN the last active time is not changed
|
// THEN the last active time is not changed
|
||||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY), capture(mediaDataCaptor), eq(true))
|
verify(listener).onMediaDataLoaded(eq(KEY), eq(KEY), capture(mediaDataCaptor), eq(true),
|
||||||
|
eq(false))
|
||||||
assertThat(mediaDataCaptor.value.lastActive).isLessThan(currentTime)
|
assertThat(mediaDataCaptor.value.lastActive).isLessThan(currentTime)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -442,7 +454,8 @@ class MediaDataManagerTest : SysuiTestCase() {
|
|||||||
mediaDataManager.onNotificationAdded(KEY, mediaNotification)
|
mediaDataManager.onNotificationAdded(KEY, mediaNotification)
|
||||||
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
|
assertThat(backgroundExecutor.runAllReady()).isEqualTo(1)
|
||||||
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
|
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
|
||||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true))
|
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
|
||||||
|
eq(false))
|
||||||
val data = mediaDataCaptor.value
|
val data = mediaDataCaptor.value
|
||||||
assertThat(data.resumption).isFalse()
|
assertThat(data.resumption).isFalse()
|
||||||
mediaDataManager.onMediaDataLoaded(KEY, null, data.copy(resumeAction = Runnable {}))
|
mediaDataManager.onMediaDataLoaded(KEY, null, data.copy(resumeAction = Runnable {}))
|
||||||
@@ -454,7 +467,8 @@ class MediaDataManagerTest : SysuiTestCase() {
|
|||||||
|
|
||||||
// THEN the last active time is not changed
|
// THEN the last active time is not changed
|
||||||
verify(listener)
|
verify(listener)
|
||||||
.onMediaDataLoaded(eq(PACKAGE_NAME), eq(KEY), capture(mediaDataCaptor), eq(true))
|
.onMediaDataLoaded(eq(PACKAGE_NAME), eq(KEY), capture(mediaDataCaptor), eq(true),
|
||||||
|
eq(false))
|
||||||
assertThat(mediaDataCaptor.value.resumption).isTrue()
|
assertThat(mediaDataCaptor.value.resumption).isTrue()
|
||||||
assertThat(mediaDataCaptor.value.lastActive).isLessThan(currentTime)
|
assertThat(mediaDataCaptor.value.lastActive).isLessThan(currentTime)
|
||||||
}
|
}
|
||||||
@@ -480,7 +494,8 @@ class MediaDataManagerTest : SysuiTestCase() {
|
|||||||
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
|
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
|
||||||
|
|
||||||
// THEN only the first MAX_COMPACT_ACTIONS are actually set
|
// THEN only the first MAX_COMPACT_ACTIONS are actually set
|
||||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true))
|
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor), eq(true),
|
||||||
|
eq(false))
|
||||||
assertThat(mediaDataCaptor.value.actionsToShowInCompact.size).isEqualTo(
|
assertThat(mediaDataCaptor.value.actionsToShowInCompact.size).isEqualTo(
|
||||||
MediaDataManager.MAX_COMPACT_ACTIONS)
|
MediaDataManager.MAX_COMPACT_ACTIONS)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -185,7 +185,8 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
|
|||||||
filter.onMediaDataLoaded(KEY, null, mediaData1)
|
filter.onMediaDataLoaded(KEY, null, mediaData1)
|
||||||
bgExecutor.runAllReady()
|
bgExecutor.runAllReady()
|
||||||
fgExecutor.runAllReady()
|
fgExecutor.runAllReady()
|
||||||
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true))
|
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
|
||||||
|
eq(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -207,7 +208,8 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
|
|||||||
bgExecutor.runAllReady()
|
bgExecutor.runAllReady()
|
||||||
fgExecutor.runAllReady()
|
fgExecutor.runAllReady()
|
||||||
// THEN the event is not filtered
|
// THEN the event is not filtered
|
||||||
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true))
|
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
|
||||||
|
eq(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -236,7 +238,8 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
|
|||||||
bgExecutor.runAllReady()
|
bgExecutor.runAllReady()
|
||||||
fgExecutor.runAllReady()
|
fgExecutor.runAllReady()
|
||||||
// THEN the event is not filtered
|
// THEN the event is not filtered
|
||||||
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true))
|
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
|
||||||
|
eq(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -251,14 +254,15 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
|
|||||||
bgExecutor.runAllReady()
|
bgExecutor.runAllReady()
|
||||||
fgExecutor.runAllReady()
|
fgExecutor.runAllReady()
|
||||||
// THEN the event is not filtered
|
// THEN the event is not filtered
|
||||||
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true))
|
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
|
||||||
|
eq(false))
|
||||||
// WHEN a loaded event is received that matches the local session
|
// WHEN a loaded event is received that matches the local session
|
||||||
filter.onMediaDataLoaded(KEY, null, mediaData2)
|
filter.onMediaDataLoaded(KEY, null, mediaData2)
|
||||||
bgExecutor.runAllReady()
|
bgExecutor.runAllReady()
|
||||||
fgExecutor.runAllReady()
|
fgExecutor.runAllReady()
|
||||||
// THEN the event is filtered
|
// THEN the event is filtered
|
||||||
verify(mediaListener, never()).onMediaDataLoaded(
|
verify(mediaListener, never()).onMediaDataLoaded(
|
||||||
eq(KEY), eq(null), eq(mediaData2), anyBoolean())
|
eq(KEY), eq(null), eq(mediaData2), anyBoolean(), anyBoolean())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -274,7 +278,8 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
|
|||||||
fgExecutor.runAllReady()
|
fgExecutor.runAllReady()
|
||||||
// THEN the event is not filtered because there isn't a notification for the remote
|
// THEN the event is not filtered because there isn't a notification for the remote
|
||||||
// session.
|
// session.
|
||||||
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true))
|
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
|
||||||
|
eq(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -291,14 +296,15 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
|
|||||||
bgExecutor.runAllReady()
|
bgExecutor.runAllReady()
|
||||||
fgExecutor.runAllReady()
|
fgExecutor.runAllReady()
|
||||||
// THEN the event is not filtered
|
// THEN the event is not filtered
|
||||||
verify(mediaListener).onMediaDataLoaded(eq(key1), eq(null), eq(mediaData1), eq(true))
|
verify(mediaListener).onMediaDataLoaded(eq(key1), eq(null), eq(mediaData1), eq(true),
|
||||||
|
eq(false))
|
||||||
// WHEN a loaded event is received that matches the local session
|
// WHEN a loaded event is received that matches the local session
|
||||||
filter.onMediaDataLoaded(key2, null, mediaData2)
|
filter.onMediaDataLoaded(key2, null, mediaData2)
|
||||||
bgExecutor.runAllReady()
|
bgExecutor.runAllReady()
|
||||||
fgExecutor.runAllReady()
|
fgExecutor.runAllReady()
|
||||||
// THEN the event is filtered
|
// THEN the event is filtered
|
||||||
verify(mediaListener, never())
|
verify(mediaListener, never())
|
||||||
.onMediaDataLoaded(eq(key2), eq(null), eq(mediaData2), anyBoolean())
|
.onMediaDataLoaded(eq(key2), eq(null), eq(mediaData2), anyBoolean(), anyBoolean())
|
||||||
// AND there should be a removed event for key2
|
// AND there should be a removed event for key2
|
||||||
verify(mediaListener).onMediaDataRemoved(eq(key2))
|
verify(mediaListener).onMediaDataRemoved(eq(key2))
|
||||||
}
|
}
|
||||||
@@ -317,13 +323,15 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
|
|||||||
bgExecutor.runAllReady()
|
bgExecutor.runAllReady()
|
||||||
fgExecutor.runAllReady()
|
fgExecutor.runAllReady()
|
||||||
// THEN the event is not filtered
|
// THEN the event is not filtered
|
||||||
verify(mediaListener).onMediaDataLoaded(eq(key1), eq(null), eq(mediaData1), eq(true))
|
verify(mediaListener).onMediaDataLoaded(eq(key1), eq(null), eq(mediaData1), eq(true),
|
||||||
|
eq(false))
|
||||||
// WHEN a loaded event is received that matches the remote session
|
// WHEN a loaded event is received that matches the remote session
|
||||||
filter.onMediaDataLoaded(key2, null, mediaData2)
|
filter.onMediaDataLoaded(key2, null, mediaData2)
|
||||||
bgExecutor.runAllReady()
|
bgExecutor.runAllReady()
|
||||||
fgExecutor.runAllReady()
|
fgExecutor.runAllReady()
|
||||||
// THEN the event is not filtered
|
// THEN the event is not filtered
|
||||||
verify(mediaListener).onMediaDataLoaded(eq(key2), eq(null), eq(mediaData2), eq(true))
|
verify(mediaListener).onMediaDataLoaded(eq(key2), eq(null), eq(mediaData2), eq(true),
|
||||||
|
eq(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -339,13 +347,15 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
|
|||||||
bgExecutor.runAllReady()
|
bgExecutor.runAllReady()
|
||||||
fgExecutor.runAllReady()
|
fgExecutor.runAllReady()
|
||||||
// THEN the event is not filtered
|
// THEN the event is not filtered
|
||||||
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true))
|
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
|
||||||
|
eq(false))
|
||||||
// WHEN a loaded event is received that matches the local session
|
// WHEN a loaded event is received that matches the local session
|
||||||
filter.onMediaDataLoaded(KEY, null, mediaData2)
|
filter.onMediaDataLoaded(KEY, null, mediaData2)
|
||||||
bgExecutor.runAllReady()
|
bgExecutor.runAllReady()
|
||||||
fgExecutor.runAllReady()
|
fgExecutor.runAllReady()
|
||||||
// THEN the event is not filtered
|
// THEN the event is not filtered
|
||||||
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData2), eq(true))
|
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData2), eq(true),
|
||||||
|
eq(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -363,7 +373,8 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
|
|||||||
bgExecutor.runAllReady()
|
bgExecutor.runAllReady()
|
||||||
fgExecutor.runAllReady()
|
fgExecutor.runAllReady()
|
||||||
// THEN the event is not filtered
|
// THEN the event is not filtered
|
||||||
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true))
|
verify(mediaListener).onMediaDataLoaded(eq(KEY), eq(null), eq(mediaData1), eq(true),
|
||||||
|
eq(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -385,7 +396,8 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
|
|||||||
bgExecutor.runAllReady()
|
bgExecutor.runAllReady()
|
||||||
fgExecutor.runAllReady()
|
fgExecutor.runAllReady()
|
||||||
// THEN the key migration event is fired
|
// THEN the key migration event is fired
|
||||||
verify(mediaListener).onMediaDataLoaded(eq(key2), eq(key1), eq(mediaData2), eq(true))
|
verify(mediaListener).onMediaDataLoaded(eq(key2), eq(key1), eq(mediaData2), eq(true),
|
||||||
|
eq(false))
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -415,12 +427,13 @@ public class MediaSessionBasedFilterTest : SysuiTestCase() {
|
|||||||
fgExecutor.runAllReady()
|
fgExecutor.runAllReady()
|
||||||
// THEN the key migration event is filtered
|
// THEN the key migration event is filtered
|
||||||
verify(mediaListener, never())
|
verify(mediaListener, never())
|
||||||
.onMediaDataLoaded(eq(key2), eq(null), eq(mediaData2), anyBoolean())
|
.onMediaDataLoaded(eq(key2), eq(null), eq(mediaData2), anyBoolean(), anyBoolean())
|
||||||
// WHEN a loaded event is received that matches the remote session
|
// WHEN a loaded event is received that matches the remote session
|
||||||
filter.onMediaDataLoaded(key2, null, mediaData1)
|
filter.onMediaDataLoaded(key2, null, mediaData1)
|
||||||
bgExecutor.runAllReady()
|
bgExecutor.runAllReady()
|
||||||
fgExecutor.runAllReady()
|
fgExecutor.runAllReady()
|
||||||
// THEN the key migration event is fired
|
// THEN the key migration event is fired
|
||||||
verify(mediaListener).onMediaDataLoaded(eq(key2), eq(null), eq(mediaData1), eq(true))
|
verify(mediaListener).onMediaDataLoaded(eq(key2), eq(null), eq(mediaData1), eq(true),
|
||||||
|
eq(false))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user