diff options
author | 2024-04-16 15:33:23 +0100 | |
---|---|---|
committer | 2024-04-17 18:16:11 +0100 | |
commit | 0a6fe047d295956844cc76d15943adaf6f9868b3 (patch) | |
tree | 363f3b4d8ca8c903ff1bd12e7853a97a26f36d26 | |
parent | 020580d714d1afa8acd209fd6651eb59069ca39d (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
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> +} |