Loading packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java +2 −29 Original line number Diff line number Diff line Loading @@ -96,13 +96,13 @@ public class MediaControlPanel { */ @Inject public MediaControlPanel(Context context, @Background Executor backgroundExecutor, ActivityStarter activityStarter, MediaHostStatesManager mediaHostStatesManager, ActivityStarter activityStarter, MediaViewController mediaViewController, SeekBarViewModel seekBarViewModel) { mContext = context; mBackgroundExecutor = backgroundExecutor; mActivityStarter = activityStarter; mSeekBarViewModel = seekBarViewModel; mMediaViewController = new MediaViewController(context, mediaHostStatesManager); mMediaViewController = mediaViewController; loadDimens(); } Loading Loading @@ -365,14 +365,6 @@ public class MediaControlPanel { return artwork; } /** * Return the token for the current media session * @return the token */ public MediaSession.Token getMediaSessionToken() { return mToken; } /** * Get the current media controller * @return the controller Loading @@ -381,25 +373,6 @@ public class MediaControlPanel { return mController; } /** * Get the name of the package associated with the current media controller * @return the package name, or null if no controller */ public String getMediaPlayerPackage() { if (mController == null) { return null; } return mController.getPackageName(); } /** * Check whether this player has an attached media session. * @return whether there is a controller with a current media session. */ public boolean hasMediaSession() { return mController != null && mController.getPlaybackState() != null; } /** * Check whether the media controlled by this player is currently playing * @return whether it is playing, or false if no controller information Loading packages/SystemUI/src/com/android/systemui/media/MediaData.kt +47 −1 Original line number Diff line number Diff line Loading @@ -25,19 +25,65 @@ import android.media.session.MediaSession data class MediaData( val initialized: Boolean = false, val backgroundColor: Int, /** * App name that will be displayed on the player. */ val app: String?, /** * Icon shown on player, close to app name. */ val appIcon: Drawable?, /** * Artist name. */ val artist: CharSequence?, /** * Song name. */ val song: CharSequence?, /** * Album artwork. */ val artwork: Icon?, /** * List of actions that can be performed on the player: prev, next, play, pause, etc. */ val actions: List<MediaAction>, /** * Same as above, but shown on smaller versions of the player, like in QQS or keyguard. */ val actionsToShowInCompact: List<Int>, /** * Package name of the app that's posting the media. */ val packageName: String, /** * Unique media session identifier. */ val token: MediaSession.Token?, /** * Action to perform when the player is tapped. * This is unrelated to {@link #actions}. */ val clickIntent: PendingIntent?, /** * Where the media is playing: phone, headphones, ear buds, remote session. */ val device: MediaDeviceData?, /** * When active, a player will be displayed on keyguard and quick-quick settings. * This is unrelated to the stream being playing or not, a player will not be active if * timed out, or in resumption mode. */ var active: Boolean, /** * Action that should be performed to restart a non active session. */ var resumeAction: Runnable?, val notificationKey: String = "INVALID", /** * Notification key for cancelling a media player after a timeout (when not using resumption.) */ val notificationKey: String? = null, var hasCheckedForResume: Boolean = false ) Loading packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt +26 −25 Original line number Diff line number Diff line Loading @@ -67,7 +67,7 @@ private const val LUMINOSITY_THRESHOLD = 0.05f private const val SATURATION_MULTIPLIER = 0.8f private val LOADING = MediaData(false, 0, null, null, null, null, null, emptyList(), emptyList(), "INVALID", null, null, null, null) emptyList(), emptyList(), "INVALID", null, null, null, true, null) fun isMediaNotification(sbn: StatusBarNotification): Boolean { if (!sbn.notification.hasMediaSession()) { Loading @@ -88,12 +88,12 @@ fun isMediaNotification(sbn: StatusBarNotification): Boolean { class MediaDataManager @Inject constructor( private val context: Context, private val mediaControllerFactory: MediaControllerFactory, private val mediaTimeoutListener: MediaTimeoutListener, private val notificationEntryManager: NotificationEntryManager, private val mediaResumeListener: MediaResumeListener, @Background private val backgroundExecutor: Executor, @Main private val foregroundExecutor: Executor, private val broadcastDispatcher: BroadcastDispatcher broadcastDispatcher: BroadcastDispatcher, mediaTimeoutListener: MediaTimeoutListener, mediaResumeListener: MediaResumeListener ) { private val listeners: MutableSet<Listener> = mutableSetOf() Loading Loading @@ -131,7 +131,6 @@ class MediaDataManager @Inject constructor( mediaTimeoutListener.timeoutCallback = { token: String, timedOut: Boolean -> setTimedOut(token, timedOut) } addListener(mediaTimeoutListener) if (useMediaResumption) { mediaResumeListener.addTrackToResumeCallback = { desc: MediaDescription, resumeAction: Runnable, token: MediaSession.Token, appName: String, Loading Loading @@ -215,7 +214,7 @@ class MediaDataManager @Inject constructor( mediaEntries.put(packageName, resumeData) } backgroundExecutor.execute { loadMediaDataInBg(desc, action, token, appName, appIntent, packageName) loadMediaDataInBgForResumption(desc, action, token, appName, appIntent, packageName) } } Loading Loading @@ -255,16 +254,21 @@ class MediaDataManager @Inject constructor( fun removeListener(listener: Listener) = listeners.remove(listener) private fun setTimedOut(token: String, timedOut: Boolean) { if (!timedOut) { mediaEntries[token]?.let { if (Utils.useMediaResumption(context)) { if (it.active == !timedOut) { return } mediaEntries[token]?.let { it.active = !timedOut onMediaDataLoaded(token, token, it) } else { notificationEntryManager.removeNotification(it.notificationKey, null /* ranking */, UNDEFINED_DISMISS_REASON) } } } private fun loadMediaDataInBg( private fun loadMediaDataInBgForResumption( desc: MediaDescription, resumeAction: Runnable, token: MediaSession.Token, Loading @@ -272,11 +276,6 @@ class MediaDataManager @Inject constructor( appIntent: PendingIntent, packageName: String ) { if (resumeAction == null) { Log.e(TAG, "Resume action cannot be null") return } if (TextUtils.isEmpty(desc.title)) { Log.e(TAG, "Description incomplete") return Loading @@ -299,7 +298,8 @@ class MediaDataManager @Inject constructor( foregroundExecutor.execute { onMediaDataLoaded(packageName, null, MediaData(true, Color.DKGRAY, appName, null, desc.subtitle, desc.title, artworkIcon, listOf(mediaAction), listOf(0), packageName, token, appIntent, null, resumeAction, packageName)) packageName, token, appIntent, device = null, active = false, resumeAction = resumeAction)) } } Loading Loading @@ -430,7 +430,8 @@ class MediaDataManager @Inject constructor( foregroundExecutor.execute { onMediaDataLoaded(key, oldKey, MediaData(true, bgColor, app, smallIconDrawable, artist, song, artWorkIcon, actionIcons, actionsToShowCollapsed, sbn.packageName, token, notif.contentIntent, null, resumeAction, key)) notif.contentIntent, null, active = true, resumeAction = resumeAction, notificationKey = key)) } } Loading Loading @@ -528,13 +529,13 @@ class MediaDataManager @Inject constructor( /** * Are there any media notifications active? */ fun hasActiveMedia() = mediaEntries.any({ isActive(it.value) }) fun hasActiveMedia() = mediaEntries.any { it.value.active } fun isActive(data: MediaData): Boolean { if (data.token == null) { fun isActive(token: MediaSession.Token?): Boolean { if (token == null) { return false } val controller = mediaControllerFactory.create(data.token) val controller = mediaControllerFactory.create(token) val state = controller?.playbackState?.state return state != null && NotificationMediaManager.isActiveState(state) } Loading @@ -542,7 +543,7 @@ class MediaDataManager @Inject constructor( /** * Are there any media entries, including resume controls? */ fun hasAnyMedia() = mediaEntries.isNotEmpty() fun hasAnyMedia() = if (useMediaResumption) mediaEntries.isNotEmpty() else hasActiveMedia() interface Listener { Loading packages/SystemUI/src/com/android/systemui/media/MediaHost.kt +60 −6 Original line number Diff line number Diff line package com.android.systemui.media import android.graphics.PointF import android.graphics.Rect import android.view.View import android.view.View.OnAttachStateChangeListener Loading @@ -20,8 +21,6 @@ class MediaHost @Inject constructor( var location: Int = -1 private set var visibleChangedListener: ((Boolean) -> Unit)? = null var visible: Boolean = false private set private val tmpLocationOnScreen: IntArray = intArrayOf(0, 0) Loading Loading @@ -109,16 +108,17 @@ class MediaHost @Inject constructor( } private fun updateViewVisibility() { if (showsOnlyActiveMedia) { visible = mediaDataManager.hasActiveMedia() visible = if (showsOnlyActiveMedia) { mediaDataManager.hasActiveMedia() } else { visible = mediaDataManager.hasAnyMedia() mediaDataManager.hasAnyMedia() } hostView.visibility = if (visible) View.VISIBLE else View.GONE visibleChangedListener?.invoke(visible) } class MediaHostStateHolder @Inject constructor() : MediaHostState { private var gonePivot: PointF = PointF() override var measurementInput: MeasurementInput? = null set(value) { Loading @@ -144,6 +144,25 @@ class MediaHost @Inject constructor( } } override var visible: Boolean = true set(value) { if (field == value) { return } field = value changedListener?.invoke() } override fun getPivotX(): Float = gonePivot.x override fun getPivotY(): Float = gonePivot.y override fun setGonePivot(x: Float, y: Float) { if (gonePivot.equals(x, y)) { return } gonePivot.set(x, y) changedListener?.invoke() } /** * A listener for all changes. This won't be copied over when invoking [copy] */ Loading @@ -157,6 +176,8 @@ class MediaHost @Inject constructor( mediaHostState.expansion = expansion mediaHostState.showsOnlyActiveMedia = showsOnlyActiveMedia mediaHostState.measurementInput = measurementInput?.copy() mediaHostState.visible = visible mediaHostState.gonePivot.set(gonePivot) return mediaHostState } Loading @@ -173,6 +194,12 @@ class MediaHost @Inject constructor( if (showsOnlyActiveMedia != other.showsOnlyActiveMedia) { return false } if (visible != other.visible) { return false } if (!gonePivot.equals(other.getPivotX(), other.getPivotY())) { return false } return true } Loading @@ -180,6 +207,8 @@ class MediaHost @Inject constructor( var result = measurementInput?.hashCode() ?: 0 result = 31 * result + expansion.hashCode() result = 31 * result + showsOnlyActiveMedia.hashCode() result = 31 * result + if (visible) 1 else 2 result = 31 * result + gonePivot.hashCode() return result } } Loading @@ -194,7 +223,8 @@ interface MediaHostState { var measurementInput: MeasurementInput? /** * The expansion of the player, 0 for fully collapsed, 1 for fully expanded * The expansion of the player, 0 for fully collapsed (up to 3 actions), 1 for fully expanded * (up to 5 actions.) */ var expansion: Float Loading @@ -203,6 +233,30 @@ interface MediaHostState { */ var showsOnlyActiveMedia: Boolean /** * If the view should be VISIBLE or GONE. */ var visible: Boolean /** * Sets the pivot point when clipping the height or width. * Clipping happens when animating visibility when we're visible in QS but not on QQS, * for example. */ fun setGonePivot(x: Float, y: Float) /** * x position of pivot, from 0 to 1 * @see [setGonePivot] */ fun getPivotX(): Float /** * y position of pivot, from 0 to 1 * @see [setGonePivot] */ fun getPivotY(): Float /** * Get a copy of this view state, deepcopying all appropriate members */ Loading packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt +7 −2 Original line number Diff line number Diff line Loading @@ -43,6 +43,11 @@ class MediaTimeoutListener @Inject constructor( private val mediaListeners: MutableMap<String, PlaybackStateListener> = mutableMapOf() /** * Callback representing that a media object is now expired: * @param token Media session unique identifier * @param pauseTimeuot True when expired for {@code PAUSED_MEDIA_TIMEOUT} */ lateinit var timeoutCallback: (String, Boolean) -> Unit override fun onMediaDataLoaded(key: String, oldKey: String?, data: MediaData) { Loading Loading @@ -112,11 +117,11 @@ class MediaTimeoutListener @Inject constructor( } } private fun expireMediaTimeout(mediaNotificationKey: String, reason: String) { private fun expireMediaTimeout(mediaKey: String, reason: String) { cancellation?.apply { if (DEBUG) { Log.v(TAG, "media timeout cancelled for $mediaNotificationKey, reason: $reason") "media timeout cancelled for $mediaKey, reason: $reason") } run() } Loading Loading
packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java +2 −29 Original line number Diff line number Diff line Loading @@ -96,13 +96,13 @@ public class MediaControlPanel { */ @Inject public MediaControlPanel(Context context, @Background Executor backgroundExecutor, ActivityStarter activityStarter, MediaHostStatesManager mediaHostStatesManager, ActivityStarter activityStarter, MediaViewController mediaViewController, SeekBarViewModel seekBarViewModel) { mContext = context; mBackgroundExecutor = backgroundExecutor; mActivityStarter = activityStarter; mSeekBarViewModel = seekBarViewModel; mMediaViewController = new MediaViewController(context, mediaHostStatesManager); mMediaViewController = mediaViewController; loadDimens(); } Loading Loading @@ -365,14 +365,6 @@ public class MediaControlPanel { return artwork; } /** * Return the token for the current media session * @return the token */ public MediaSession.Token getMediaSessionToken() { return mToken; } /** * Get the current media controller * @return the controller Loading @@ -381,25 +373,6 @@ public class MediaControlPanel { return mController; } /** * Get the name of the package associated with the current media controller * @return the package name, or null if no controller */ public String getMediaPlayerPackage() { if (mController == null) { return null; } return mController.getPackageName(); } /** * Check whether this player has an attached media session. * @return whether there is a controller with a current media session. */ public boolean hasMediaSession() { return mController != null && mController.getPlaybackState() != null; } /** * Check whether the media controlled by this player is currently playing * @return whether it is playing, or false if no controller information Loading
packages/SystemUI/src/com/android/systemui/media/MediaData.kt +47 −1 Original line number Diff line number Diff line Loading @@ -25,19 +25,65 @@ import android.media.session.MediaSession data class MediaData( val initialized: Boolean = false, val backgroundColor: Int, /** * App name that will be displayed on the player. */ val app: String?, /** * Icon shown on player, close to app name. */ val appIcon: Drawable?, /** * Artist name. */ val artist: CharSequence?, /** * Song name. */ val song: CharSequence?, /** * Album artwork. */ val artwork: Icon?, /** * List of actions that can be performed on the player: prev, next, play, pause, etc. */ val actions: List<MediaAction>, /** * Same as above, but shown on smaller versions of the player, like in QQS or keyguard. */ val actionsToShowInCompact: List<Int>, /** * Package name of the app that's posting the media. */ val packageName: String, /** * Unique media session identifier. */ val token: MediaSession.Token?, /** * Action to perform when the player is tapped. * This is unrelated to {@link #actions}. */ val clickIntent: PendingIntent?, /** * Where the media is playing: phone, headphones, ear buds, remote session. */ val device: MediaDeviceData?, /** * When active, a player will be displayed on keyguard and quick-quick settings. * This is unrelated to the stream being playing or not, a player will not be active if * timed out, or in resumption mode. */ var active: Boolean, /** * Action that should be performed to restart a non active session. */ var resumeAction: Runnable?, val notificationKey: String = "INVALID", /** * Notification key for cancelling a media player after a timeout (when not using resumption.) */ val notificationKey: String? = null, var hasCheckedForResume: Boolean = false ) Loading
packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt +26 −25 Original line number Diff line number Diff line Loading @@ -67,7 +67,7 @@ private const val LUMINOSITY_THRESHOLD = 0.05f private const val SATURATION_MULTIPLIER = 0.8f private val LOADING = MediaData(false, 0, null, null, null, null, null, emptyList(), emptyList(), "INVALID", null, null, null, null) emptyList(), emptyList(), "INVALID", null, null, null, true, null) fun isMediaNotification(sbn: StatusBarNotification): Boolean { if (!sbn.notification.hasMediaSession()) { Loading @@ -88,12 +88,12 @@ fun isMediaNotification(sbn: StatusBarNotification): Boolean { class MediaDataManager @Inject constructor( private val context: Context, private val mediaControllerFactory: MediaControllerFactory, private val mediaTimeoutListener: MediaTimeoutListener, private val notificationEntryManager: NotificationEntryManager, private val mediaResumeListener: MediaResumeListener, @Background private val backgroundExecutor: Executor, @Main private val foregroundExecutor: Executor, private val broadcastDispatcher: BroadcastDispatcher broadcastDispatcher: BroadcastDispatcher, mediaTimeoutListener: MediaTimeoutListener, mediaResumeListener: MediaResumeListener ) { private val listeners: MutableSet<Listener> = mutableSetOf() Loading Loading @@ -131,7 +131,6 @@ class MediaDataManager @Inject constructor( mediaTimeoutListener.timeoutCallback = { token: String, timedOut: Boolean -> setTimedOut(token, timedOut) } addListener(mediaTimeoutListener) if (useMediaResumption) { mediaResumeListener.addTrackToResumeCallback = { desc: MediaDescription, resumeAction: Runnable, token: MediaSession.Token, appName: String, Loading Loading @@ -215,7 +214,7 @@ class MediaDataManager @Inject constructor( mediaEntries.put(packageName, resumeData) } backgroundExecutor.execute { loadMediaDataInBg(desc, action, token, appName, appIntent, packageName) loadMediaDataInBgForResumption(desc, action, token, appName, appIntent, packageName) } } Loading Loading @@ -255,16 +254,21 @@ class MediaDataManager @Inject constructor( fun removeListener(listener: Listener) = listeners.remove(listener) private fun setTimedOut(token: String, timedOut: Boolean) { if (!timedOut) { mediaEntries[token]?.let { if (Utils.useMediaResumption(context)) { if (it.active == !timedOut) { return } mediaEntries[token]?.let { it.active = !timedOut onMediaDataLoaded(token, token, it) } else { notificationEntryManager.removeNotification(it.notificationKey, null /* ranking */, UNDEFINED_DISMISS_REASON) } } } private fun loadMediaDataInBg( private fun loadMediaDataInBgForResumption( desc: MediaDescription, resumeAction: Runnable, token: MediaSession.Token, Loading @@ -272,11 +276,6 @@ class MediaDataManager @Inject constructor( appIntent: PendingIntent, packageName: String ) { if (resumeAction == null) { Log.e(TAG, "Resume action cannot be null") return } if (TextUtils.isEmpty(desc.title)) { Log.e(TAG, "Description incomplete") return Loading @@ -299,7 +298,8 @@ class MediaDataManager @Inject constructor( foregroundExecutor.execute { onMediaDataLoaded(packageName, null, MediaData(true, Color.DKGRAY, appName, null, desc.subtitle, desc.title, artworkIcon, listOf(mediaAction), listOf(0), packageName, token, appIntent, null, resumeAction, packageName)) packageName, token, appIntent, device = null, active = false, resumeAction = resumeAction)) } } Loading Loading @@ -430,7 +430,8 @@ class MediaDataManager @Inject constructor( foregroundExecutor.execute { onMediaDataLoaded(key, oldKey, MediaData(true, bgColor, app, smallIconDrawable, artist, song, artWorkIcon, actionIcons, actionsToShowCollapsed, sbn.packageName, token, notif.contentIntent, null, resumeAction, key)) notif.contentIntent, null, active = true, resumeAction = resumeAction, notificationKey = key)) } } Loading Loading @@ -528,13 +529,13 @@ class MediaDataManager @Inject constructor( /** * Are there any media notifications active? */ fun hasActiveMedia() = mediaEntries.any({ isActive(it.value) }) fun hasActiveMedia() = mediaEntries.any { it.value.active } fun isActive(data: MediaData): Boolean { if (data.token == null) { fun isActive(token: MediaSession.Token?): Boolean { if (token == null) { return false } val controller = mediaControllerFactory.create(data.token) val controller = mediaControllerFactory.create(token) val state = controller?.playbackState?.state return state != null && NotificationMediaManager.isActiveState(state) } Loading @@ -542,7 +543,7 @@ class MediaDataManager @Inject constructor( /** * Are there any media entries, including resume controls? */ fun hasAnyMedia() = mediaEntries.isNotEmpty() fun hasAnyMedia() = if (useMediaResumption) mediaEntries.isNotEmpty() else hasActiveMedia() interface Listener { Loading
packages/SystemUI/src/com/android/systemui/media/MediaHost.kt +60 −6 Original line number Diff line number Diff line package com.android.systemui.media import android.graphics.PointF import android.graphics.Rect import android.view.View import android.view.View.OnAttachStateChangeListener Loading @@ -20,8 +21,6 @@ class MediaHost @Inject constructor( var location: Int = -1 private set var visibleChangedListener: ((Boolean) -> Unit)? = null var visible: Boolean = false private set private val tmpLocationOnScreen: IntArray = intArrayOf(0, 0) Loading Loading @@ -109,16 +108,17 @@ class MediaHost @Inject constructor( } private fun updateViewVisibility() { if (showsOnlyActiveMedia) { visible = mediaDataManager.hasActiveMedia() visible = if (showsOnlyActiveMedia) { mediaDataManager.hasActiveMedia() } else { visible = mediaDataManager.hasAnyMedia() mediaDataManager.hasAnyMedia() } hostView.visibility = if (visible) View.VISIBLE else View.GONE visibleChangedListener?.invoke(visible) } class MediaHostStateHolder @Inject constructor() : MediaHostState { private var gonePivot: PointF = PointF() override var measurementInput: MeasurementInput? = null set(value) { Loading @@ -144,6 +144,25 @@ class MediaHost @Inject constructor( } } override var visible: Boolean = true set(value) { if (field == value) { return } field = value changedListener?.invoke() } override fun getPivotX(): Float = gonePivot.x override fun getPivotY(): Float = gonePivot.y override fun setGonePivot(x: Float, y: Float) { if (gonePivot.equals(x, y)) { return } gonePivot.set(x, y) changedListener?.invoke() } /** * A listener for all changes. This won't be copied over when invoking [copy] */ Loading @@ -157,6 +176,8 @@ class MediaHost @Inject constructor( mediaHostState.expansion = expansion mediaHostState.showsOnlyActiveMedia = showsOnlyActiveMedia mediaHostState.measurementInput = measurementInput?.copy() mediaHostState.visible = visible mediaHostState.gonePivot.set(gonePivot) return mediaHostState } Loading @@ -173,6 +194,12 @@ class MediaHost @Inject constructor( if (showsOnlyActiveMedia != other.showsOnlyActiveMedia) { return false } if (visible != other.visible) { return false } if (!gonePivot.equals(other.getPivotX(), other.getPivotY())) { return false } return true } Loading @@ -180,6 +207,8 @@ class MediaHost @Inject constructor( var result = measurementInput?.hashCode() ?: 0 result = 31 * result + expansion.hashCode() result = 31 * result + showsOnlyActiveMedia.hashCode() result = 31 * result + if (visible) 1 else 2 result = 31 * result + gonePivot.hashCode() return result } } Loading @@ -194,7 +223,8 @@ interface MediaHostState { var measurementInput: MeasurementInput? /** * The expansion of the player, 0 for fully collapsed, 1 for fully expanded * The expansion of the player, 0 for fully collapsed (up to 3 actions), 1 for fully expanded * (up to 5 actions.) */ var expansion: Float Loading @@ -203,6 +233,30 @@ interface MediaHostState { */ var showsOnlyActiveMedia: Boolean /** * If the view should be VISIBLE or GONE. */ var visible: Boolean /** * Sets the pivot point when clipping the height or width. * Clipping happens when animating visibility when we're visible in QS but not on QQS, * for example. */ fun setGonePivot(x: Float, y: Float) /** * x position of pivot, from 0 to 1 * @see [setGonePivot] */ fun getPivotX(): Float /** * y position of pivot, from 0 to 1 * @see [setGonePivot] */ fun getPivotY(): Float /** * Get a copy of this view state, deepcopying all appropriate members */ Loading
packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt +7 −2 Original line number Diff line number Diff line Loading @@ -43,6 +43,11 @@ class MediaTimeoutListener @Inject constructor( private val mediaListeners: MutableMap<String, PlaybackStateListener> = mutableMapOf() /** * Callback representing that a media object is now expired: * @param token Media session unique identifier * @param pauseTimeuot True when expired for {@code PAUSED_MEDIA_TIMEOUT} */ lateinit var timeoutCallback: (String, Boolean) -> Unit override fun onMediaDataLoaded(key: String, oldKey: String?, data: MediaData) { Loading Loading @@ -112,11 +117,11 @@ class MediaTimeoutListener @Inject constructor( } } private fun expireMediaTimeout(mediaNotificationKey: String, reason: String) { private fun expireMediaTimeout(mediaKey: String, reason: String) { cancellation?.apply { if (DEBUG) { Log.v(TAG, "media timeout cancelled for $mediaNotificationKey, reason: $reason") "media timeout cancelled for $mediaKey, reason: $reason") } run() } Loading