Merge "Suspend and resume DozeTriggers when entering and exiting car mode." into tm-qpr-dev

This commit is contained in:
Chandru S
2022-06-02 10:10:39 +00:00
committed by Android (Google) Code Review
12 changed files with 272 additions and 42 deletions

View File

@@ -17,6 +17,9 @@ Note: The default UI used in AOD shares views with the Lock Screen and does not
### DOZE ### DOZE
Device is asleep and listening for enabled pulsing and wake-up gesture triggers. In this state, no UI shows. Device is asleep and listening for enabled pulsing and wake-up gesture triggers. In this state, no UI shows.
### DOZE_SUSPEND_TRIGGERS
Device is asleep and not listening for any triggers to wake up. This state is used only when CAR_MODE is active. In this state, no UI shows.
### DOZE_AOD ### DOZE_AOD
Device is asleep, showing UI, and listening for enabled pulsing and wake-up triggers. In this state, screen brightness is handled by [DozeScreenBrightness][5] which uses the brightness sensor specified by `doze_brightness_sensor_type` in the [SystemUI config][6]. To save power, this should be a low-powered sensor that shouldn't trigger as often as the light sensor used for on-screen adaptive brightness. Device is asleep, showing UI, and listening for enabled pulsing and wake-up triggers. In this state, screen brightness is handled by [DozeScreenBrightness][5] which uses the brightness sensor specified by `doze_brightness_sensor_type` in the [SystemUI config][6]. To save power, this should be a low-powered sensor that shouldn't trigger as often as the light sensor used for on-screen adaptive brightness.

View File

@@ -331,6 +331,20 @@ public class DozeLog implements Dumpable {
mLogger.logImmediatelyEndDoze(reason); mLogger.logImmediatelyEndDoze(reason);
} }
/**
* Logs the car mode started event.
*/
public void traceCarModeStarted() {
mLogger.logCarModeStarted();
}
/**
* Logs the car mode ended event.
*/
public void traceCarModeEnded() {
mLogger.logCarModeEnded();
}
/** /**
* Appends power save changes that may cause a new doze state * Appends power save changes that may cause a new doze state
* @param powerSaveActive true if power saving is active * @param powerSaveActive true if power saving is active

View File

@@ -105,7 +105,7 @@ class DozeLogger @Inject constructor(
bool4 = screenOnFromTouch bool4 = screenOnFromTouch
}, { }, {
"Fling expand=$bool1 aboveThreshold=$bool2 thresholdNeeded=$bool3 " + "Fling expand=$bool1 aboveThreshold=$bool2 thresholdNeeded=$bool3 " +
"screenOnFromTouch=$bool4" "screenOnFromTouch=$bool4"
}) })
} }
@@ -151,7 +151,7 @@ class DozeLogger @Inject constructor(
long2 = triggerAt long2 = triggerAt
}, { }, {
"Time tick scheduledAt=${DATE_FORMAT.format(Date(long1))} " + "Time tick scheduledAt=${DATE_FORMAT.format(Date(long1))} " +
"triggerAt=${DATE_FORMAT.format(Date(long2))}" "triggerAt=${DATE_FORMAT.format(Date(long2))}"
}) })
} }
@@ -220,7 +220,7 @@ class DozeLogger @Inject constructor(
str1 = partUpdated str1 = partUpdated
}, { }, {
"Posture changed, posture=${DevicePostureController.devicePostureToString(int1)}" + "Posture changed, posture=${DevicePostureController.devicePostureToString(int1)}" +
" partUpdated=$str1" " partUpdated=$str1"
}) })
} }
@@ -299,6 +299,18 @@ class DozeLogger @Inject constructor(
"Doze aod dimming scrim opacity set, opacity=$long1" "Doze aod dimming scrim opacity set, opacity=$long1"
}) })
} }
fun logCarModeEnded() {
buffer.log(TAG, INFO, {}, {
"Doze car mode ended"
})
}
fun logCarModeStarted() {
buffer.log(TAG, INFO, {}, {
"Doze car mode started"
})
}
} }
private const val TAG = "DozeLog" private const val TAG = "DozeLog"

View File

@@ -20,6 +20,8 @@ import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWA
import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_WAKING; import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_WAKING;
import android.annotation.MainThread; import android.annotation.MainThread;
import android.app.UiModeManager;
import android.content.res.Configuration;
import android.hardware.display.AmbientDisplayConfiguration; import android.hardware.display.AmbientDisplayConfiguration;
import android.os.Trace; import android.os.Trace;
import android.os.UserHandle; import android.os.UserHandle;
@@ -33,7 +35,6 @@ import com.android.systemui.doze.dagger.WrappedService;
import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.keyguard.WakefulnessLifecycle.Wakefulness; import com.android.systemui.keyguard.WakefulnessLifecycle.Wakefulness;
import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.util.Assert; import com.android.systemui.util.Assert;
import com.android.systemui.util.wakelock.WakeLock; import com.android.systemui.util.wakelock.WakeLock;
@@ -66,6 +67,8 @@ public class DozeMachine {
INITIALIZED, INITIALIZED,
/** Regular doze. Device is asleep and listening for pulse triggers. */ /** Regular doze. Device is asleep and listening for pulse triggers. */
DOZE, DOZE,
/** Deep doze. Device is asleep and is not listening for pulse triggers. */
DOZE_SUSPEND_TRIGGERS,
/** Always-on doze. Device is asleep, showing UI and listening for pulse triggers. */ /** Always-on doze. Device is asleep, showing UI and listening for pulse triggers. */
DOZE_AOD, DOZE_AOD,
/** Pulse has been requested. Device is awake and preparing UI */ /** Pulse has been requested. Device is awake and preparing UI */
@@ -125,6 +128,7 @@ public class DozeMachine {
: Display.STATE_ON; : Display.STATE_ON;
case DOZE_AOD_PAUSED: case DOZE_AOD_PAUSED:
case DOZE: case DOZE:
case DOZE_SUSPEND_TRIGGERS:
return Display.STATE_OFF; return Display.STATE_OFF;
case DOZE_PULSING: case DOZE_PULSING:
case DOZE_PULSING_BRIGHT: case DOZE_PULSING_BRIGHT:
@@ -143,26 +147,27 @@ public class DozeMachine {
private final WakeLock mWakeLock; private final WakeLock mWakeLock;
private final AmbientDisplayConfiguration mConfig; private final AmbientDisplayConfiguration mConfig;
private final WakefulnessLifecycle mWakefulnessLifecycle; private final WakefulnessLifecycle mWakefulnessLifecycle;
private final BatteryController mBatteryController;
private final DozeHost mDozeHost; private final DozeHost mDozeHost;
private Part[] mParts; private final UiModeManager mUiModeManager;
private final DockManager mDockManager;
private final Part[] mParts;
private final ArrayList<State> mQueuedRequests = new ArrayList<>(); private final ArrayList<State> mQueuedRequests = new ArrayList<>();
private State mState = State.UNINITIALIZED; private State mState = State.UNINITIALIZED;
private int mPulseReason; private int mPulseReason;
private boolean mWakeLockHeldForCurrentState = false; private boolean mWakeLockHeldForCurrentState = false;
private DockManager mDockManager;
@Inject @Inject
public DozeMachine(@WrappedService Service service, AmbientDisplayConfiguration config, public DozeMachine(@WrappedService Service service, AmbientDisplayConfiguration config,
WakeLock wakeLock, WakefulnessLifecycle wakefulnessLifecycle, WakeLock wakeLock, WakefulnessLifecycle wakefulnessLifecycle,
BatteryController batteryController, DozeLog dozeLog, DockManager dockManager, UiModeManager uiModeManager,
DozeLog dozeLog, DockManager dockManager,
DozeHost dozeHost, Part[] parts) { DozeHost dozeHost, Part[] parts) {
mDozeService = service; mDozeService = service;
mConfig = config; mConfig = config;
mWakefulnessLifecycle = wakefulnessLifecycle; mWakefulnessLifecycle = wakefulnessLifecycle;
mWakeLock = wakeLock; mWakeLock = wakeLock;
mBatteryController = batteryController; mUiModeManager = uiModeManager;
mDozeLog = dozeLog; mDozeLog = dozeLog;
mDockManager = dockManager; mDockManager = dockManager;
mDozeHost = dozeHost; mDozeHost = dozeHost;
@@ -244,7 +249,7 @@ public class DozeMachine {
Assert.isMainThread(); Assert.isMainThread();
if (isExecutingTransition()) { if (isExecutingTransition()) {
throw new IllegalStateException("Cannot get state because there were pending " throw new IllegalStateException("Cannot get state because there were pending "
+ "transitions: " + mQueuedRequests.toString()); + "transitions: " + mQueuedRequests);
} }
return mState; return mState;
} }
@@ -313,11 +318,8 @@ public class DozeMachine {
} }
mDozeLog.traceDozeStateSendComplete(newState); mDozeLog.traceDozeStateSendComplete(newState);
switch (newState) { if (newState == State.FINISH) {
case FINISH: mDozeService.finish();
mDozeService.finish();
break;
default:
} }
} }
@@ -357,6 +359,12 @@ public class DozeMachine {
if (mState == State.FINISH) { if (mState == State.FINISH) {
return State.FINISH; return State.FINISH;
} }
if (mUiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR
&& (requestedState.canPulse() || requestedState.staysAwake())) {
Log.i(TAG, "Doze is suppressed with all triggers disabled as car mode is active");
mDozeLog.traceCarModeStarted();
return State.DOZE_SUSPEND_TRIGGERS;
}
if (mDozeHost.isAlwaysOnSuppressed() && requestedState.isAlwaysOn()) { if (mDozeHost.isAlwaysOnSuppressed() && requestedState.isAlwaysOn()) {
Log.i(TAG, "Doze is suppressed by an app. Suppressing state: " + requestedState); Log.i(TAG, "Doze is suppressed by an app. Suppressing state: " + requestedState);
mDozeLog.traceAlwaysOnSuppressed(requestedState, "app"); mDozeLog.traceAlwaysOnSuppressed(requestedState, "app");

View File

@@ -147,6 +147,7 @@ public class DozeScreenBrightness extends BroadcastReceiver implements DozeMachi
setLightSensorEnabled(true); setLightSensorEnabled(true);
break; break;
case DOZE: case DOZE:
case DOZE_SUSPEND_TRIGGERS:
setLightSensorEnabled(false); setLightSensorEnabled(false);
resetBrightnessToDefault(); resetBrightnessToDefault();
break; break;

View File

@@ -17,6 +17,7 @@
package com.android.systemui.doze; package com.android.systemui.doze;
import static android.app.UiModeManager.ACTION_ENTER_CAR_MODE; import static android.app.UiModeManager.ACTION_ENTER_CAR_MODE;
import static android.app.UiModeManager.ACTION_EXIT_CAR_MODE;
import android.app.UiModeManager; import android.app.UiModeManager;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
@@ -96,6 +97,7 @@ public class DozeSuppressor implements DozeMachine.Part {
registerBroadcastReceiver(); registerBroadcastReceiver();
mDozeHost.addCallback(mHostCallback); mDozeHost.addCallback(mHostCallback);
checkShouldImmediatelyEndDoze(); checkShouldImmediatelyEndDoze();
checkShouldImmediatelySuspendDoze();
break; break;
case FINISH: case FINISH:
destroy(); destroy();
@@ -110,11 +112,16 @@ public class DozeSuppressor implements DozeMachine.Part {
mDozeHost.removeCallback(mHostCallback); mDozeHost.removeCallback(mHostCallback);
} }
private void checkShouldImmediatelySuspendDoze() {
if (mUiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR) {
mDozeLog.traceCarModeStarted();
mMachine.requestState(DozeMachine.State.DOZE_SUSPEND_TRIGGERS);
}
}
private void checkShouldImmediatelyEndDoze() { private void checkShouldImmediatelyEndDoze() {
String reason = null; String reason = null;
if (mUiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR) { if (!mDozeHost.isProvisioned()) {
reason = "car_mode";
} else if (!mDozeHost.isProvisioned()) {
reason = "device_unprovisioned"; reason = "device_unprovisioned";
} else if (mBiometricUnlockControllerLazy.get().hasPendingAuthentication()) { } else if (mBiometricUnlockControllerLazy.get().hasPendingAuthentication()) {
reason = "has_pending_auth"; reason = "has_pending_auth";
@@ -141,6 +148,7 @@ public class DozeSuppressor implements DozeMachine.Part {
return; return;
} }
IntentFilter filter = new IntentFilter(ACTION_ENTER_CAR_MODE); IntentFilter filter = new IntentFilter(ACTION_ENTER_CAR_MODE);
filter.addAction(ACTION_EXIT_CAR_MODE);
mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter); mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter);
mBroadcastReceiverRegistered = true; mBroadcastReceiverRegistered = true;
} }
@@ -156,9 +164,14 @@ public class DozeSuppressor implements DozeMachine.Part {
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
if (ACTION_ENTER_CAR_MODE.equals(intent.getAction())) { String action = intent.getAction();
mDozeLog.traceImmediatelyEndDoze("car_mode"); if (ACTION_ENTER_CAR_MODE.equals(action)) {
mMachine.requestState(DozeMachine.State.FINISH); mDozeLog.traceCarModeStarted();
mMachine.requestState(DozeMachine.State.DOZE_SUSPEND_TRIGGERS);
} else if (ACTION_EXIT_CAR_MODE.equals(action)) {
mDozeLog.traceCarModeEnded();
mMachine.requestState(mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT)
? DozeMachine.State.DOZE_AOD : DozeMachine.State.DOZE);
} }
} }
}; };

View File

@@ -16,6 +16,10 @@
package com.android.systemui.doze; package com.android.systemui.doze;
import static com.android.systemui.doze.DozeMachine.State.DOZE_SUSPEND_TRIGGERS;
import static com.android.systemui.doze.DozeMachine.State.FINISH;
import static com.android.systemui.doze.DozeMachine.State.UNINITIALIZED;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
@@ -437,14 +441,18 @@ public class DozeTriggers implements DozeMachine.Part {
@Override @Override
public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) { public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
if (oldState == DOZE_SUSPEND_TRIGGERS && (newState != FINISH
&& newState != UNINITIALIZED)) {
// Register callbacks that were unregistered when we switched to
// DOZE_SUSPEND_TRIGGERS state.
registerCallbacks();
}
switch (newState) { switch (newState) {
case INITIALIZED: case INITIALIZED:
mAodInterruptRunnable = null; mAodInterruptRunnable = null;
sWakeDisplaySensorState = true; sWakeDisplaySensorState = true;
mBroadcastReceiver.register(mBroadcastDispatcher); registerCallbacks();
mDockManager.addListener(mDockEventListener);
mDozeSensors.requestTemporaryDisable(); mDozeSensors.requestTemporaryDisable();
mDozeHost.addCallback(mHostCallback);
break; break;
case DOZE: case DOZE:
case DOZE_AOD: case DOZE_AOD:
@@ -472,21 +480,36 @@ public class DozeTriggers implements DozeMachine.Part {
case DOZE_PULSE_DONE: case DOZE_PULSE_DONE:
mDozeSensors.requestTemporaryDisable(); mDozeSensors.requestTemporaryDisable();
break; break;
case DOZE_SUSPEND_TRIGGERS:
case FINISH: case FINISH:
mBroadcastReceiver.unregister(mBroadcastDispatcher); stopListeningToAllTriggers();
mDozeHost.removeCallback(mHostCallback);
mDockManager.removeListener(mDockEventListener);
mDozeSensors.setListening(false, false);
mDozeSensors.setProxListening(false);
mWantSensors = false;
mWantProxSensor = false;
mWantTouchScreenSensors = false;
break; break;
default: default:
} }
mDozeSensors.setListening(mWantSensors, mWantTouchScreenSensors); mDozeSensors.setListening(mWantSensors, mWantTouchScreenSensors);
} }
private void registerCallbacks() {
mBroadcastReceiver.register(mBroadcastDispatcher);
mDockManager.addListener(mDockEventListener);
mDozeHost.addCallback(mHostCallback);
}
private void unregisterCallbacks() {
mBroadcastReceiver.unregister(mBroadcastDispatcher);
mDozeHost.removeCallback(mHostCallback);
mDockManager.removeListener(mDockEventListener);
}
private void stopListeningToAllTriggers() {
unregisterCallbacks();
mDozeSensors.setListening(false, false);
mDozeSensors.setProxListening(false);
mWantSensors = false;
mWantProxSensor = false;
mWantTouchScreenSensors = false;
}
@Override @Override
public void onScreenState(int state) { public void onScreenState(int state) {
mDozeSensors.onScreenState(state); mDozeSensors.onScreenState(state);

View File

@@ -139,6 +139,7 @@ public class DozeUi implements DozeMachine.Part {
break; break;
case DOZE: case DOZE:
case DOZE_AOD_PAUSED: case DOZE_AOD_PAUSED:
case DOZE_SUSPEND_TRIGGERS:
unscheduleTimeTick(); unscheduleTimeTick();
break; break;
case DOZE_REQUEST_PULSE: case DOZE_REQUEST_PULSE:

View File

@@ -21,7 +21,9 @@ import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD;
import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD_DOCKED; import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD_DOCKED;
import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSE_DONE; import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSE_DONE;
import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSING; import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSING;
import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSING_BRIGHT;
import static com.android.systemui.doze.DozeMachine.State.DOZE_REQUEST_PULSE; import static com.android.systemui.doze.DozeMachine.State.DOZE_REQUEST_PULSE;
import static com.android.systemui.doze.DozeMachine.State.DOZE_SUSPEND_TRIGGERS;
import static com.android.systemui.doze.DozeMachine.State.FINISH; import static com.android.systemui.doze.DozeMachine.State.FINISH;
import static com.android.systemui.doze.DozeMachine.State.INITIALIZED; import static com.android.systemui.doze.DozeMachine.State.INITIALIZED;
import static com.android.systemui.doze.DozeMachine.State.UNINITIALIZED; import static com.android.systemui.doze.DozeMachine.State.UNINITIALIZED;
@@ -39,6 +41,8 @@ import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.app.UiModeManager;
import android.content.res.Configuration;
import android.hardware.display.AmbientDisplayConfiguration; import android.hardware.display.AmbientDisplayConfiguration;
import android.testing.AndroidTestingRunner; import android.testing.AndroidTestingRunner;
import android.testing.UiThreadTest; import android.testing.UiThreadTest;
@@ -50,7 +54,6 @@ import com.android.systemui.SysuiTestCase;
import com.android.systemui.dock.DockManager; import com.android.systemui.dock.DockManager;
import com.android.systemui.keyguard.WakefulnessLifecycle; import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.policy.BatteryController;
import com.android.systemui.util.wakelock.WakeLockFake; import com.android.systemui.util.wakelock.WakeLockFake;
import org.junit.Before; import org.junit.Before;
@@ -70,9 +73,12 @@ public class DozeMachineTest extends SysuiTestCase {
private WakefulnessLifecycle mWakefulnessLifecycle; private WakefulnessLifecycle mWakefulnessLifecycle;
@Mock @Mock
private DozeLog mDozeLog; private DozeLog mDozeLog;
@Mock private DockManager mDockManager; @Mock
private DockManager mDockManager;
@Mock @Mock
private DozeHost mHost; private DozeHost mHost;
@Mock
private UiModeManager mUiModeManager;
private DozeServiceFake mServiceFake; private DozeServiceFake mServiceFake;
private WakeLockFake mWakeLockFake; private WakeLockFake mWakeLockFake;
private AmbientDisplayConfiguration mConfigMock; private AmbientDisplayConfiguration mConfigMock;
@@ -89,7 +95,7 @@ public class DozeMachineTest extends SysuiTestCase {
when(mDockManager.isHidden()).thenReturn(false); when(mDockManager.isHidden()).thenReturn(false);
mMachine = new DozeMachine(mServiceFake, mConfigMock, mWakeLockFake, mMachine = new DozeMachine(mServiceFake, mConfigMock, mWakeLockFake,
mWakefulnessLifecycle, mock(BatteryController.class), mDozeLog, mDockManager, mWakefulnessLifecycle, mUiModeManager, mDozeLog, mDockManager,
mHost, new DozeMachine.Part[]{mPartMock}); mHost, new DozeMachine.Part[]{mPartMock});
} }
@@ -462,4 +468,64 @@ public class DozeMachineTest extends SysuiTestCase {
assertEquals(Display.STATE_ON, DOZE_REQUEST_PULSE.screenState(dozeParameters)); assertEquals(Display.STATE_ON, DOZE_REQUEST_PULSE.screenState(dozeParameters));
} }
@Test
public void testTransitionToInitialized_carModeIsEnabled() {
when(mUiModeManager.getCurrentModeType()).thenReturn(Configuration.UI_MODE_TYPE_CAR);
mMachine.requestState(INITIALIZED);
verify(mPartMock).transitionTo(UNINITIALIZED, INITIALIZED);
verify(mPartMock).transitionTo(INITIALIZED, DOZE_SUSPEND_TRIGGERS);
assertEquals(DOZE_SUSPEND_TRIGGERS, mMachine.getState());
}
@Test
public void testTransitionToFinish_carModeIsEnabled() {
when(mUiModeManager.getCurrentModeType()).thenReturn(Configuration.UI_MODE_TYPE_CAR);
mMachine.requestState(INITIALIZED);
mMachine.requestState(FINISH);
assertEquals(FINISH, mMachine.getState());
}
@Test
public void testDozeToDozeSuspendTriggers_carModeIsEnabled() {
when(mUiModeManager.getCurrentModeType()).thenReturn(Configuration.UI_MODE_TYPE_CAR);
mMachine.requestState(INITIALIZED);
mMachine.requestState(DOZE);
assertEquals(DOZE_SUSPEND_TRIGGERS, mMachine.getState());
}
@Test
public void testDozeAoDToDozeSuspendTriggers_carModeIsEnabled() {
when(mUiModeManager.getCurrentModeType()).thenReturn(Configuration.UI_MODE_TYPE_CAR);
mMachine.requestState(INITIALIZED);
mMachine.requestState(DOZE_AOD);
assertEquals(DOZE_SUSPEND_TRIGGERS, mMachine.getState());
}
@Test
public void testDozePulsingBrightDozeSuspendTriggers_carModeIsEnabled() {
when(mUiModeManager.getCurrentModeType()).thenReturn(Configuration.UI_MODE_TYPE_CAR);
mMachine.requestState(INITIALIZED);
mMachine.requestState(DOZE_PULSING_BRIGHT);
assertEquals(DOZE_SUSPEND_TRIGGERS, mMachine.getState());
}
@Test
public void testDozeAodDockedDozeSuspendTriggers_carModeIsEnabled() {
when(mUiModeManager.getCurrentModeType()).thenReturn(Configuration.UI_MODE_TYPE_CAR);
mMachine.requestState(INITIALIZED);
mMachine.requestState(DOZE_AOD_DOCKED);
assertEquals(DOZE_SUSPEND_TRIGGERS, mMachine.getState());
}
@Test
public void testDozeSuppressTriggers_screenState() {
assertEquals(Display.STATE_OFF, DOZE_SUSPEND_TRIGGERS.screenState(null));
}
} }

View File

@@ -24,6 +24,7 @@ import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD_PAUSING;
import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSE_DONE; import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSE_DONE;
import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSING; import static com.android.systemui.doze.DozeMachine.State.DOZE_PULSING;
import static com.android.systemui.doze.DozeMachine.State.DOZE_REQUEST_PULSE; import static com.android.systemui.doze.DozeMachine.State.DOZE_REQUEST_PULSE;
import static com.android.systemui.doze.DozeMachine.State.DOZE_SUSPEND_TRIGGERS;
import static com.android.systemui.doze.DozeMachine.State.FINISH; import static com.android.systemui.doze.DozeMachine.State.FINISH;
import static com.android.systemui.doze.DozeMachine.State.INITIALIZED; import static com.android.systemui.doze.DozeMachine.State.INITIALIZED;
import static com.android.systemui.doze.DozeMachine.State.UNINITIALIZED; import static com.android.systemui.doze.DozeMachine.State.UNINITIALIZED;
@@ -181,6 +182,21 @@ public class DozeScreenBrightnessTest extends SysuiTestCase {
assertEquals(DEFAULT_BRIGHTNESS, mServiceFake.screenBrightness); assertEquals(DEFAULT_BRIGHTNESS, mServiceFake.screenBrightness);
} }
@Test
public void dozeSuspendTriggers_doesNotUseLightSensor() {
// GIVEN the device is DOZE and the display state changes to ON
mScreen.transitionTo(UNINITIALIZED, INITIALIZED);
mScreen.transitionTo(INITIALIZED, DOZE_SUSPEND_TRIGGERS);
waitForSensorManager();
// WHEN new sensor event sent
mSensor.sendSensorEvent(3);
// THEN brightness is NOT changed, it's set to the default brightness
assertNotSame(3, mServiceFake.screenBrightness);
assertEquals(DEFAULT_BRIGHTNESS, mServiceFake.screenBrightness);
}
@Test @Test
public void aod_usesLightSensor() { public void aod_usesLightSensor() {
// GIVEN the device is DOZE_AOD and the display state changes to ON // GIVEN the device is DOZE_AOD and the display state changes to ON

View File

@@ -16,19 +16,26 @@
package com.android.systemui.doze; package com.android.systemui.doze;
import static android.app.UiModeManager.ACTION_ENTER_CAR_MODE;
import static android.app.UiModeManager.ACTION_EXIT_CAR_MODE;
import static com.android.systemui.doze.DozeMachine.State.DOZE; import static com.android.systemui.doze.DozeMachine.State.DOZE;
import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD; import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD;
import static com.android.systemui.doze.DozeMachine.State.DOZE_SUSPEND_TRIGGERS;
import static com.android.systemui.doze.DozeMachine.State.FINISH; import static com.android.systemui.doze.DozeMachine.State.FINISH;
import static com.android.systemui.doze.DozeMachine.State.INITIALIZED; import static com.android.systemui.doze.DozeMachine.State.INITIALIZED;
import static com.android.systemui.doze.DozeMachine.State.UNINITIALIZED; import static com.android.systemui.doze.DozeMachine.State.UNINITIALIZED;
import static org.mockito.Matchers.anyObject; import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.anyInt; import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when; import static org.mockito.Mockito.when;
import android.app.UiModeManager; import android.app.UiModeManager;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration; import android.content.res.Configuration;
import android.hardware.display.AmbientDisplayConfiguration; import android.hardware.display.AmbientDisplayConfiguration;
import android.testing.AndroidTestingRunner; import android.testing.AndroidTestingRunner;
@@ -77,7 +84,10 @@ public class DozeSuppressorTest extends SysuiTestCase {
@Captor @Captor
private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor; private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor;
@Captor
private ArgumentCaptor<IntentFilter> mIntentFilterCaptor;
private BroadcastReceiver mBroadcastReceiver; private BroadcastReceiver mBroadcastReceiver;
private IntentFilter mIntentFilter;
@Captor @Captor
private ArgumentCaptor<DozeHost.Callback> mDozeHostCaptor; private ArgumentCaptor<DozeHost.Callback> mDozeHostCaptor;
@@ -122,15 +132,59 @@ public class DozeSuppressorTest extends SysuiTestCase {
} }
@Test @Test
public void testEndDoze_carMode() { public void testSuspendTriggersDoze_carMode() {
// GIVEN car mode // GIVEN car mode
when(mUiModeManager.getCurrentModeType()).thenReturn(Configuration.UI_MODE_TYPE_CAR); when(mUiModeManager.getCurrentModeType()).thenReturn(Configuration.UI_MODE_TYPE_CAR);
// WHEN dozing begins // WHEN dozing begins
mDozeSuppressor.transitionTo(UNINITIALIZED, INITIALIZED); mDozeSuppressor.transitionTo(UNINITIALIZED, INITIALIZED);
// THEN doze immediately ends // THEN doze continues with all doze triggers disabled.
verify(mDozeMachine).requestState(FINISH); verify(mDozeMachine).requestState(DOZE_SUSPEND_TRIGGERS);
}
@Test
public void testSuspendTriggersDoze_enterCarMode() {
// GIVEN currently dozing
mDozeSuppressor.transitionTo(UNINITIALIZED, INITIALIZED);
captureBroadcastReceiver();
mDozeSuppressor.transitionTo(INITIALIZED, DOZE);
// WHEN car mode entered
mBroadcastReceiver.onReceive(null, new Intent(ACTION_ENTER_CAR_MODE));
// THEN doze continues with all doze triggers disabled.
verify(mDozeMachine).requestState(DOZE_SUSPEND_TRIGGERS);
}
@Test
public void testDozeResume_exitCarMode() {
// GIVEN currently suspended, with AOD not enabled
when(mConfig.alwaysOnEnabled(anyInt())).thenReturn(false);
mDozeSuppressor.transitionTo(UNINITIALIZED, INITIALIZED);
captureBroadcastReceiver();
mDozeSuppressor.transitionTo(INITIALIZED, DOZE_SUSPEND_TRIGGERS);
// WHEN exiting car mode
mBroadcastReceiver.onReceive(null, new Intent(ACTION_EXIT_CAR_MODE));
// THEN doze is resumed
verify(mDozeMachine).requestState(DOZE);
}
@Test
public void testDozeAoDResume_exitCarMode() {
// GIVEN currently suspended, with AOD not enabled
when(mConfig.alwaysOnEnabled(anyInt())).thenReturn(true);
mDozeSuppressor.transitionTo(UNINITIALIZED, INITIALIZED);
captureBroadcastReceiver();
mDozeSuppressor.transitionTo(INITIALIZED, DOZE_SUSPEND_TRIGGERS);
// WHEN exiting car mode
mBroadcastReceiver.onReceive(null, new Intent(ACTION_EXIT_CAR_MODE));
// THEN doze AOD is resumed
verify(mDozeMachine).requestState(DOZE_AOD);
} }
@Test @Test
@@ -225,7 +279,11 @@ public class DozeSuppressorTest extends SysuiTestCase {
private void captureBroadcastReceiver() { private void captureBroadcastReceiver() {
verify(mBroadcastDispatcher).registerReceiver(mBroadcastReceiverCaptor.capture(), verify(mBroadcastDispatcher).registerReceiver(mBroadcastReceiverCaptor.capture(),
anyObject()); mIntentFilterCaptor.capture());
mBroadcastReceiver = mBroadcastReceiverCaptor.getValue(); mBroadcastReceiver = mBroadcastReceiverCaptor.getValue();
mIntentFilter = mIntentFilterCaptor.getValue();
assertEquals(2, mIntentFilter.countActions());
org.hamcrest.MatcherAssert.assertThat(() -> mIntentFilter.actionsIterator(),
containsInAnyOrder(ACTION_ENTER_CAR_MODE, ACTION_EXIT_CAR_MODE));
} }
} }

View File

@@ -17,6 +17,8 @@
package com.android.systemui.doze; package com.android.systemui.doze;
import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD; import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD;
import static com.android.systemui.doze.DozeMachine.State.INITIALIZED;
import static com.android.systemui.doze.DozeMachine.State.UNINITIALIZED;
import static org.mockito.ArgumentMatchers.any; import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyFloat; import static org.mockito.ArgumentMatchers.anyFloat;
@@ -133,7 +135,7 @@ public class DozeTriggersTest extends SysuiTestCase {
ArgumentCaptor<DozeHost.Callback> captor = ArgumentCaptor.forClass(DozeHost.Callback.class); ArgumentCaptor<DozeHost.Callback> captor = ArgumentCaptor.forClass(DozeHost.Callback.class);
doAnswer(invocation -> null).when(mHost).addCallback(captor.capture()); doAnswer(invocation -> null).when(mHost).addCallback(captor.capture());
mTriggers.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED); mTriggers.transitionTo(UNINITIALIZED, DozeMachine.State.INITIALIZED);
mTriggers.transitionTo(DozeMachine.State.INITIALIZED, DozeMachine.State.DOZE); mTriggers.transitionTo(DozeMachine.State.INITIALIZED, DozeMachine.State.DOZE);
clearInvocations(mMachine); clearInvocations(mMachine);
@@ -191,9 +193,22 @@ public class DozeTriggersTest extends SysuiTestCase {
verify(mSensors).cancelTriggerSensor(any(), eq(mTapSensor)); verify(mSensors).cancelTriggerSensor(any(), eq(mTapSensor));
} }
@Test
public void transitionToDozeSuspendTriggers_disablesAllCallbacks() {
mTriggers.transitionTo(UNINITIALIZED, INITIALIZED);
when(mMachine.getState()).thenReturn(DozeMachine.State.DOZE_SUSPEND_TRIGGERS);
mTriggers.transitionTo(DozeMachine.State.INITIALIZED,
DozeMachine.State.DOZE_SUSPEND_TRIGGERS);
verify(mDockManager).removeListener(any());
verify(mBroadcastDispatcher).unregisterReceiver(any());
verify(mHost).removeCallback(any());
}
@Test @Test
public void testDockEventListener_registerAndUnregister() { public void testDockEventListener_registerAndUnregister() {
mTriggers.transitionTo(DozeMachine.State.UNINITIALIZED, DozeMachine.State.INITIALIZED); mTriggers.transitionTo(UNINITIALIZED, DozeMachine.State.INITIALIZED);
verify(mDockManager).addListener(any()); verify(mDockManager).addListener(any());
mTriggers.transitionTo(DozeMachine.State.DOZE, DozeMachine.State.FINISH); mTriggers.transitionTo(DozeMachine.State.DOZE, DozeMachine.State.FINISH);