Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 79dab7a7 authored by Anton Potapov's avatar Anton Potapov
Browse files

Make ViewModels consistent in terms of using ExclusiveActivateable

It's way more convinient to use flows in the View because of the
animations. This CL makes sure all Volume Dialog ViewModels follow the
same pattern of exposing properties as Flow.

This CL doesn't introduce new changes, but reorganizes the existing
code.

Flag: com.android.systemui.volume_redesign
Bug: 369994090
Test: manual on the foldable
Change-Id: I1818de4eee266edb70fc6216039a3db288230cb8
parent a4fda58f
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.systemui.volume.dialog

import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.plugins.VolumeDialog
import com.android.systemui.volume.dialog.dagger.VolumeDialogPluginComponent
@@ -23,7 +24,6 @@ import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.coroutineScope
import com.android.app.tracing.coroutines.launchTraced as launch

class VolumeDialogPlugin
@Inject
@@ -33,19 +33,22 @@ constructor(
) : VolumeDialog {

    private var job: Job? = null
    private var pluginComponent: VolumeDialogPluginComponent? = null

    override fun init(windowType: Int, callback: VolumeDialog.Callback?) {
        job =
            applicationCoroutineScope.launch {
                coroutineScope {
                    val component = volumeDialogPluginComponentFactory.create(this)

                    component.viewModel().activate()
                    pluginComponent =
                        volumeDialogPluginComponentFactory.create(this).also {
                            it.viewModel().launchVolumeDialog()
                        }
                }
            }
    }

    override fun destroy() {
        job?.cancel()
        pluginComponent = null
    }
}
+10 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.volume.dialog.domain.interactor

import android.annotation.SuppressLint
import com.android.systemui.plugins.VolumeDialogController
import com.android.systemui.volume.Events
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogPlugin
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogPluginScope
@@ -34,11 +35,14 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.mapNotNull
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.stateIn

private val MAX_DIALOG_SHOW_TIME: Duration = 3.seconds

@@ -57,11 +61,16 @@ constructor(
    callbacksInteractor: VolumeDialogCallbacksInteractor,
    private val tracer: VolumeTracer,
    private val repository: VolumeDialogVisibilityRepository,
    private val controller: VolumeDialogController,
) {

    @SuppressLint("SharedFlowCreation")
    private val mutableDismissDialogEvents = MutableSharedFlow<Unit>(extraBufferCapacity = 1)
    val dialogVisibility: Flow<VolumeDialogVisibilityModel> = repository.dialogVisibility
    val dialogVisibility: Flow<VolumeDialogVisibilityModel> =
        repository.dialogVisibility
            .onEach { controller.notifyVisible(it is Visible) }
            .stateIn(coroutineScope, SharingStarted.Eagerly, null)
            .filterNotNull()

    init {
        merge(
+8 −1
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@ import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope
import com.android.systemui.volume.dialog.settings.ui.viewmodel.VolumeDialogSettingsButtonViewModel
import javax.inject.Inject
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach

@VolumeDialogScope
class VolumeDialogSettingsButtonViewBinder
@@ -42,7 +44,12 @@ constructor(private val viewModelFactory: VolumeDialogSettingsButtonViewModel.Fa
                    factory = { viewModelFactory.create() },
                ) { viewModel ->
                    setSnapshotBinding {
                        visibility = if (viewModel.isVisible) View.VISIBLE else View.GONE
                        viewModel.isVisible
                            .onEach { isVisible ->
                                visibility = if (isVisible) View.VISIBLE else View.GONE
                            }
                            .launchIn(this)

                        button.setOnClickListener { viewModel.onButtonClicked() }
                    }

+2 −11
Original line number Diff line number Diff line
@@ -16,9 +16,6 @@

package com.android.systemui.volume.dialog.settings.ui.viewmodel

import androidx.compose.runtime.getValue
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.Hydrator
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope
import com.android.systemui.volume.dialog.settings.domain.VolumeDialogSettingsButtonInteractor
import dagger.assisted.AssistedFactory
@@ -26,15 +23,9 @@ import dagger.assisted.AssistedInject

class VolumeDialogSettingsButtonViewModel
@AssistedInject
constructor(private val interactor: VolumeDialogSettingsButtonInteractor) : ExclusiveActivatable() {
constructor(private val interactor: VolumeDialogSettingsButtonInteractor) {

    private val hydrator = Hydrator("VolumeDialog_settings_button")

    val isVisible by hydrator.hydratedStateOf("isVisible", interactor.isVisible)

    override suspend fun onActivated(): Nothing {
        hydrator.activate()
    }
    val isVisible = interactor.isVisible

    fun onButtonClicked() {
        interactor.onButtonClicked()
+14 −14
Original line number Diff line number Diff line
@@ -23,14 +23,14 @@ import androidx.annotation.LayoutRes
import androidx.compose.ui.util.fastForEachIndexed
import com.android.systemui.lifecycle.WindowLifecycleState
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.lifecycle.setSnapshotBinding
import com.android.systemui.lifecycle.viewModel
import com.android.systemui.res.R
import com.android.systemui.volume.dialog.dagger.scope.VolumeDialogScope
import com.android.systemui.volume.dialog.sliders.ui.viewmodel.VolumeDialogSlidersViewModel
import javax.inject.Inject
import kotlin.math.abs
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach

@VolumeDialogScope
class VolumeDialogSlidersViewBinder
@@ -48,11 +48,11 @@ constructor(private val viewModelFactory: VolumeDialogSlidersViewModel.Factory)
                    minWindowLifecycleState = WindowLifecycleState.ATTACHED,
                    factory = { viewModelFactory.create() },
                ) { viewModel ->
                    setSnapshotBinding {
                        viewModel.uiModel?.sliderViewBinder?.bind(volumeDialog)
                    viewModel.sliders
                        .onEach { uiModel ->
                            uiModel.sliderViewBinder.bind(volumeDialog)

                        val floatingSliderViewBinders =
                            viewModel.uiModel?.floatingSliderViewBinders ?: emptyList()
                            val floatingSliderViewBinders = uiModel.floatingSliderViewBinders
                            floatingSlidersContainer.ensureChildCount(
                                viewLayoutId = R.layout.volume_dialog_slider_floating,
                                count = floatingSliderViewBinders.size,
@@ -61,7 +61,7 @@ constructor(private val viewModelFactory: VolumeDialogSlidersViewModel.Factory)
                                viewBinder.bind(floatingSlidersContainer.getChildAt(index))
                            }
                        }
                    awaitCancellation()
                        .launchIn(this)
                }
            }
        }
Loading