Loading packages/SystemUI/src/com/android/systemui/doze/DozeHost.java +7 −5 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ public interface DozeHost { boolean isPowerSaveActive(); boolean isPulsingBlocked(); boolean isProvisioned(); boolean isBlockingDoze(); /** * Makes a current pulse last for twice as long. Loading Loading @@ -80,8 +79,9 @@ public interface DozeHost { */ void stopPulsing(); /** Returns whether doze is suppressed. */ boolean isDozeSuppressed(); /** Returns whether always-on-display is suppressed. This does not include suppressing * wake-up gestures. */ boolean isAlwaysOnSuppressed(); interface Callback { /** Loading @@ -97,8 +97,10 @@ public interface DozeHost { */ default void onPowerSaveChanged(boolean active) {} /** Called when the doze suppression state changes. */ default void onDozeSuppressedChanged(boolean suppressed) {} /** * Called when the always on suppression state changes. See {@link #isAlwaysOnSuppressed()}. */ default void onAlwaysOnSuppressedChanged(boolean suppressed) {} } interface PulseCallback { Loading packages/SystemUI/src/com/android/systemui/doze/DozeLog.java +29 −12 Original line number Diff line number Diff line Loading @@ -131,14 +131,6 @@ public class DozeLog implements Dumpable { mLogger.logDozingChanged(dozing); } /** * Appends dozing event to the logs * @param suppressed true if dozing is suppressed */ public void traceDozingSuppressed(boolean suppressed) { mLogger.logDozingSuppressed(suppressed); } /** * Appends fling event to the logs */ Loading Loading @@ -325,15 +317,40 @@ public class DozeLog implements Dumpable { } /** * Appends doze suppressed event to the logs * Appends the doze state that was suppressed to the doze event log * @param suppressedState The {@link DozeMachine.State} that was suppressed */ public void traceDozeSuppressed(DozeMachine.State suppressedState) { mLogger.logDozeSuppressed(suppressedState); public void traceAlwaysOnSuppressed(DozeMachine.State suppressedState) { mLogger.logAlwaysOnSuppressed(suppressedState); } /** * Appends reason why doze immediately ended. */ public void traceImmediatelyEndDoze(String reason) { mLogger.logImmediatelyEndDoze(reason); } /** * Appends power save changes that may cause a new doze state * @param powerSaveActive true if power saving is active * @param nextState the state that we'll transition to */ public void tracePowerSaveChanged(boolean powerSaveActive, DozeMachine.State nextState) { mLogger.logPowerSaveChanged(powerSaveActive, nextState); } /** * Appends an event on AOD suppression change * @param suppressed true if AOD is being suppressed * @param nextState the state that we'll transition to */ public void traceAlwaysOnSuppressedChange(boolean suppressed, DozeMachine.State nextState) { mLogger.logAlwaysOnSuppressedChange(suppressed, nextState); } /** * Appends new AOD sreen brightness to logs * Appends new AOD screen brightness to logs * @param brightness display brightness setting */ public void traceDozeScreenBrightness(int brightness) { Loading packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt +23 −5 Original line number Diff line number Diff line Loading @@ -74,11 +74,21 @@ class DozeLogger @Inject constructor( }) } fun logDozingSuppressed(isDozingSuppressed: Boolean) { fun logPowerSaveChanged(powerSaveActive: Boolean, nextState: DozeMachine.State) { buffer.log(TAG, INFO, { bool1 = isDozingSuppressed bool1 = powerSaveActive str1 = nextState.name }, { "DozingSuppressed=$bool1" "Power save active=$bool1 nextState=$str1" }) } fun logAlwaysOnSuppressedChange(isAodSuppressed: Boolean, nextState: DozeMachine.State) { buffer.log(TAG, INFO, { bool1 = isAodSuppressed str1 = nextState.name }, { "Always on (AOD) suppressed changed, suppressed=$bool1 nextState=$str1" }) } Loading Loading @@ -257,11 +267,19 @@ class DozeLogger @Inject constructor( }) } fun logDozeSuppressed(state: DozeMachine.State) { fun logAlwaysOnSuppressed(state: DozeMachine.State) { buffer.log(TAG, INFO, { str1 = state.name }, { "Doze state suppressed, state=$str1" "Always-on state suppressed, suppressed state=$str1" }) } fun logImmediatelyEndDoze(reason: String) { buffer.log(TAG, INFO, { str1 = reason }, { "Doze immediately ended due to $str1" }) } Loading packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java +2 −3 Original line number Diff line number Diff line Loading @@ -357,9 +357,9 @@ public class DozeMachine { if (mState == State.FINISH) { return State.FINISH; } if (mDozeHost.isDozeSuppressed() && requestedState.isAlwaysOn()) { if (mDozeHost.isAlwaysOnSuppressed() && requestedState.isAlwaysOn()) { Log.i(TAG, "Doze is suppressed. Suppressing state: " + requestedState); mDozeLog.traceDozeSuppressed(requestedState); mDozeLog.traceAlwaysOnSuppressed(requestedState); return State.DOZE; } if ((mState == State.DOZE_AOD_PAUSED || mState == State.DOZE_AOD_PAUSING Loading Loading @@ -415,7 +415,6 @@ public class DozeMachine { pw.print(" state="); pw.println(mState); pw.print(" wakeLockHeldForCurrentState="); pw.println(mWakeLockHeldForCurrentState); pw.print(" wakeLock="); pw.println(mWakeLock); pw.print(" isDozeSuppressed="); pw.println(mDozeHost.isDozeSuppressed()); pw.println("Parts:"); for (Part p : mParts) { p.dump(pw); Loading packages/SystemUI/src/com/android/systemui/doze/DozeSuppressor.java 0 → 100644 +195 −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.doze; import static android.app.UiModeManager.ACTION_ENTER_CAR_MODE; import android.app.UiModeManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.Configuration; import android.hardware.display.AmbientDisplayConfiguration; import android.os.PowerManager; import android.os.UserHandle; import android.text.TextUtils; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.doze.dagger.DozeScope; import com.android.systemui.statusbar.phone.BiometricUnlockController; import java.io.PrintWriter; import javax.inject.Inject; import dagger.Lazy; /** * Handles suppressing doze on: * 1. INITIALIZED, don't allow dozing at all when: * - in CAR_MODE * - device is NOT provisioned * - there's a pending authentication * 2. PowerSaveMode active * - no always-on-display (DOZE_AOD) * - continues to allow doze triggers (DOZE, DOZE_REQUEST_PULSE) * 3. Suppression changes from the PowerManager API. See {@link PowerManager#suppressAmbientDisplay} * and {@link DozeHost#isAlwaysOnSuppressed()}. * - no always-on-display (DOZE_AOD) * - allow doze triggers (DOZE), but disallow notifications (handled by {@link DozeTriggers}) * - See extra check in {@link DozeMachine} to guarantee device never enters always-on states */ @DozeScope public class DozeSuppressor implements DozeMachine.Part { private static final String TAG = "DozeSuppressor"; private DozeMachine mMachine; private final DozeHost mDozeHost; private final AmbientDisplayConfiguration mConfig; private final DozeLog mDozeLog; private final BroadcastDispatcher mBroadcastDispatcher; private final UiModeManager mUiModeManager; private final Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy; private boolean mBroadcastReceiverRegistered; @Inject public DozeSuppressor( DozeHost dozeHost, AmbientDisplayConfiguration config, DozeLog dozeLog, BroadcastDispatcher broadcastDispatcher, UiModeManager uiModeManager, Lazy<BiometricUnlockController> biometricUnlockControllerLazy) { mDozeHost = dozeHost; mConfig = config; mDozeLog = dozeLog; mBroadcastDispatcher = broadcastDispatcher; mUiModeManager = uiModeManager; mBiometricUnlockControllerLazy = biometricUnlockControllerLazy; } @Override public void setDozeMachine(DozeMachine dozeMachine) { mMachine = dozeMachine; } @Override public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) { switch (newState) { case INITIALIZED: registerBroadcastReceiver(); mDozeHost.addCallback(mHostCallback); checkShouldImmediatelyEndDoze(); break; case FINISH: destroy(); break; default: } } @Override public void destroy() { unregisterBroadcastReceiver(); mDozeHost.removeCallback(mHostCallback); } private void checkShouldImmediatelyEndDoze() { String reason = null; if (mUiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR) { reason = "car_mode"; } else if (!mDozeHost.isProvisioned()) { reason = "device_unprovisioned"; } else if (mBiometricUnlockControllerLazy.get().hasPendingAuthentication()) { reason = "has_pending_auth"; } if (!TextUtils.isEmpty(reason)) { mDozeLog.traceImmediatelyEndDoze(reason); mMachine.requestState(DozeMachine.State.FINISH); } } @Override public void dump(PrintWriter pw) { pw.println(" uiMode=" + mUiModeManager.getCurrentModeType()); pw.println(" hasPendingAuth=" + mBiometricUnlockControllerLazy.get().hasPendingAuthentication()); pw.println(" isProvisioned=" + mDozeHost.isProvisioned()); pw.println(" isAlwaysOnSuppressed=" + mDozeHost.isAlwaysOnSuppressed()); pw.println(" aodPowerSaveActive=" + mDozeHost.isPowerSaveActive()); } private void registerBroadcastReceiver() { if (mBroadcastReceiverRegistered) { return; } IntentFilter filter = new IntentFilter(ACTION_ENTER_CAR_MODE); mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter); mBroadcastReceiverRegistered = true; } private void unregisterBroadcastReceiver() { if (!mBroadcastReceiverRegistered) { return; } mBroadcastDispatcher.unregisterReceiver(mBroadcastReceiver); mBroadcastReceiverRegistered = false; } private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (ACTION_ENTER_CAR_MODE.equals(intent.getAction())) { mDozeLog.traceImmediatelyEndDoze("car_mode"); mMachine.requestState(DozeMachine.State.FINISH); } } }; private DozeHost.Callback mHostCallback = new DozeHost.Callback() { @Override public void onPowerSaveChanged(boolean active) { DozeMachine.State nextState = null; if (mDozeHost.isPowerSaveActive()) { nextState = DozeMachine.State.DOZE; } else if (mMachine.getState() == DozeMachine.State.DOZE && mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT)) { nextState = DozeMachine.State.DOZE_AOD; } if (nextState != null) { mDozeLog.tracePowerSaveChanged(mDozeHost.isPowerSaveActive(), nextState); mMachine.requestState(nextState); } } @Override public void onAlwaysOnSuppressedChanged(boolean suppressed) { final DozeMachine.State nextState; if (mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT) && !suppressed) { nextState = DozeMachine.State.DOZE_AOD; } else { nextState = DozeMachine.State.DOZE; } mDozeLog.traceAlwaysOnSuppressedChange(suppressed, nextState); mMachine.requestState(nextState); } }; } Loading
packages/SystemUI/src/com/android/systemui/doze/DozeHost.java +7 −5 Original line number Diff line number Diff line Loading @@ -31,7 +31,6 @@ public interface DozeHost { boolean isPowerSaveActive(); boolean isPulsingBlocked(); boolean isProvisioned(); boolean isBlockingDoze(); /** * Makes a current pulse last for twice as long. Loading Loading @@ -80,8 +79,9 @@ public interface DozeHost { */ void stopPulsing(); /** Returns whether doze is suppressed. */ boolean isDozeSuppressed(); /** Returns whether always-on-display is suppressed. This does not include suppressing * wake-up gestures. */ boolean isAlwaysOnSuppressed(); interface Callback { /** Loading @@ -97,8 +97,10 @@ public interface DozeHost { */ default void onPowerSaveChanged(boolean active) {} /** Called when the doze suppression state changes. */ default void onDozeSuppressedChanged(boolean suppressed) {} /** * Called when the always on suppression state changes. See {@link #isAlwaysOnSuppressed()}. */ default void onAlwaysOnSuppressedChanged(boolean suppressed) {} } interface PulseCallback { Loading
packages/SystemUI/src/com/android/systemui/doze/DozeLog.java +29 −12 Original line number Diff line number Diff line Loading @@ -131,14 +131,6 @@ public class DozeLog implements Dumpable { mLogger.logDozingChanged(dozing); } /** * Appends dozing event to the logs * @param suppressed true if dozing is suppressed */ public void traceDozingSuppressed(boolean suppressed) { mLogger.logDozingSuppressed(suppressed); } /** * Appends fling event to the logs */ Loading Loading @@ -325,15 +317,40 @@ public class DozeLog implements Dumpable { } /** * Appends doze suppressed event to the logs * Appends the doze state that was suppressed to the doze event log * @param suppressedState The {@link DozeMachine.State} that was suppressed */ public void traceDozeSuppressed(DozeMachine.State suppressedState) { mLogger.logDozeSuppressed(suppressedState); public void traceAlwaysOnSuppressed(DozeMachine.State suppressedState) { mLogger.logAlwaysOnSuppressed(suppressedState); } /** * Appends reason why doze immediately ended. */ public void traceImmediatelyEndDoze(String reason) { mLogger.logImmediatelyEndDoze(reason); } /** * Appends power save changes that may cause a new doze state * @param powerSaveActive true if power saving is active * @param nextState the state that we'll transition to */ public void tracePowerSaveChanged(boolean powerSaveActive, DozeMachine.State nextState) { mLogger.logPowerSaveChanged(powerSaveActive, nextState); } /** * Appends an event on AOD suppression change * @param suppressed true if AOD is being suppressed * @param nextState the state that we'll transition to */ public void traceAlwaysOnSuppressedChange(boolean suppressed, DozeMachine.State nextState) { mLogger.logAlwaysOnSuppressedChange(suppressed, nextState); } /** * Appends new AOD sreen brightness to logs * Appends new AOD screen brightness to logs * @param brightness display brightness setting */ public void traceDozeScreenBrightness(int brightness) { Loading
packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt +23 −5 Original line number Diff line number Diff line Loading @@ -74,11 +74,21 @@ class DozeLogger @Inject constructor( }) } fun logDozingSuppressed(isDozingSuppressed: Boolean) { fun logPowerSaveChanged(powerSaveActive: Boolean, nextState: DozeMachine.State) { buffer.log(TAG, INFO, { bool1 = isDozingSuppressed bool1 = powerSaveActive str1 = nextState.name }, { "DozingSuppressed=$bool1" "Power save active=$bool1 nextState=$str1" }) } fun logAlwaysOnSuppressedChange(isAodSuppressed: Boolean, nextState: DozeMachine.State) { buffer.log(TAG, INFO, { bool1 = isAodSuppressed str1 = nextState.name }, { "Always on (AOD) suppressed changed, suppressed=$bool1 nextState=$str1" }) } Loading Loading @@ -257,11 +267,19 @@ class DozeLogger @Inject constructor( }) } fun logDozeSuppressed(state: DozeMachine.State) { fun logAlwaysOnSuppressed(state: DozeMachine.State) { buffer.log(TAG, INFO, { str1 = state.name }, { "Doze state suppressed, state=$str1" "Always-on state suppressed, suppressed state=$str1" }) } fun logImmediatelyEndDoze(reason: String) { buffer.log(TAG, INFO, { str1 = reason }, { "Doze immediately ended due to $str1" }) } Loading
packages/SystemUI/src/com/android/systemui/doze/DozeMachine.java +2 −3 Original line number Diff line number Diff line Loading @@ -357,9 +357,9 @@ public class DozeMachine { if (mState == State.FINISH) { return State.FINISH; } if (mDozeHost.isDozeSuppressed() && requestedState.isAlwaysOn()) { if (mDozeHost.isAlwaysOnSuppressed() && requestedState.isAlwaysOn()) { Log.i(TAG, "Doze is suppressed. Suppressing state: " + requestedState); mDozeLog.traceDozeSuppressed(requestedState); mDozeLog.traceAlwaysOnSuppressed(requestedState); return State.DOZE; } if ((mState == State.DOZE_AOD_PAUSED || mState == State.DOZE_AOD_PAUSING Loading Loading @@ -415,7 +415,6 @@ public class DozeMachine { pw.print(" state="); pw.println(mState); pw.print(" wakeLockHeldForCurrentState="); pw.println(mWakeLockHeldForCurrentState); pw.print(" wakeLock="); pw.println(mWakeLock); pw.print(" isDozeSuppressed="); pw.println(mDozeHost.isDozeSuppressed()); pw.println("Parts:"); for (Part p : mParts) { p.dump(pw); Loading
packages/SystemUI/src/com/android/systemui/doze/DozeSuppressor.java 0 → 100644 +195 −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.doze; import static android.app.UiModeManager.ACTION_ENTER_CAR_MODE; import android.app.UiModeManager; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.res.Configuration; import android.hardware.display.AmbientDisplayConfiguration; import android.os.PowerManager; import android.os.UserHandle; import android.text.TextUtils; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.doze.dagger.DozeScope; import com.android.systemui.statusbar.phone.BiometricUnlockController; import java.io.PrintWriter; import javax.inject.Inject; import dagger.Lazy; /** * Handles suppressing doze on: * 1. INITIALIZED, don't allow dozing at all when: * - in CAR_MODE * - device is NOT provisioned * - there's a pending authentication * 2. PowerSaveMode active * - no always-on-display (DOZE_AOD) * - continues to allow doze triggers (DOZE, DOZE_REQUEST_PULSE) * 3. Suppression changes from the PowerManager API. See {@link PowerManager#suppressAmbientDisplay} * and {@link DozeHost#isAlwaysOnSuppressed()}. * - no always-on-display (DOZE_AOD) * - allow doze triggers (DOZE), but disallow notifications (handled by {@link DozeTriggers}) * - See extra check in {@link DozeMachine} to guarantee device never enters always-on states */ @DozeScope public class DozeSuppressor implements DozeMachine.Part { private static final String TAG = "DozeSuppressor"; private DozeMachine mMachine; private final DozeHost mDozeHost; private final AmbientDisplayConfiguration mConfig; private final DozeLog mDozeLog; private final BroadcastDispatcher mBroadcastDispatcher; private final UiModeManager mUiModeManager; private final Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy; private boolean mBroadcastReceiverRegistered; @Inject public DozeSuppressor( DozeHost dozeHost, AmbientDisplayConfiguration config, DozeLog dozeLog, BroadcastDispatcher broadcastDispatcher, UiModeManager uiModeManager, Lazy<BiometricUnlockController> biometricUnlockControllerLazy) { mDozeHost = dozeHost; mConfig = config; mDozeLog = dozeLog; mBroadcastDispatcher = broadcastDispatcher; mUiModeManager = uiModeManager; mBiometricUnlockControllerLazy = biometricUnlockControllerLazy; } @Override public void setDozeMachine(DozeMachine dozeMachine) { mMachine = dozeMachine; } @Override public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) { switch (newState) { case INITIALIZED: registerBroadcastReceiver(); mDozeHost.addCallback(mHostCallback); checkShouldImmediatelyEndDoze(); break; case FINISH: destroy(); break; default: } } @Override public void destroy() { unregisterBroadcastReceiver(); mDozeHost.removeCallback(mHostCallback); } private void checkShouldImmediatelyEndDoze() { String reason = null; if (mUiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR) { reason = "car_mode"; } else if (!mDozeHost.isProvisioned()) { reason = "device_unprovisioned"; } else if (mBiometricUnlockControllerLazy.get().hasPendingAuthentication()) { reason = "has_pending_auth"; } if (!TextUtils.isEmpty(reason)) { mDozeLog.traceImmediatelyEndDoze(reason); mMachine.requestState(DozeMachine.State.FINISH); } } @Override public void dump(PrintWriter pw) { pw.println(" uiMode=" + mUiModeManager.getCurrentModeType()); pw.println(" hasPendingAuth=" + mBiometricUnlockControllerLazy.get().hasPendingAuthentication()); pw.println(" isProvisioned=" + mDozeHost.isProvisioned()); pw.println(" isAlwaysOnSuppressed=" + mDozeHost.isAlwaysOnSuppressed()); pw.println(" aodPowerSaveActive=" + mDozeHost.isPowerSaveActive()); } private void registerBroadcastReceiver() { if (mBroadcastReceiverRegistered) { return; } IntentFilter filter = new IntentFilter(ACTION_ENTER_CAR_MODE); mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter); mBroadcastReceiverRegistered = true; } private void unregisterBroadcastReceiver() { if (!mBroadcastReceiverRegistered) { return; } mBroadcastDispatcher.unregisterReceiver(mBroadcastReceiver); mBroadcastReceiverRegistered = false; } private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { if (ACTION_ENTER_CAR_MODE.equals(intent.getAction())) { mDozeLog.traceImmediatelyEndDoze("car_mode"); mMachine.requestState(DozeMachine.State.FINISH); } } }; private DozeHost.Callback mHostCallback = new DozeHost.Callback() { @Override public void onPowerSaveChanged(boolean active) { DozeMachine.State nextState = null; if (mDozeHost.isPowerSaveActive()) { nextState = DozeMachine.State.DOZE; } else if (mMachine.getState() == DozeMachine.State.DOZE && mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT)) { nextState = DozeMachine.State.DOZE_AOD; } if (nextState != null) { mDozeLog.tracePowerSaveChanged(mDozeHost.isPowerSaveActive(), nextState); mMachine.requestState(nextState); } } @Override public void onAlwaysOnSuppressedChanged(boolean suppressed) { final DozeMachine.State nextState; if (mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT) && !suppressed) { nextState = DozeMachine.State.DOZE_AOD; } else { nextState = DozeMachine.State.DOZE; } mDozeLog.traceAlwaysOnSuppressedChange(suppressed, nextState); mMachine.requestState(nextState); } }; }