Loading packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt +1 −2 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import com.android.systemui.authentication.domain.interactor.AuthenticationResul import com.android.systemui.authentication.shared.model.AuthenticationMethodModel import com.android.systemui.bouncer.domain.interactor.BouncerInteractor import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.lifecycle.SysUiViewModel import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.MutableStateFlow Loading @@ -40,7 +39,7 @@ sealed class AuthMethodBouncerViewModel( * being able to attempt to unlock the device. */ val isInputEnabled: StateFlow<Boolean>, ) : SysUiViewModel, ExclusiveActivatable() { ) : ExclusiveActivatable() { private val _animateFailure = MutableStateFlow(false) /** Loading packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModel.kt +1 −2 Original line number Diff line number Diff line Loading @@ -39,7 +39,6 @@ import com.android.systemui.deviceentry.shared.model.FaceTimeoutMessage import com.android.systemui.deviceentry.shared.model.FingerprintFailureMessage import com.android.systemui.deviceentry.shared.model.FingerprintLockoutMessage import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.lifecycle.SysUiViewModel import com.android.systemui.res.R.string.kg_too_many_failed_attempts_countdown import com.android.systemui.user.ui.viewmodel.UserSwitcherViewModel import com.android.systemui.util.kotlin.Utils.Companion.sample Loading Loading @@ -80,7 +79,7 @@ constructor( private val deviceUnlockedInteractor: DeviceUnlockedInteractor, private val deviceEntryBiometricsAllowedInteractor: DeviceEntryBiometricsAllowedInteractor, private val flags: ComposeBouncerFlags, ) : SysUiViewModel, ExclusiveActivatable() { ) : ExclusiveActivatable() { /** * A message shown when the user has attempted the wrong credential too many times and now must * wait a while before attempting to authenticate again. Loading packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModel.kt +1 −2 Original line number Diff line number Diff line Loading @@ -34,7 +34,6 @@ import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.shared.model.Text import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.lifecycle.SysUiViewModel import com.android.systemui.user.ui.viewmodel.UserSwitcherViewModel import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject Loading Loading @@ -63,7 +62,7 @@ constructor( private val pinViewModelFactory: PinBouncerViewModel.Factory, private val patternViewModelFactory: PatternBouncerViewModel.Factory, private val passwordViewModelFactory: PasswordBouncerViewModel.Factory, ) : SysUiViewModel, ExclusiveActivatable() { ) : ExclusiveActivatable() { private val _selectedUserImage = MutableStateFlow<Bitmap?>(null) val selectedUserImage: StateFlow<Bitmap?> = _selectedUserImage.asStateFlow() Loading packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModel.kt +1 −2 Original line number Diff line number Diff line Loading @@ -25,7 +25,6 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardBlueprintInteract import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor import com.android.systemui.keyguard.shared.model.ClockSize import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.lifecycle.SysUiViewModel import com.android.systemui.res.R import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor import com.android.systemui.scene.shared.model.Scenes Loading Loading @@ -60,7 +59,7 @@ constructor( private val unfoldTransitionInteractor: UnfoldTransitionInteractor, private val occlusionInteractor: SceneContainerOcclusionInteractor, private val deviceEntryInteractor: DeviceEntryInteractor, ) : SysUiViewModel, ExclusiveActivatable() { ) : ExclusiveActivatable() { @VisibleForTesting val clockSize = clockInteractor.clockSize val isUdfpsVisible: Boolean Loading packages/SystemUI/src/com/android/systemui/lifecycle/Hydrator.kt +51 −12 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ package com.android.systemui.lifecycle import androidx.compose.runtime.State import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.snapshots.StateFactoryMarker import com.android.app.tracing.coroutines.launch import com.android.app.tracing.coroutines.traceCoroutine import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.Flow Loading @@ -37,35 +39,55 @@ import kotlinx.coroutines.launch * } * ``` */ class Hydrator : ExclusiveActivatable() { class Hydrator( /** * A name for performance tracing purposes. * * Please use a short string literal that's easy to find in code search. Try to avoid * concatenation or templating. */ private val traceName: String, ) : ExclusiveActivatable() { private val children = mutableListOf<Activatable>() private val children = mutableListOf<NamedActivatable>() /** * Returns a snapshot [State] that's kept up-to-date as long as the [SysUiViewModel] is active. * Returns a snapshot [State] that's kept up-to-date as long as its owner is active. * * @param traceName Used for coroutine performance tracing purposes. Please try to use a label * that's unique enough and easy enough to find in code search; this should help correlate * performance findings with actual code. One recommendation: prefer whole string literals * instead of some complex concatenation or templating scheme. * @param source The upstream [StateFlow] to collect from; values emitted to it will be * automatically set on the returned [State]. */ @StateFactoryMarker fun <T> hydratedStateOf( traceName: String, source: StateFlow<T>, ): State<T> { return hydratedStateOf( traceName = traceName, initialValue = source.value, source = source, ) } /** * Returns a snapshot [State] that's kept up-to-date as long as the [SysUiViewModel] is active. * Returns a snapshot [State] that's kept up-to-date as long as its owner is active. * * @param traceName Used for coroutine performance tracing purposes. Please try to use a label * that's unique enough and easy enough to find in code search; this should help correlate * performance findings with actual code. One recommendation: prefer whole string literals * instead of some complex concatenation or templating scheme. Use `null` to disable * performance tracing for this state. * @param initialValue The first value to place on the [State] * @param source The upstream [Flow] to collect from; values emitted to it will be automatically * set on the returned [State]. */ @StateFactoryMarker fun <T> hydratedStateOf( traceName: String?, initialValue: T, source: Flow<T>, ): State<T> { Loading @@ -73,18 +95,35 @@ class Hydrator : ExclusiveActivatable() { val mutableState = mutableStateOf(initialValue) children.add( NamedActivatable( traceName = traceName, activatable = object : ExclusiveActivatable() { override suspend fun onActivated(): Nothing { source.collect { mutableState.value = it } awaitCancellation() } } }, ) ) return mutableState } override suspend fun onActivated() = coroutineScope { children.forEach { child -> launch { child.activate() } } traceCoroutine(traceName) { children.forEach { child -> if (child.traceName != null) { launch(spanName = child.traceName) { child.activatable.activate() } } else { launch { child.activatable.activate() } } } awaitCancellation() } } private data class NamedActivatable( val traceName: String?, val activatable: Activatable, ) } Loading
packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/AuthMethodBouncerViewModel.kt +1 −2 Original line number Diff line number Diff line Loading @@ -22,7 +22,6 @@ import com.android.systemui.authentication.domain.interactor.AuthenticationResul import com.android.systemui.authentication.shared.model.AuthenticationMethodModel import com.android.systemui.bouncer.domain.interactor.BouncerInteractor import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.lifecycle.SysUiViewModel import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.channels.Channel import kotlinx.coroutines.flow.MutableStateFlow Loading @@ -40,7 +39,7 @@ sealed class AuthMethodBouncerViewModel( * being able to attempt to unlock the device. */ val isInputEnabled: StateFlow<Boolean>, ) : SysUiViewModel, ExclusiveActivatable() { ) : ExclusiveActivatable() { private val _animateFailure = MutableStateFlow(false) /** Loading
packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerMessageViewModel.kt +1 −2 Original line number Diff line number Diff line Loading @@ -39,7 +39,6 @@ import com.android.systemui.deviceentry.shared.model.FaceTimeoutMessage import com.android.systemui.deviceentry.shared.model.FingerprintFailureMessage import com.android.systemui.deviceentry.shared.model.FingerprintLockoutMessage import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.lifecycle.SysUiViewModel import com.android.systemui.res.R.string.kg_too_many_failed_attempts_countdown import com.android.systemui.user.ui.viewmodel.UserSwitcherViewModel import com.android.systemui.util.kotlin.Utils.Companion.sample Loading Loading @@ -80,7 +79,7 @@ constructor( private val deviceUnlockedInteractor: DeviceUnlockedInteractor, private val deviceEntryBiometricsAllowedInteractor: DeviceEntryBiometricsAllowedInteractor, private val flags: ComposeBouncerFlags, ) : SysUiViewModel, ExclusiveActivatable() { ) : ExclusiveActivatable() { /** * A message shown when the user has attempted the wrong credential too many times and now must * wait a while before attempting to authenticate again. Loading
packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerSceneContentViewModel.kt +1 −2 Original line number Diff line number Diff line Loading @@ -34,7 +34,6 @@ import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.shared.model.Text import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.lifecycle.SysUiViewModel import com.android.systemui.user.ui.viewmodel.UserSwitcherViewModel import dagger.assisted.AssistedFactory import dagger.assisted.AssistedInject Loading Loading @@ -63,7 +62,7 @@ constructor( private val pinViewModelFactory: PinBouncerViewModel.Factory, private val patternViewModelFactory: PatternBouncerViewModel.Factory, private val passwordViewModelFactory: PasswordBouncerViewModel.Factory, ) : SysUiViewModel, ExclusiveActivatable() { ) : ExclusiveActivatable() { private val _selectedUserImage = MutableStateFlow<Bitmap?>(null) val selectedUserImage: StateFlow<Bitmap?> = _selectedUserImage.asStateFlow() Loading
packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenContentViewModel.kt +1 −2 Original line number Diff line number Diff line Loading @@ -25,7 +25,6 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardBlueprintInteract import com.android.systemui.keyguard.domain.interactor.KeyguardClockInteractor import com.android.systemui.keyguard.shared.model.ClockSize import com.android.systemui.lifecycle.ExclusiveActivatable import com.android.systemui.lifecycle.SysUiViewModel import com.android.systemui.res.R import com.android.systemui.scene.domain.interactor.SceneContainerOcclusionInteractor import com.android.systemui.scene.shared.model.Scenes Loading Loading @@ -60,7 +59,7 @@ constructor( private val unfoldTransitionInteractor: UnfoldTransitionInteractor, private val occlusionInteractor: SceneContainerOcclusionInteractor, private val deviceEntryInteractor: DeviceEntryInteractor, ) : SysUiViewModel, ExclusiveActivatable() { ) : ExclusiveActivatable() { @VisibleForTesting val clockSize = clockInteractor.clockSize val isUdfpsVisible: Boolean Loading
packages/SystemUI/src/com/android/systemui/lifecycle/Hydrator.kt +51 −12 Original line number Diff line number Diff line Loading @@ -19,6 +19,8 @@ package com.android.systemui.lifecycle import androidx.compose.runtime.State import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.snapshots.StateFactoryMarker import com.android.app.tracing.coroutines.launch import com.android.app.tracing.coroutines.traceCoroutine import kotlinx.coroutines.awaitCancellation import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.flow.Flow Loading @@ -37,35 +39,55 @@ import kotlinx.coroutines.launch * } * ``` */ class Hydrator : ExclusiveActivatable() { class Hydrator( /** * A name for performance tracing purposes. * * Please use a short string literal that's easy to find in code search. Try to avoid * concatenation or templating. */ private val traceName: String, ) : ExclusiveActivatable() { private val children = mutableListOf<Activatable>() private val children = mutableListOf<NamedActivatable>() /** * Returns a snapshot [State] that's kept up-to-date as long as the [SysUiViewModel] is active. * Returns a snapshot [State] that's kept up-to-date as long as its owner is active. * * @param traceName Used for coroutine performance tracing purposes. Please try to use a label * that's unique enough and easy enough to find in code search; this should help correlate * performance findings with actual code. One recommendation: prefer whole string literals * instead of some complex concatenation or templating scheme. * @param source The upstream [StateFlow] to collect from; values emitted to it will be * automatically set on the returned [State]. */ @StateFactoryMarker fun <T> hydratedStateOf( traceName: String, source: StateFlow<T>, ): State<T> { return hydratedStateOf( traceName = traceName, initialValue = source.value, source = source, ) } /** * Returns a snapshot [State] that's kept up-to-date as long as the [SysUiViewModel] is active. * Returns a snapshot [State] that's kept up-to-date as long as its owner is active. * * @param traceName Used for coroutine performance tracing purposes. Please try to use a label * that's unique enough and easy enough to find in code search; this should help correlate * performance findings with actual code. One recommendation: prefer whole string literals * instead of some complex concatenation or templating scheme. Use `null` to disable * performance tracing for this state. * @param initialValue The first value to place on the [State] * @param source The upstream [Flow] to collect from; values emitted to it will be automatically * set on the returned [State]. */ @StateFactoryMarker fun <T> hydratedStateOf( traceName: String?, initialValue: T, source: Flow<T>, ): State<T> { Loading @@ -73,18 +95,35 @@ class Hydrator : ExclusiveActivatable() { val mutableState = mutableStateOf(initialValue) children.add( NamedActivatable( traceName = traceName, activatable = object : ExclusiveActivatable() { override suspend fun onActivated(): Nothing { source.collect { mutableState.value = it } awaitCancellation() } } }, ) ) return mutableState } override suspend fun onActivated() = coroutineScope { children.forEach { child -> launch { child.activate() } } traceCoroutine(traceName) { children.forEach { child -> if (child.traceName != null) { launch(spanName = child.traceName) { child.activatable.activate() } } else { launch { child.activatable.activate() } } } awaitCancellation() } } private data class NamedActivatable( val traceName: String?, val activatable: Activatable, ) }