Loading packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugStartable.kt +7 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import com.android.systemui.broadcast.BroadcastSender import com.android.systemui.dump.DumpManager import com.android.systemui.statusbar.commandline.CommandRegistry import com.android.systemui.util.InitializationChecker import com.android.systemui.util.concurrency.DelayableExecutor import dagger.Binds import dagger.Module import dagger.multibindings.ClassKey Loading @@ -36,7 +37,9 @@ constructor( private val flagCommand: FlagCommand, private val featureFlags: FeatureFlagsDebug, private val broadcastSender: BroadcastSender, private val initializationChecker: InitializationChecker private val initializationChecker: InitializationChecker, private val restartDozeListener: RestartDozeListener, private val delayableExecutor: DelayableExecutor ) : CoreStartable { init { Loading @@ -52,6 +55,9 @@ constructor( // protected broadcast should only be sent for the main process val intent = Intent(FlagManager.ACTION_SYSUI_STARTED) broadcastSender.sendBroadcast(intent) restartDozeListener.init() delayableExecutor.executeDelayed({ restartDozeListener.maybeRestartSleep() }, 1000) } } } Loading packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseStartable.kt +13 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ package com.android.systemui.flags import com.android.systemui.CoreStartable import com.android.systemui.dump.DumpManager import com.android.systemui.util.InitializationChecker import com.android.systemui.util.concurrency.DelayableExecutor import dagger.Binds import dagger.Module import dagger.multibindings.ClassKey Loading @@ -26,7 +28,13 @@ import javax.inject.Inject class FeatureFlagsReleaseStartable @Inject constructor(dumpManager: DumpManager, featureFlags: FeatureFlags) : CoreStartable { constructor( dumpManager: DumpManager, featureFlags: FeatureFlags, private val initializationChecker: InitializationChecker, private val restartDozeListener: RestartDozeListener, private val delayableExecutor: DelayableExecutor ) : CoreStartable { init { dumpManager.registerCriticalDumpable(FeatureFlagsRelease.TAG) { pw, args -> Loading @@ -35,7 +43,10 @@ constructor(dumpManager: DumpManager, featureFlags: FeatureFlags) : CoreStartabl } override fun start() { // no-op if (initializationChecker.initializeComponents()) { restartDozeListener.init() delayableExecutor.executeDelayed({ restartDozeListener.maybeRestartSleep() }, 1000) } } } Loading packages/SystemUI/src/com/android/systemui/flags/RestartDozeListener.kt 0 → 100644 +72 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.os.PowerManager import android.util.Log import com.android.internal.annotations.VisibleForTesting import com.android.systemui.dagger.SysUISingleton import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.util.settings.SecureSettings import com.android.systemui.util.time.SystemClock import javax.inject.Inject @SysUISingleton class RestartDozeListener @Inject constructor( private val settings: SecureSettings, private val statusBarStateController: StatusBarStateController, private val powerManager: PowerManager, private val systemClock: SystemClock, ) { companion object { @VisibleForTesting val RESTART_NAP_KEY = "restart_nap_after_start" } private var inited = false val listener = object : StatusBarStateController.StateListener { override fun onDreamingChanged(isDreaming: Boolean) { settings.putBool(RESTART_NAP_KEY, isDreaming) } } fun init() { if (inited) { return } inited = true statusBarStateController.addCallback(listener) } fun destroy() { statusBarStateController.removeCallback(listener) } fun maybeRestartSleep() { if (settings.getBool(RESTART_NAP_KEY, false)) { Log.d("RestartDozeListener", "Restarting sleep state") powerManager.wakeUp(systemClock.uptimeMillis()) powerManager.goToSleep(systemClock.uptimeMillis()) settings.putBool(RESTART_NAP_KEY, false) } } } packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt +1 −6 Original line number Diff line number Diff line Loading @@ -62,11 +62,10 @@ class ServerFlagReaderImpl @Inject constructor( return } for ((listener, flags) in listeners) { propLoop@ for (propName in properties.keyset) { for (flag in flags) { if (propName == getServerOverrideName(flag.id) || propName == flag.name) { if (propName == flag.name) { listener.onChange(flag) break@propLoop } Loading Loading @@ -103,10 +102,6 @@ class ServerFlagReaderImpl @Inject constructor( } listeners.add(Pair(listener, flags)) } private fun getServerOverrideName(flagId: Int): String { return "flag_override_$flagId" } } @Module Loading packages/SystemUI/tests/src/com/android/systemui/flags/RestartDozeListenerTest.kt 0 → 100644 +85 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.os.PowerManager import android.test.suitebuilder.annotation.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.util.settings.FakeSettings import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test import org.mockito.ArgumentCaptor import org.mockito.Mock import org.mockito.Mockito.anyLong import org.mockito.Mockito.never import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @SmallTest class RestartDozeListenerTest : SysuiTestCase() { lateinit var restartDozeListener: RestartDozeListener val settings = FakeSettings() @Mock lateinit var statusBarStateController: StatusBarStateController @Mock lateinit var powerManager: PowerManager val clock = FakeSystemClock() lateinit var listener: StatusBarStateController.StateListener @Before fun setup() { MockitoAnnotations.initMocks(this) restartDozeListener = RestartDozeListener(settings, statusBarStateController, powerManager, clock) val captor = ArgumentCaptor.forClass(StatusBarStateController.StateListener::class.java) restartDozeListener.init() verify(statusBarStateController).addCallback(captor.capture()) listener = captor.value } @Test fun testStoreDreamState_onDreamingStarted() { listener.onDreamingChanged(true) assertThat(settings.getBool(RestartDozeListener.RESTART_NAP_KEY)).isTrue() } @Test fun testStoreDreamState_onDreamingStopped() { listener.onDreamingChanged(false) assertThat(settings.getBool(RestartDozeListener.RESTART_NAP_KEY)).isFalse() } @Test fun testRestoreDreamState_dreamingShouldStart() { settings.putBool(RestartDozeListener.RESTART_NAP_KEY, true) restartDozeListener.maybeRestartSleep() verify(powerManager).wakeUp(clock.uptimeMillis()) verify(powerManager).goToSleep(clock.uptimeMillis()) } @Test fun testRestoreDreamState_dreamingShouldNot() { settings.putBool(RestartDozeListener.RESTART_NAP_KEY, false) restartDozeListener.maybeRestartSleep() verify(powerManager, never()).wakeUp(anyLong()) verify(powerManager, never()).goToSleep(anyLong()) } } Loading
packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugStartable.kt +7 −1 Original line number Diff line number Diff line Loading @@ -22,6 +22,7 @@ import com.android.systemui.broadcast.BroadcastSender import com.android.systemui.dump.DumpManager import com.android.systemui.statusbar.commandline.CommandRegistry import com.android.systemui.util.InitializationChecker import com.android.systemui.util.concurrency.DelayableExecutor import dagger.Binds import dagger.Module import dagger.multibindings.ClassKey Loading @@ -36,7 +37,9 @@ constructor( private val flagCommand: FlagCommand, private val featureFlags: FeatureFlagsDebug, private val broadcastSender: BroadcastSender, private val initializationChecker: InitializationChecker private val initializationChecker: InitializationChecker, private val restartDozeListener: RestartDozeListener, private val delayableExecutor: DelayableExecutor ) : CoreStartable { init { Loading @@ -52,6 +55,9 @@ constructor( // protected broadcast should only be sent for the main process val intent = Intent(FlagManager.ACTION_SYSUI_STARTED) broadcastSender.sendBroadcast(intent) restartDozeListener.init() delayableExecutor.executeDelayed({ restartDozeListener.maybeRestartSleep() }, 1000) } } } Loading
packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseStartable.kt +13 −2 Original line number Diff line number Diff line Loading @@ -18,6 +18,8 @@ package com.android.systemui.flags import com.android.systemui.CoreStartable import com.android.systemui.dump.DumpManager import com.android.systemui.util.InitializationChecker import com.android.systemui.util.concurrency.DelayableExecutor import dagger.Binds import dagger.Module import dagger.multibindings.ClassKey Loading @@ -26,7 +28,13 @@ import javax.inject.Inject class FeatureFlagsReleaseStartable @Inject constructor(dumpManager: DumpManager, featureFlags: FeatureFlags) : CoreStartable { constructor( dumpManager: DumpManager, featureFlags: FeatureFlags, private val initializationChecker: InitializationChecker, private val restartDozeListener: RestartDozeListener, private val delayableExecutor: DelayableExecutor ) : CoreStartable { init { dumpManager.registerCriticalDumpable(FeatureFlagsRelease.TAG) { pw, args -> Loading @@ -35,7 +43,10 @@ constructor(dumpManager: DumpManager, featureFlags: FeatureFlags) : CoreStartabl } override fun start() { // no-op if (initializationChecker.initializeComponents()) { restartDozeListener.init() delayableExecutor.executeDelayed({ restartDozeListener.maybeRestartSleep() }, 1000) } } } Loading
packages/SystemUI/src/com/android/systemui/flags/RestartDozeListener.kt 0 → 100644 +72 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.os.PowerManager import android.util.Log import com.android.internal.annotations.VisibleForTesting import com.android.systemui.dagger.SysUISingleton import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.util.settings.SecureSettings import com.android.systemui.util.time.SystemClock import javax.inject.Inject @SysUISingleton class RestartDozeListener @Inject constructor( private val settings: SecureSettings, private val statusBarStateController: StatusBarStateController, private val powerManager: PowerManager, private val systemClock: SystemClock, ) { companion object { @VisibleForTesting val RESTART_NAP_KEY = "restart_nap_after_start" } private var inited = false val listener = object : StatusBarStateController.StateListener { override fun onDreamingChanged(isDreaming: Boolean) { settings.putBool(RESTART_NAP_KEY, isDreaming) } } fun init() { if (inited) { return } inited = true statusBarStateController.addCallback(listener) } fun destroy() { statusBarStateController.removeCallback(listener) } fun maybeRestartSleep() { if (settings.getBool(RESTART_NAP_KEY, false)) { Log.d("RestartDozeListener", "Restarting sleep state") powerManager.wakeUp(systemClock.uptimeMillis()) powerManager.goToSleep(systemClock.uptimeMillis()) settings.putBool(RESTART_NAP_KEY, false) } } }
packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt +1 −6 Original line number Diff line number Diff line Loading @@ -62,11 +62,10 @@ class ServerFlagReaderImpl @Inject constructor( return } for ((listener, flags) in listeners) { propLoop@ for (propName in properties.keyset) { for (flag in flags) { if (propName == getServerOverrideName(flag.id) || propName == flag.name) { if (propName == flag.name) { listener.onChange(flag) break@propLoop } Loading Loading @@ -103,10 +102,6 @@ class ServerFlagReaderImpl @Inject constructor( } listeners.add(Pair(listener, flags)) } private fun getServerOverrideName(flagId: Int): String { return "flag_override_$flagId" } } @Module Loading
packages/SystemUI/tests/src/com/android/systemui/flags/RestartDozeListenerTest.kt 0 → 100644 +85 −0 Original line number Diff line number Diff line /* * Copyright (C) 2023 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.os.PowerManager import android.test.suitebuilder.annotation.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.plugins.statusbar.StatusBarStateController import com.android.systemui.util.settings.FakeSettings import com.android.systemui.util.time.FakeSystemClock import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test import org.mockito.ArgumentCaptor import org.mockito.Mock import org.mockito.Mockito.anyLong import org.mockito.Mockito.never import org.mockito.Mockito.verify import org.mockito.MockitoAnnotations @SmallTest class RestartDozeListenerTest : SysuiTestCase() { lateinit var restartDozeListener: RestartDozeListener val settings = FakeSettings() @Mock lateinit var statusBarStateController: StatusBarStateController @Mock lateinit var powerManager: PowerManager val clock = FakeSystemClock() lateinit var listener: StatusBarStateController.StateListener @Before fun setup() { MockitoAnnotations.initMocks(this) restartDozeListener = RestartDozeListener(settings, statusBarStateController, powerManager, clock) val captor = ArgumentCaptor.forClass(StatusBarStateController.StateListener::class.java) restartDozeListener.init() verify(statusBarStateController).addCallback(captor.capture()) listener = captor.value } @Test fun testStoreDreamState_onDreamingStarted() { listener.onDreamingChanged(true) assertThat(settings.getBool(RestartDozeListener.RESTART_NAP_KEY)).isTrue() } @Test fun testStoreDreamState_onDreamingStopped() { listener.onDreamingChanged(false) assertThat(settings.getBool(RestartDozeListener.RESTART_NAP_KEY)).isFalse() } @Test fun testRestoreDreamState_dreamingShouldStart() { settings.putBool(RestartDozeListener.RESTART_NAP_KEY, true) restartDozeListener.maybeRestartSleep() verify(powerManager).wakeUp(clock.uptimeMillis()) verify(powerManager).goToSleep(clock.uptimeMillis()) } @Test fun testRestoreDreamState_dreamingShouldNot() { settings.putBool(RestartDozeListener.RESTART_NAP_KEY, false) restartDozeListener.maybeRestartSleep() verify(powerManager, never()).wakeUp(anyLong()) verify(powerManager, never()).goToSleep(anyLong()) } }