Loading packages/SystemUI/src-debug/com/android/systemui/flags/FlagsModule.kt +6 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,12 @@ abstract class FlagsModule { @IntoSet abstract fun bindsScreenIdleCondition(impl: ScreenIdleCondition): ConditionalRestarter.Condition @Binds @IntoSet abstract fun bindsNotOccludedCondition( impl: NotOccludedCondition ): ConditionalRestarter.Condition @Module companion object { @JvmStatic Loading packages/SystemUI/src-release/com/android/systemui/flags/FlagsModule.kt +6 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,12 @@ abstract class FlagsModule { @IntoSet abstract fun bindsPluggedInCondition(impl: PluggedInCondition): ConditionalRestarter.Condition @Binds @IntoSet abstract fun bindsNotOccludedCondition( impl: NotOccludedCondition ): ConditionalRestarter.Condition @Module companion object { @JvmStatic Loading packages/SystemUI/src/com/android/systemui/flags/ConditionalRestarter.kt +17 −12 Original line number Diff line number Diff line Loading @@ -19,13 +19,17 @@ package com.android.systemui.flags import android.util.Log import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.flags.ConditionalRestarter.Condition import java.util.concurrent.TimeUnit import javax.inject.Inject import javax.inject.Named import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.transformLatest import kotlinx.coroutines.launch /** Restarts the process after all passed in [Condition]s are true. */ Loading @@ -39,7 +43,6 @@ constructor( @Background private val backgroundDispatcher: CoroutineDispatcher, ) : Restarter { private var restartJob: Job? = null private var pendingReason = "" private var androidRestartRequested = false Loading @@ -57,17 +60,19 @@ constructor( private fun scheduleRestart(reason: String = "") { pendingReason = if (reason.isEmpty()) pendingReason else reason if (conditions.all { c -> c.canRestartNow(this::scheduleRestart) }) { if (restartJob == null) { restartJob = applicationScope.launch(backgroundDispatcher) { combine(conditions.map { condition -> condition.canRestartNow }) { it.all { it } } // Once all conditions are met, delay. .transformLatest { allConditionsMet -> if (allConditionsMet) { delay(TimeUnit.SECONDS.toMillis(restartDelaySec)) restartNow() emit(Unit) } } } else { restartJob?.cancel() restartJob = null // Once we have successfully delayed _once_, continue to restart. .first() restartNow() } } Loading @@ -94,7 +99,7 @@ constructor( * multiple [Condition]s are being checked. If any one [Condition] returns false, all the * [Condition]s will need to be rechecked on the next restart attempt. */ fun canRestartNow(retryFn: () -> Unit): Boolean val canRestartNow: Flow<Boolean> } companion object { Loading packages/SystemUI/src/com/android/systemui/flags/NotOccludedCondition.kt 0 → 100644 +24 −0 Original line number Diff line number Diff line package com.android.systemui.flags import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.KeyguardState import dagger.Lazy import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map /** Returns true when the device is "asleep" as defined by the [WakefullnessLifecycle]. */ class NotOccludedCondition @Inject constructor( private val keyguardTransitionInteractorLazy: Lazy<KeyguardTransitionInteractor>, ) : ConditionalRestarter.Condition { override val canRestartNow: Flow<Boolean> get() { return keyguardTransitionInteractorLazy .get() .transitionValue(KeyguardState.OCCLUDED) .map { it == 0f } } } packages/SystemUI/src/com/android/systemui/flags/PluggedInCondition.kt +17 −17 Original line number Diff line number Diff line Loading @@ -16,34 +16,34 @@ package com.android.systemui.flags import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow import com.android.systemui.statusbar.policy.BatteryController import dagger.Lazy import javax.inject.Inject import kotlinx.coroutines.channels.awaitClose /** Returns true when the device is plugged in. */ class PluggedInCondition @Inject constructor( private val batteryController: BatteryController, private val batteryControllerLazy: Lazy<BatteryController>, ) : ConditionalRestarter.Condition { var listenersAdded = false var retryFn: (() -> Unit)? = null override val canRestartNow = conflatedCallbackFlow { val batteryCallback = object : BatteryController.BatteryStateChangeCallback { override fun onBatteryLevelChanged(level: Int, pluggedIn: Boolean, charging: Boolean) { retryFn?.invoke() } override fun onBatteryLevelChanged( level: Int, pluggedIn: Boolean, charging: Boolean ) { trySend(pluggedIn) } override fun canRestartNow(retryFn: () -> Unit): Boolean { if (!listenersAdded) { listenersAdded = true batteryController.addCallback(batteryCallback) } batteryControllerLazy.get().addCallback(batteryCallback) this.retryFn = retryFn trySend(batteryControllerLazy.get().isPluggedIn) return batteryController.isPluggedIn awaitClose { batteryControllerLazy.get().removeCallback(batteryCallback) } } } Loading
packages/SystemUI/src-debug/com/android/systemui/flags/FlagsModule.kt +6 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,12 @@ abstract class FlagsModule { @IntoSet abstract fun bindsScreenIdleCondition(impl: ScreenIdleCondition): ConditionalRestarter.Condition @Binds @IntoSet abstract fun bindsNotOccludedCondition( impl: NotOccludedCondition ): ConditionalRestarter.Condition @Module companion object { @JvmStatic Loading
packages/SystemUI/src-release/com/android/systemui/flags/FlagsModule.kt +6 −0 Original line number Diff line number Diff line Loading @@ -39,6 +39,12 @@ abstract class FlagsModule { @IntoSet abstract fun bindsPluggedInCondition(impl: PluggedInCondition): ConditionalRestarter.Condition @Binds @IntoSet abstract fun bindsNotOccludedCondition( impl: NotOccludedCondition ): ConditionalRestarter.Condition @Module companion object { @JvmStatic Loading
packages/SystemUI/src/com/android/systemui/flags/ConditionalRestarter.kt +17 −12 Original line number Diff line number Diff line Loading @@ -19,13 +19,17 @@ package com.android.systemui.flags import android.util.Log import com.android.systemui.dagger.qualifiers.Application import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.flags.ConditionalRestarter.Condition import java.util.concurrent.TimeUnit import javax.inject.Inject import javax.inject.Named import kotlinx.coroutines.CoroutineDispatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.transformLatest import kotlinx.coroutines.launch /** Restarts the process after all passed in [Condition]s are true. */ Loading @@ -39,7 +43,6 @@ constructor( @Background private val backgroundDispatcher: CoroutineDispatcher, ) : Restarter { private var restartJob: Job? = null private var pendingReason = "" private var androidRestartRequested = false Loading @@ -57,17 +60,19 @@ constructor( private fun scheduleRestart(reason: String = "") { pendingReason = if (reason.isEmpty()) pendingReason else reason if (conditions.all { c -> c.canRestartNow(this::scheduleRestart) }) { if (restartJob == null) { restartJob = applicationScope.launch(backgroundDispatcher) { combine(conditions.map { condition -> condition.canRestartNow }) { it.all { it } } // Once all conditions are met, delay. .transformLatest { allConditionsMet -> if (allConditionsMet) { delay(TimeUnit.SECONDS.toMillis(restartDelaySec)) restartNow() emit(Unit) } } } else { restartJob?.cancel() restartJob = null // Once we have successfully delayed _once_, continue to restart. .first() restartNow() } } Loading @@ -94,7 +99,7 @@ constructor( * multiple [Condition]s are being checked. If any one [Condition] returns false, all the * [Condition]s will need to be rechecked on the next restart attempt. */ fun canRestartNow(retryFn: () -> Unit): Boolean val canRestartNow: Flow<Boolean> } companion object { Loading
packages/SystemUI/src/com/android/systemui/flags/NotOccludedCondition.kt 0 → 100644 +24 −0 Original line number Diff line number Diff line package com.android.systemui.flags import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.KeyguardState import dagger.Lazy import javax.inject.Inject import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.map /** Returns true when the device is "asleep" as defined by the [WakefullnessLifecycle]. */ class NotOccludedCondition @Inject constructor( private val keyguardTransitionInteractorLazy: Lazy<KeyguardTransitionInteractor>, ) : ConditionalRestarter.Condition { override val canRestartNow: Flow<Boolean> get() { return keyguardTransitionInteractorLazy .get() .transitionValue(KeyguardState.OCCLUDED) .map { it == 0f } } }
packages/SystemUI/src/com/android/systemui/flags/PluggedInCondition.kt +17 −17 Original line number Diff line number Diff line Loading @@ -16,34 +16,34 @@ package com.android.systemui.flags import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow import com.android.systemui.statusbar.policy.BatteryController import dagger.Lazy import javax.inject.Inject import kotlinx.coroutines.channels.awaitClose /** Returns true when the device is plugged in. */ class PluggedInCondition @Inject constructor( private val batteryController: BatteryController, private val batteryControllerLazy: Lazy<BatteryController>, ) : ConditionalRestarter.Condition { var listenersAdded = false var retryFn: (() -> Unit)? = null override val canRestartNow = conflatedCallbackFlow { val batteryCallback = object : BatteryController.BatteryStateChangeCallback { override fun onBatteryLevelChanged(level: Int, pluggedIn: Boolean, charging: Boolean) { retryFn?.invoke() } override fun onBatteryLevelChanged( level: Int, pluggedIn: Boolean, charging: Boolean ) { trySend(pluggedIn) } override fun canRestartNow(retryFn: () -> Unit): Boolean { if (!listenersAdded) { listenersAdded = true batteryController.addCallback(batteryCallback) } batteryControllerLazy.get().addCallback(batteryCallback) this.retryFn = retryFn trySend(batteryControllerLazy.get().isPluggedIn) return batteryController.isPluggedIn awaitClose { batteryControllerLazy.get().removeCallback(batteryCallback) } } }