Revert^2 Initial data pipeline for Smartspace media recommendations data in media carousel.
This reverts commit 1967209719.
Reason for revert: Forward fix with removing the bcsmartspace dependency.
Test: Tested manually on local builds
Bug: 182813345
Change-Id: Icb8cbac4e27abfa9346f9ed0ef6513f6874db556
This commit is contained in:
@@ -276,6 +276,8 @@
|
||||
<!-- Permission to make accessibility service access Bubbles -->
|
||||
<uses-permission android:name="android.permission.ADD_TRUSTED_DISPLAY" />
|
||||
|
||||
<!-- Permission for Smartspace. -->
|
||||
<uses-permission android:name="android.permission.MANAGE_SMARTSPACE" />
|
||||
|
||||
<protected-broadcast android:name="com.android.settingslib.action.REGISTER_SLICE_RECEIVER" />
|
||||
<protected-broadcast android:name="com.android.settingslib.action.UNREGISTER_SLICE_RECEIVER" />
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.android.systemui.media
|
||||
|
||||
import android.animation.ArgbEvaluator
|
||||
import android.app.smartspace.SmartspaceTarget
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.res.ColorStateList
|
||||
@@ -201,9 +202,18 @@ class MediaCarouselController @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSmartspaceMediaDataLoaded(key: String, data: SmartspaceTarget) {
|
||||
Log.d(TAG, "My Smartspace media update is here")
|
||||
addOrUpdateSmartspaceMediaRecommendations(key, data)
|
||||
}
|
||||
|
||||
override fun onMediaDataRemoved(key: String) {
|
||||
removePlayer(key)
|
||||
}
|
||||
|
||||
override fun onSmartspaceMediaDataRemoved(key: String) {
|
||||
Log.d(TAG, "My Smartspace media removal request is received")
|
||||
}
|
||||
})
|
||||
mediaFrame.addOnLayoutChangeListener { _, _, _, _, _, _, _, _, _ ->
|
||||
// The pageIndicator is not laid out yet when we get the current state update,
|
||||
@@ -291,6 +301,10 @@ class MediaCarouselController @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun addOrUpdateSmartspaceMediaRecommendations(key: String, data: SmartspaceTarget) {
|
||||
// TODO(b/182813345): Add Smartspace media recommendation view.
|
||||
}
|
||||
|
||||
private fun removePlayer(key: String, dismissMediaData: Boolean = true) {
|
||||
val removed = MediaPlayerData.removeMediaPlayer(key)
|
||||
removed?.apply {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.media
|
||||
|
||||
import android.app.smartspace.SmartspaceTarget
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
@@ -37,10 +38,18 @@ class MediaDataCombineLatest @Inject constructor() : MediaDataManager.Listener,
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSmartspaceMediaDataLoaded(key: String, data: SmartspaceTarget) {
|
||||
listeners.toSet().forEach { it.onSmartspaceMediaDataLoaded(key, data) }
|
||||
}
|
||||
|
||||
override fun onMediaDataRemoved(key: String) {
|
||||
remove(key)
|
||||
}
|
||||
|
||||
override fun onSmartspaceMediaDataRemoved(key: String) {
|
||||
listeners.toSet().forEach { it.onSmartspaceMediaDataRemoved(key) }
|
||||
}
|
||||
|
||||
override fun onMediaDeviceChanged(
|
||||
key: String,
|
||||
oldKey: String?,
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.media
|
||||
|
||||
import android.app.smartspace.SmartspaceTarget
|
||||
import android.util.Log
|
||||
import com.android.internal.annotations.VisibleForTesting
|
||||
import com.android.systemui.broadcast.BroadcastDispatcher
|
||||
@@ -82,6 +83,10 @@ class MediaDataFilter @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSmartspaceMediaDataLoaded(key: String, data: SmartspaceTarget) {
|
||||
listeners.forEach { it.onSmartspaceMediaDataLoaded(key, data) }
|
||||
}
|
||||
|
||||
override fun onMediaDataRemoved(key: String) {
|
||||
allEntries.remove(key)
|
||||
userEntries.remove(key)?.let {
|
||||
@@ -92,6 +97,10 @@ class MediaDataFilter @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSmartspaceMediaDataRemoved(key: String) {
|
||||
listeners.forEach { it.onSmartspaceMediaDataRemoved(key) }
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
internal fun handleUserSwitched(id: Int) {
|
||||
// If the user changes, remove all current MediaData objects and inform listeners
|
||||
|
||||
@@ -18,6 +18,10 @@ package com.android.systemui.media
|
||||
|
||||
import android.app.Notification
|
||||
import android.app.PendingIntent
|
||||
import android.app.smartspace.SmartspaceConfig
|
||||
import android.app.smartspace.SmartspaceManager
|
||||
import android.app.smartspace.SmartspaceSession
|
||||
import android.app.smartspace.SmartspaceTarget
|
||||
import android.content.BroadcastReceiver
|
||||
import android.content.ContentResolver
|
||||
import android.content.Context
|
||||
@@ -33,6 +37,7 @@ import android.media.MediaMetadata
|
||||
import android.media.session.MediaController
|
||||
import android.media.session.MediaSession
|
||||
import android.net.Uri
|
||||
import android.os.Parcelable
|
||||
import android.os.UserHandle
|
||||
import android.service.notification.StatusBarNotification
|
||||
import android.text.TextUtils
|
||||
@@ -45,6 +50,7 @@ import com.android.systemui.dagger.qualifiers.Background
|
||||
import com.android.systemui.dagger.qualifiers.Main
|
||||
import com.android.systemui.dump.DumpManager
|
||||
import com.android.systemui.plugins.ActivityStarter
|
||||
import com.android.systemui.plugins.BcSmartspaceDataPlugin
|
||||
import com.android.systemui.statusbar.NotificationMediaManager.isPlayingState
|
||||
import com.android.systemui.statusbar.notification.row.HybridGroupManager
|
||||
import com.android.systemui.util.Assert
|
||||
@@ -54,6 +60,7 @@ import java.io.FileDescriptor
|
||||
import java.io.IOException
|
||||
import java.io.PrintWriter
|
||||
import java.util.concurrent.Executor
|
||||
import java.util.concurrent.Executors
|
||||
import javax.inject.Inject
|
||||
|
||||
// URI fields to try loading album art from
|
||||
@@ -99,9 +106,16 @@ class MediaDataManager(
|
||||
mediaDataCombineLatest: MediaDataCombineLatest,
|
||||
private val mediaDataFilter: MediaDataFilter,
|
||||
private val activityStarter: ActivityStarter,
|
||||
private val smartspaceMediaDataProvider: SmartspaceMediaDataProvider,
|
||||
private var useMediaResumption: Boolean,
|
||||
private val useQsMediaPlayer: Boolean
|
||||
) : Dumpable {
|
||||
) : Dumpable, BcSmartspaceDataPlugin.SmartspaceTargetListener {
|
||||
|
||||
companion object {
|
||||
// UI surface label for subscribing Smartspace updates.
|
||||
@JvmField
|
||||
val SMARTSPACE_UI_SURFACE_LABEL = "media_data_manager"
|
||||
}
|
||||
|
||||
private val themeText = com.android.settingslib.Utils.getColorAttr(context,
|
||||
com.android.internal.R.attr.textColorPrimary).defaultColor
|
||||
@@ -117,6 +131,8 @@ class MediaDataManager(
|
||||
// TODO(b/159539991#comment5): Move internal listeners to separate package.
|
||||
private val internalListeners: MutableSet<Listener> = mutableSetOf()
|
||||
private val mediaEntries: LinkedHashMap<String, MediaData> = LinkedHashMap()
|
||||
// There should ONLY be at most one Smartspace media recommendation.
|
||||
private var smartspaceMediaTarget: SmartspaceTarget? = null
|
||||
internal var appsBlockedFromResume: MutableSet<String> = Utils.getBlockedMediaApps(context)
|
||||
set(value) {
|
||||
// Update list
|
||||
@@ -128,6 +144,7 @@ class MediaDataManager(
|
||||
removeAllForPackage(it)
|
||||
}
|
||||
}
|
||||
private var smartspaceSession: SmartspaceSession? = null
|
||||
|
||||
@Inject
|
||||
constructor(
|
||||
@@ -143,11 +160,13 @@ class MediaDataManager(
|
||||
mediaDeviceManager: MediaDeviceManager,
|
||||
mediaDataCombineLatest: MediaDataCombineLatest,
|
||||
mediaDataFilter: MediaDataFilter,
|
||||
activityStarter: ActivityStarter
|
||||
activityStarter: ActivityStarter,
|
||||
smartspaceMediaDataProvider: SmartspaceMediaDataProvider
|
||||
) : this(context, backgroundExecutor, foregroundExecutor, mediaControllerFactory,
|
||||
broadcastDispatcher, dumpManager, mediaTimeoutListener, mediaResumeListener,
|
||||
mediaSessionBasedFilter, mediaDeviceManager, mediaDataCombineLatest, mediaDataFilter,
|
||||
activityStarter, Utils.useMediaResumption(context), Utils.useQsMediaPlayer(context))
|
||||
activityStarter, smartspaceMediaDataProvider, Utils.useMediaResumption(context),
|
||||
Utils.useQsMediaPlayer(context))
|
||||
|
||||
private val appChangeReceiver = object : BroadcastReceiver() {
|
||||
override fun onReceive(context: Context, intent: Intent) {
|
||||
@@ -200,9 +219,31 @@ class MediaDataManager(
|
||||
}
|
||||
// BroadcastDispatcher does not allow filters with data schemes
|
||||
context.registerReceiver(appChangeReceiver, uninstallFilter)
|
||||
|
||||
// Register for Smartspace data updates.
|
||||
smartspaceMediaDataProvider.registerListener(this)
|
||||
val smartspaceManager: SmartspaceManager =
|
||||
context.getSystemService(SmartspaceManager::class.java)
|
||||
smartspaceSession = smartspaceManager.createSmartspaceSession(
|
||||
SmartspaceConfig.Builder(context, SMARTSPACE_UI_SURFACE_LABEL).build())
|
||||
smartspaceSession?.let {
|
||||
it.registerSmartspaceUpdates(
|
||||
// Use a new thread listening to Smartspace updates instead of using the existing
|
||||
// backgroundExecutor. SmartspaceSession has scheduled routine updates which can be
|
||||
// unpredictable on test simulators, using the backgroundExecutor makes it's hard to
|
||||
// test the threads numbers.
|
||||
// Switch to use backgroundExecutor when SmartspaceSession has a good way to be
|
||||
// mocked.
|
||||
Executors.newCachedThreadPool(),
|
||||
SmartspaceSession.Callback { targets ->
|
||||
smartspaceMediaDataProvider.onTargetsAvailable(targets)
|
||||
})
|
||||
}
|
||||
smartspaceSession?.let { it.requestSmartspaceUpdate() }
|
||||
}
|
||||
|
||||
fun destroy() {
|
||||
smartspaceMediaDataProvider.unregisterListener(this)
|
||||
context.unregisterReceiver(appChangeReceiver)
|
||||
}
|
||||
|
||||
@@ -309,7 +350,7 @@ class MediaDataManager(
|
||||
private fun addInternalListener(listener: Listener) = internalListeners.add(listener)
|
||||
|
||||
/**
|
||||
* Notify internal listeners of loaded event.
|
||||
* Notify internal listeners of media loaded event.
|
||||
*
|
||||
* External listeners registered with [addListener] will be notified after the event propagates
|
||||
* through the internal listener pipeline.
|
||||
@@ -319,7 +360,17 @@ class MediaDataManager(
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify internal listeners of removed event.
|
||||
* Notify internal listeners of Smartspace media loaded event.
|
||||
*
|
||||
* External listeners registered with [addListener] will be notified after the event propagates
|
||||
* through the internal listener pipeline.
|
||||
*/
|
||||
private fun notifySmartspaceMediaDataLoaded(key: String, info: SmartspaceTarget) {
|
||||
internalListeners.forEach { it.onSmartspaceMediaDataLoaded(key, info) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify internal listeners of media removed event.
|
||||
*
|
||||
* External listeners registered with [addListener] will be notified after the event propagates
|
||||
* through the internal listener pipeline.
|
||||
@@ -328,6 +379,16 @@ class MediaDataManager(
|
||||
internalListeners.forEach { it.onMediaDataRemoved(key) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify internal listeners of Smartspace media removed event.
|
||||
*
|
||||
* External listeners registered with [addListener] will be notified after the event propagates
|
||||
* through the internal listener pipeline.
|
||||
*/
|
||||
private fun notifySmartspaceMediaDataRemoved(key: String) {
|
||||
internalListeners.forEach { it.onSmartspaceMediaDataRemoved(key) }
|
||||
}
|
||||
|
||||
/**
|
||||
* Called whenever the player has been paused or stopped for a while, or swiped from QQS.
|
||||
* This will make the player not active anymore, hiding it from QQS and Keyguard.
|
||||
@@ -601,6 +662,49 @@ class MediaDataManager(
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSmartspaceTargetsUpdated(targets: List<Parcelable>) {
|
||||
Log.d(TAG, "My Smartspace media updates are here")
|
||||
val mediaTargets = targets.filterIsInstance<SmartspaceTarget>()
|
||||
when (mediaTargets.size) {
|
||||
0 -> {
|
||||
Log.d(TAG, "Empty Smartspace media target")
|
||||
smartspaceMediaTarget?.let {
|
||||
notifySmartspaceMediaDataRemoved(it.smartspaceTargetId)
|
||||
}
|
||||
smartspaceMediaTarget = null
|
||||
}
|
||||
1 -> {
|
||||
// TODO(b/182811956): Reactivate the resumable media sessions whose last active
|
||||
// time is within 3 hours.
|
||||
// TODO(b/182813365): Wire this up with MediaTimeoutListener so the session can be
|
||||
// expired after 30 seconds.
|
||||
val newMediaTarget = mediaTargets.get(0)
|
||||
if (smartspaceMediaTarget != null &&
|
||||
smartspaceMediaTarget!!.smartspaceTargetId ==
|
||||
newMediaTarget.smartspaceTargetId) {
|
||||
// The same Smartspace updates can be received. Only send the first one.
|
||||
Log.d(TAG, "Same Smartspace media update exists. Skip loading data.")
|
||||
} else {
|
||||
smartspaceMediaTarget?.let {
|
||||
notifySmartspaceMediaDataRemoved(it.smartspaceTargetId)
|
||||
}
|
||||
notifySmartspaceMediaDataLoaded(
|
||||
newMediaTarget.smartspaceTargetId, newMediaTarget)
|
||||
smartspaceMediaTarget = newMediaTarget
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
// There should NOT be more than 1 Smartspace media update. When it happens, it
|
||||
// indicates a bad state or an error. Reset the status accordingly.
|
||||
Log.wtf(TAG, "More than 1 Smartspace Media Update. Resetting the status...")
|
||||
smartspaceMediaTarget?.let {
|
||||
notifySmartspaceMediaDataRemoved(it.smartspaceTargetId)
|
||||
}
|
||||
smartspaceMediaTarget = null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun onNotificationRemoved(key: String) {
|
||||
Assert.isMainThread()
|
||||
val removed = mediaEntries.remove(key)
|
||||
@@ -685,10 +789,16 @@ class MediaDataManager(
|
||||
*/
|
||||
fun onMediaDataLoaded(key: String, oldKey: String?, data: MediaData) {}
|
||||
|
||||
/** Called whenever there's new Smartspace media data loaded. */
|
||||
fun onSmartspaceMediaDataLoaded(key: String, data: SmartspaceTarget) {}
|
||||
|
||||
/**
|
||||
* Called whenever a previously existing Media notification was removed
|
||||
*/
|
||||
fun onMediaDataRemoved(key: String) {}
|
||||
|
||||
/** Called whenever a previously existing Smartspace media data was removed. */
|
||||
fun onSmartspaceMediaDataRemoved(key: String) {}
|
||||
}
|
||||
|
||||
override fun dump(fd: FileDescriptor, pw: PrintWriter, args: Array<out String>) {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.android.systemui.media
|
||||
|
||||
import android.app.smartspace.SmartspaceTarget
|
||||
import android.graphics.Rect
|
||||
import android.util.ArraySet
|
||||
import android.view.View
|
||||
@@ -53,9 +54,17 @@ class MediaHost constructor(
|
||||
updateViewVisibility()
|
||||
}
|
||||
|
||||
override fun onSmartspaceMediaDataLoaded(key: String, data: SmartspaceTarget) {
|
||||
updateViewVisibility()
|
||||
}
|
||||
|
||||
override fun onMediaDataRemoved(key: String) {
|
||||
updateViewVisibility()
|
||||
}
|
||||
|
||||
override fun onSmartspaceMediaDataRemoved(key: String) {
|
||||
updateViewVisibility()
|
||||
}
|
||||
}
|
||||
|
||||
fun addVisibilityChangeListener(listener: (Boolean) -> Unit) {
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.media
|
||||
|
||||
import android.app.smartspace.SmartspaceTarget
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.media.session.MediaController
|
||||
@@ -134,6 +135,12 @@ class MediaSessionBasedFilter @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSmartspaceMediaDataLoaded(key: String, data: SmartspaceTarget) {
|
||||
backgroundExecutor.execute {
|
||||
dispatchSmartspaceMediaDataLoaded(key, data)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onMediaDataRemoved(key: String) {
|
||||
// Queue on background thread to ensure ordering of loaded and removed events is maintained.
|
||||
backgroundExecutor.execute {
|
||||
@@ -142,6 +149,12 @@ class MediaSessionBasedFilter @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
override fun onSmartspaceMediaDataRemoved(key: String) {
|
||||
backgroundExecutor.execute {
|
||||
dispatchSmartspaceMediaDataRemoved(key)
|
||||
}
|
||||
}
|
||||
|
||||
private fun dispatchMediaDataLoaded(key: String, oldKey: String?, info: MediaData) {
|
||||
foregroundExecutor.execute {
|
||||
listeners.toSet().forEach { it.onMediaDataLoaded(key, oldKey, info) }
|
||||
@@ -154,6 +167,18 @@ class MediaSessionBasedFilter @Inject constructor(
|
||||
}
|
||||
}
|
||||
|
||||
private fun dispatchSmartspaceMediaDataLoaded(key: String, info: SmartspaceTarget) {
|
||||
foregroundExecutor.execute {
|
||||
listeners.toSet().forEach { it.onSmartspaceMediaDataLoaded(key, info) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun dispatchSmartspaceMediaDataRemoved(key: String) {
|
||||
foregroundExecutor.execute {
|
||||
listeners.toSet().forEach { it.onSmartspaceMediaDataRemoved(key) }
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleControllersChanged(controllers: List<MediaController>) {
|
||||
packageControllers.clear()
|
||||
controllers.forEach {
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.android.systemui.media
|
||||
|
||||
import android.app.smartspace.SmartspaceTarget
|
||||
import com.android.systemui.plugins.BcSmartspaceDataPlugin
|
||||
import com.android.systemui.plugins.BcSmartspaceDataPlugin.SmartspaceTargetListener
|
||||
import javax.inject.Inject
|
||||
|
||||
/** Provides SmartspaceTargets of media types for SystemUI media control. */
|
||||
class SmartspaceMediaDataProvider @Inject constructor() : BcSmartspaceDataPlugin {
|
||||
|
||||
private val smartspaceMediaTargetListeners: MutableList<SmartspaceTargetListener> =
|
||||
mutableListOf()
|
||||
private var smartspaceMediaTargets: List<SmartspaceTarget> = listOf()
|
||||
|
||||
override fun registerListener(smartspaceTargetListener: SmartspaceTargetListener) {
|
||||
smartspaceMediaTargetListeners.add(smartspaceTargetListener)
|
||||
}
|
||||
|
||||
override fun unregisterListener(smartspaceTargetListener: SmartspaceTargetListener?) {
|
||||
smartspaceMediaTargetListeners.remove(smartspaceTargetListener)
|
||||
}
|
||||
|
||||
/** Updates Smartspace data and propagates it to any listeners. */
|
||||
fun onTargetsAvailable(targets: List<SmartspaceTarget>) {
|
||||
// Filter out non-media targets.
|
||||
val mediaTargets = mutableListOf<SmartspaceTarget>()
|
||||
for (target in targets) {
|
||||
val smartspaceTarget = target
|
||||
if (smartspaceTarget.featureType == SmartspaceTarget.FEATURE_MEDIA) {
|
||||
mediaTargets.add(smartspaceTarget)
|
||||
}
|
||||
}
|
||||
|
||||
smartspaceMediaTargets = mediaTargets
|
||||
smartspaceMediaTargetListeners.forEach {
|
||||
it.onSmartspaceTargetsUpdated(smartspaceMediaTargets)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -24,6 +24,7 @@ import android.annotation.MainThread;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.app.Notification;
|
||||
import android.app.smartspace.SmartspaceTarget;
|
||||
import android.content.Context;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.drawable.BitmapDrawable;
|
||||
@@ -247,6 +248,11 @@ public class NotificationMediaManager implements Dumpable {
|
||||
@Nullable String oldKey, @NonNull MediaData data) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSmartspaceMediaDataLoaded(@NonNull String key,
|
||||
@NonNull SmartspaceTarget data) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaDataRemoved(@NonNull String key) {
|
||||
mNotifPipeline.getAllNotifs()
|
||||
@@ -260,6 +266,9 @@ public class NotificationMediaManager implements Dumpable {
|
||||
getDismissedByUserStats(entry));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSmartspaceMediaDataRemoved(@NonNull String key) {}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -312,6 +321,11 @@ public class NotificationMediaManager implements Dumpable {
|
||||
@Nullable String oldKey, @NonNull MediaData data) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSmartspaceMediaDataLoaded(@NonNull String key,
|
||||
@NonNull SmartspaceTarget data) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMediaDataRemoved(@NonNull String key) {
|
||||
NotificationEntry entry = mEntryManager.getPendingOrActiveNotif(key);
|
||||
@@ -323,6 +337,9 @@ public class NotificationMediaManager implements Dumpable {
|
||||
NotificationListenerService.REASON_CANCEL);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSmartspaceMediaDataRemoved(@NonNull String key) {}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.android.systemui.media
|
||||
|
||||
import android.app.Notification.MediaStyle
|
||||
import android.app.PendingIntent
|
||||
import android.app.smartspace.SmartspaceTarget
|
||||
import android.graphics.Bitmap
|
||||
import android.media.MediaDescription
|
||||
import android.media.MediaMetadata
|
||||
@@ -39,6 +40,8 @@ import org.mockito.Mockito.`when` as whenever
|
||||
|
||||
private const val KEY = "KEY"
|
||||
private const val KEY_2 = "KEY_2"
|
||||
private const val KEY_MEDIA_SMARTSPACE = "MEDIA_SMARTSPACE_ID"
|
||||
private const val KEY_NONE_MEDIA_SMARTSPACE = "NONE_MEDIA_SMARTSPACE_ID"
|
||||
private const val PACKAGE_NAME = "com.android.systemui"
|
||||
private const val APP_NAME = "SystemUI"
|
||||
private const val SESSION_ARTIST = "artist"
|
||||
@@ -72,6 +75,8 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
@Mock lateinit var listener: MediaDataManager.Listener
|
||||
@Mock lateinit var pendingIntent: PendingIntent
|
||||
@Mock lateinit var activityStarter: ActivityStarter
|
||||
lateinit var smartspaceMediaDataProvider: SmartspaceMediaDataProvider
|
||||
@Mock lateinit var mediaSmartspaceTarget: SmartspaceTarget
|
||||
lateinit var mediaDataManager: MediaDataManager
|
||||
lateinit var mediaNotification: StatusBarNotification
|
||||
@Captor lateinit var mediaDataCaptor: ArgumentCaptor<MediaData>
|
||||
@@ -80,6 +85,7 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
fun setup() {
|
||||
foregroundExecutor = FakeExecutor(FakeSystemClock())
|
||||
backgroundExecutor = FakeExecutor(FakeSystemClock())
|
||||
smartspaceMediaDataProvider = SmartspaceMediaDataProvider()
|
||||
mediaDataManager = MediaDataManager(
|
||||
context = context,
|
||||
backgroundExecutor = backgroundExecutor,
|
||||
@@ -94,6 +100,7 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
mediaDataCombineLatest = mediaDataCombineLatest,
|
||||
mediaDataFilter = mediaDataFilter,
|
||||
activityStarter = activityStarter,
|
||||
smartspaceMediaDataProvider = smartspaceMediaDataProvider,
|
||||
useMediaResumption = true,
|
||||
useQsMediaPlayer = true
|
||||
)
|
||||
@@ -117,6 +124,9 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
// mock, it doesn't pass those events along the chain to the external listeners. So, just
|
||||
// treat mediaSessionBasedFilter as a listener for testing.
|
||||
listener = mediaSessionBasedFilter
|
||||
|
||||
whenever(mediaSmartspaceTarget.smartspaceTargetId).thenReturn(KEY_MEDIA_SMARTSPACE)
|
||||
whenever(mediaSmartspaceTarget.featureType).thenReturn(SmartspaceTarget.FEATURE_MEDIA)
|
||||
}
|
||||
|
||||
@After
|
||||
@@ -320,4 +330,24 @@ class MediaDataManagerTest : SysuiTestCase() {
|
||||
assertThat(foregroundExecutor.runAllReady()).isEqualTo(1)
|
||||
verify(listener).onMediaDataLoaded(eq(KEY), eq(null), capture(mediaDataCaptor))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnSmartspaceMediaDataLoaded_hasNewMediaTarget_callsListener() {
|
||||
smartspaceMediaDataProvider.onTargetsAvailable(listOf(mediaSmartspaceTarget))
|
||||
verify(listener).onSmartspaceMediaDataLoaded(
|
||||
eq(KEY_MEDIA_SMARTSPACE), eq(mediaSmartspaceTarget))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnSmartspaceMediaDataLoaded_hasNoneMediaTarget_notCallsListener() {
|
||||
smartspaceMediaDataProvider.onTargetsAvailable(listOf())
|
||||
verify(listener, never()).onSmartspaceMediaDataLoaded(anyObject(), anyObject())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testOnSmartspaceMediaDataLoaded_hasNoneMediaTarget_callsRemoveListener() {
|
||||
smartspaceMediaDataProvider.onTargetsAvailable(listOf(mediaSmartspaceTarget))
|
||||
smartspaceMediaDataProvider.onTargetsAvailable(listOf())
|
||||
verify(listener).onSmartspaceMediaDataRemoved(KEY_MEDIA_SMARTSPACE)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user