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