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

Commit c38ec1a5 authored by Dave Mankoff's avatar Dave Mankoff
Browse files

Restart after flag changes on screen off.

On debug builds, restart as soon as the screen goes off.
On release builds, restart after the device is plugged in,
the screen is off, and the device has been idle for a few
seconds.

The flag app does not yet reflect this change, but it will
allow multiple flags to be flipped.

Bug: 257302229
Test: manual
Change-Id: I9da58f9881973d69fc0e35b394ca42a4166ceb08
parent 5d076fc2
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -34,6 +34,9 @@ abstract class FlagsModule {
    @Binds
    abstract fun bindsFeatureFlagDebug(impl: FeatureFlagsDebug): FeatureFlags

    @Binds
    abstract fun bindsRestarter(debugRestarter: FeatureFlagsDebugRestarter): Restarter

    @Module
    companion object {
        @JvmStatic
+3 −0
Original line number Diff line number Diff line
@@ -27,4 +27,7 @@ import dagger.Module
abstract class FlagsModule {
    @Binds
    abstract fun bindsFeatureFlagRelease(impl: FeatureFlagsRelease): FeatureFlags

    @Binds
    abstract fun bindsRestarter(debugRestarter: FeatureFlagsReleaseRestarter): Restarter
}
+0 −1
Original line number Diff line number Diff line
@@ -336,7 +336,6 @@ public class FeatureFlagsDebug implements FeatureFlags {
            Log.i(TAG, "Android Restart Suppressed");
            return;
        }
        Log.i(TAG, "Restarting Android");
        mRestarter.restart();
    }

+51 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.flags

import android.util.Log
import com.android.systemui.keyguard.WakefulnessLifecycle
import javax.inject.Inject

/** Restarts SystemUI when the screen is locked. */
class FeatureFlagsDebugRestarter
@Inject
constructor(
    private val wakefulnessLifecycle: WakefulnessLifecycle,
    private val systemExitRestarter: SystemExitRestarter,
) : Restarter {

    val observer =
        object : WakefulnessLifecycle.Observer {
            override fun onFinishedGoingToSleep() {
                Log.d(FeatureFlagsDebug.TAG, "Restarting due to systemui flag change")
                restartNow()
            }
        }

    override fun restart() {
        Log.d(FeatureFlagsDebug.TAG, "Restart requested. Restarting on next screen off.")
        if (wakefulnessLifecycle.wakefulness == WakefulnessLifecycle.WAKEFULNESS_ASLEEP) {
            restartNow()
        } else {
            wakefulnessLifecycle.addObserver(observer)
        }
    }

    private fun restartNow() {
        systemExitRestarter.restart()
    }
}
+82 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2022 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.flags

import android.util.Log
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_ASLEEP
import com.android.systemui.statusbar.policy.BatteryController
import com.android.systemui.util.concurrency.DelayableExecutor
import java.util.concurrent.TimeUnit
import javax.inject.Inject

/** Restarts SystemUI when the device appears idle. */
class FeatureFlagsReleaseRestarter
@Inject
constructor(
    private val wakefulnessLifecycle: WakefulnessLifecycle,
    private val batteryController: BatteryController,
    @Background private val bgExecutor: DelayableExecutor,
    private val systemExitRestarter: SystemExitRestarter
) : Restarter {
    var shouldRestart = false
    var pendingRestart: Runnable? = null

    val observer =
        object : WakefulnessLifecycle.Observer {
            override fun onFinishedGoingToSleep() {
                maybeScheduleRestart()
            }
        }

    val batteryCallback =
        object : BatteryController.BatteryStateChangeCallback {
            override fun onBatteryLevelChanged(level: Int, pluggedIn: Boolean, charging: Boolean) {
                maybeScheduleRestart()
            }
        }

    override fun restart() {
        Log.d(FeatureFlagsDebug.TAG, "Restart requested. Restarting when plugged in and idle.")
        if (!shouldRestart) {
            // Don't bother scheduling twice.
            shouldRestart = true
            wakefulnessLifecycle.addObserver(observer)
            batteryController.addCallback(batteryCallback)
            maybeScheduleRestart()
        }
    }

    private fun maybeScheduleRestart() {
        if (
            wakefulnessLifecycle.wakefulness == WAKEFULNESS_ASLEEP && batteryController.isPluggedIn
        ) {
            if (pendingRestart == null) {
                pendingRestart = bgExecutor.executeDelayed(this::restartNow, 30L, TimeUnit.SECONDS)
            }
        } else if (pendingRestart != null) {
            pendingRestart?.run()
            pendingRestart = null
        }
    }

    private fun restartNow() {
        Log.d(FeatureFlagsRelease.TAG, "Restarting due to systemui flag change")
        systemExitRestarter.restart()
    }
}
Loading