@@ -7,18 +7,17 @@ package ch.srgssr.androidx.mediarouter.compose
7
7
8
8
import android.app.Application
9
9
import android.app.PendingIntent
10
- import android.media.MediaDescription
11
- import android.media.MediaMetadata
12
- import android.media.session.MediaController
13
- import android.media.session.MediaSession
14
- import android.media.session.PlaybackState
15
- import android.media.session.PlaybackState.ACTION_PAUSE
16
- import android.media.session.PlaybackState.ACTION_PLAY
17
- import android.media.session.PlaybackState.ACTION_PLAY_PAUSE
18
- import android.media.session.PlaybackState.ACTION_STOP
19
- import android.media.session.PlaybackState.STATE_BUFFERING
20
- import android.media.session.PlaybackState.STATE_NONE
21
- import android.media.session.PlaybackState.STATE_PLAYING
10
+ import android.support.v4.media.MediaDescriptionCompat
11
+ import android.support.v4.media.MediaMetadataCompat
12
+ import android.support.v4.media.session.MediaControllerCompat
13
+ import android.support.v4.media.session.PlaybackStateCompat
14
+ import android.support.v4.media.session.PlaybackStateCompat.ACTION_PAUSE
15
+ import android.support.v4.media.session.PlaybackStateCompat.ACTION_PLAY
16
+ import android.support.v4.media.session.PlaybackStateCompat.ACTION_PLAY_PAUSE
17
+ import android.support.v4.media.session.PlaybackStateCompat.ACTION_STOP
18
+ import android.support.v4.media.session.PlaybackStateCompat.STATE_BUFFERING
19
+ import android.support.v4.media.session.PlaybackStateCompat.STATE_NONE
20
+ import android.support.v4.media.session.PlaybackStateCompat.STATE_PLAYING
22
21
import android.util.Log
23
22
import androidx.annotation.VisibleForTesting
24
23
import androidx.compose.ui.graphics.vector.ImageVector
@@ -47,13 +46,14 @@ import kotlinx.coroutines.flow.combine
47
46
import kotlinx.coroutines.flow.map
48
47
import kotlinx.coroutines.flow.stateIn
49
48
import kotlinx.coroutines.flow.update
49
+ import kotlinx.coroutines.launch
50
50
51
51
internal class MediaRouteControllerDialogViewModel (
52
52
private val application : Application ,
53
53
private val savedStateHandle : SavedStateHandle ,
54
54
private val volumeControlEnabled : Boolean ,
55
55
) : AndroidViewModel(application) {
56
- private var mediaController: MediaController ? = null
56
+ private var mediaController: MediaControllerCompat ? = null
57
57
58
58
private val mediaControllerCallback = MediaControllerCallback ()
59
59
private val mediaRouterCallback = MediaRouterCallback ()
@@ -63,10 +63,10 @@ internal class MediaRouteControllerDialogViewModel(
63
63
private val routerUpdates = MutableStateFlow (0 )
64
64
65
65
@VisibleForTesting
66
- internal val mediaDescription = MutableStateFlow <MediaDescription ?>(null )
66
+ internal val mediaDescription = MutableStateFlow <MediaDescriptionCompat ?>(null )
67
67
68
68
@VisibleForTesting
69
- internal val playbackState = MutableStateFlow <PlaybackState ?>(null )
69
+ internal val playbackState = MutableStateFlow <PlaybackStateCompat ?>(null )
70
70
private val _isDeviceGroupExpanded = MutableStateFlow (false )
71
71
private val _selectedRoute = routerUpdates.map { router.selectedRoute }
72
72
@@ -80,9 +80,14 @@ internal class MediaRouteControllerDialogViewModel(
80
80
mediaDescription != null || playbackState != null
81
81
}.stateIn(viewModelScope, WhileSubscribed (), false )
82
82
val showVolumeControl = _selectedRoute .map { selectedRoute ->
83
- selectedRoute.volumeHandling == RouteInfo .PLAYBACK_VOLUME_VARIABLE
84
- && (isGroupVolumeUxEnabled || ! (selectedRoute.isGroup && selectedRoute.memberRoutes.size > 1 ))
85
- && volumeControlEnabled
83
+ if (! isGroupVolumeUxEnabled && selectedRoute.isGroup && selectedRoute.memberRoutes.size > 1 ) {
84
+ _isDeviceGroupExpanded .update { true }
85
+ false
86
+ } else {
87
+ selectedRoute.volumeHandling == RouteInfo .PLAYBACK_VOLUME_VARIABLE
88
+ && (! _isDeviceGroupExpanded .value || isGroupVolumeUxEnabled)
89
+ && volumeControlEnabled
90
+ }
86
91
}.stateIn(viewModelScope, WhileSubscribed (), false )
87
92
val imageModel = mediaDescription.map { mediaDescription ->
88
93
mediaDescription?.iconBitmap?.takeIf { ! it.isRecycled } ? : mediaDescription?.iconUri
@@ -139,14 +144,21 @@ internal class MediaRouteControllerDialogViewModel(
139
144
)
140
145
141
146
router.mediaSessionToken?.let { mediaSessionToken ->
142
- val platformToken = mediaSessionToken.token as MediaSession .Token
143
- val mediaController = MediaController (application, platformToken)
147
+ val mediaController = MediaControllerCompat (application, mediaSessionToken)
144
148
mediaController.registerCallback(mediaControllerCallback)
145
149
146
150
this .mediaController = mediaController
147
151
mediaDescription.update { mediaController.metadata?.description }
148
152
playbackState.update { mediaController.playbackState }
149
153
}
154
+
155
+ viewModelScope.launch {
156
+ _selectedRoute .collect {
157
+ if (! it.isSelected || it.isDefaultOrBluetooth) {
158
+ hideDialog()
159
+ }
160
+ }
161
+ }
150
162
}
151
163
152
164
fun hideDialog () {
@@ -222,13 +234,13 @@ internal class MediaRouteControllerDialogViewModel(
222
234
mediaControllerCallback.onSessionDestroyed()
223
235
}
224
236
225
- private val PlaybackState .isPlayActionSupported: Boolean
237
+ private val PlaybackStateCompat .isPlayActionSupported: Boolean
226
238
get() = actions and (ACTION_PLAY or ACTION_PLAY_PAUSE ) != 0L
227
239
228
- private val PlaybackState .isPauseActionSupported: Boolean
240
+ private val PlaybackStateCompat .isPauseActionSupported: Boolean
229
241
get() = actions and (ACTION_PAUSE or ACTION_PLAY_PAUSE ) != 0L
230
242
231
- private val PlaybackState .isStopActionSupported: Boolean
243
+ private val PlaybackStateCompat .isStopActionSupported: Boolean
232
244
get() = actions and ACTION_STOP != 0L
233
245
234
246
private companion object {
@@ -249,18 +261,18 @@ internal class MediaRouteControllerDialogViewModel(
249
261
}
250
262
}
251
263
252
- private inner class MediaControllerCallback : MediaController .Callback () {
264
+ private inner class MediaControllerCallback : MediaControllerCompat .Callback () {
253
265
override fun onSessionDestroyed () {
254
266
mediaController?.unregisterCallback(this )
255
267
mediaController = null
256
268
}
257
269
258
- override fun onPlaybackStateChanged (state : PlaybackState ? ) {
270
+ override fun onPlaybackStateChanged (state : PlaybackStateCompat ? ) {
259
271
playbackState.update { state }
260
272
routerUpdates.update { it + 1 }
261
273
}
262
274
263
- override fun onMetadataChanged (metadata : MediaMetadata ? ) {
275
+ override fun onMetadataChanged (metadata : MediaMetadataCompat ? ) {
264
276
mediaDescription.update { metadata?.description }
265
277
routerUpdates.update { it + 1 }
266
278
}
0 commit comments