summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Anton Potapov <apotapov@google.com> 2024-04-16 15:33:23 +0100
committer Anton Potapov <apotapov@google.com> 2024-04-17 18:16:11 +0100
commit0a6fe047d295956844cc76d15943adaf6f9868b3 (patch)
tree363f3b4d8ca8c903ff1bd12e7853a97a26f36d26
parent020580d714d1afa8acd209fd6651eb59069ca39d (diff)
Add loading state in the MediaOutputViewModel
We need to distinguish between loading and null session in the MediaOutputViewModel to wait for the initial load to finish. Flag: aconfig new_volume_panel TRUNKFOOD Test: manual on the phone Fixes: 332721662 Change-Id: Ib9eb6cdade98fdd75ccacbac7b49caa782ba8bd6
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModel.kt34
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/panel/shared/model/Result.kt27
2 files changed, 51 insertions, 10 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModel.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModel.kt
index 6b237f8e329b..f19fa20bd999 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/component/mediaoutput/ui/viewmodel/MediaOutputViewModel.kt
@@ -27,6 +27,7 @@ import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor
import com.android.systemui.volume.panel.component.mediaoutput.domain.interactor.MediaOutputInteractor
import com.android.systemui.volume.panel.component.mediaoutput.shared.model.SessionWithPlayback
import com.android.systemui.volume.panel.dagger.scope.VolumePanelScope
+import com.android.systemui.volume.panel.shared.model.Result
import com.android.systemui.volume.panel.ui.VolumePanelUiEvent
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
@@ -34,6 +35,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
@@ -53,32 +55,40 @@ constructor(
private val uiEventLogger: UiEventLogger,
) {
- private val sessionWithPlayback: StateFlow<SessionWithPlayback?> =
+ private val sessionWithPlayback: StateFlow<Result<SessionWithPlayback?>> =
interactor.defaultActiveMediaSession
.flatMapLatest { session ->
if (session == null) {
- flowOf(null)
+ flowOf(Result.Data<SessionWithPlayback?>(null))
} else {
- mediaDeviceSessionInteractor.playbackState(session).map { playback ->
- playback?.let { SessionWithPlayback(session, it) }
- }
+ mediaDeviceSessionInteractor
+ .playbackState(session)
+ .map { playback ->
+ playback?.let {
+ Result.Data<SessionWithPlayback?>(SessionWithPlayback(session, it))
+ }
+ }
+ .filterNotNull()
}
}
.stateIn(
coroutineScope,
SharingStarted.Eagerly,
- null,
+ Result.Loading(),
)
val connectedDeviceViewModel: StateFlow<ConnectedDeviceViewModel?> =
combine(sessionWithPlayback, interactor.currentConnectedDevice) {
mediaDeviceSession,
currentConnectedDevice ->
+ if (mediaDeviceSession !is Result.Data) {
+ return@combine null
+ }
ConnectedDeviceViewModel(
- if (mediaDeviceSession?.playback?.isActive == true) {
+ if (mediaDeviceSession.data?.playback?.isActive == true) {
context.getString(
R.string.media_output_label_title,
- mediaDeviceSession.session.appLabel
+ mediaDeviceSession.data.session.appLabel
)
} else {
context.getString(R.string.media_output_title_without_playing)
@@ -96,7 +106,10 @@ constructor(
combine(sessionWithPlayback, interactor.currentConnectedDevice) {
mediaDeviceSession,
currentConnectedDevice ->
- if (mediaDeviceSession?.playback?.isActive == true) {
+ if (mediaDeviceSession !is Result.Data) {
+ return@combine null
+ }
+ if (mediaDeviceSession.data?.playback?.isActive == true) {
val icon =
currentConnectedDevice?.icon?.let { Icon.Loaded(it, null) }
?: Icon.Resource(
@@ -130,6 +143,7 @@ constructor(
fun onBarClick(expandable: Expandable) {
uiEventLogger.log(VolumePanelUiEvent.VOLUME_PANEL_MEDIA_OUTPUT_CLICKED)
- actionsInteractor.onBarClick(sessionWithPlayback.value, expandable)
+ val result = sessionWithPlayback.value
+ actionsInteractor.onBarClick((result as? Result.Data)?.data, expandable)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/panel/shared/model/Result.kt b/packages/SystemUI/src/com/android/systemui/volume/panel/shared/model/Result.kt
new file mode 100644
index 000000000000..8793538aac0d
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/panel/shared/model/Result.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2024 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.volume.panel.shared.model
+
+/** Models a loadable result */
+sealed interface Result<T> {
+
+ /** The data is still loading */
+ class Loading<T> : Result<T>
+
+ /** The data is loaded successfully */
+ data class Data<T>(val data: T) : Result<T>
+}