Merge "Uses Configuration.uiMode in DozeMachine to determine if car mode is active" into tm-qpr-dev

This commit is contained in:
Chandru S
2022-10-20 09:40:51 +00:00
committed by Android (Google) Code Review
5 changed files with 213 additions and 134 deletions

View File

@@ -20,7 +20,6 @@ import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_AWA
import static com.android.systemui.keyguard.WakefulnessLifecycle.WAKEFULNESS_WAKING;
import android.annotation.MainThread;
import android.app.UiModeManager;
import android.content.res.Configuration;
import android.hardware.display.AmbientDisplayConfiguration;
import android.os.Trace;
@@ -145,10 +144,9 @@ public class DozeMachine {
private final Service mDozeService;
private final WakeLock mWakeLock;
private final AmbientDisplayConfiguration mConfig;
private final AmbientDisplayConfiguration mAmbientDisplayConfig;
private final WakefulnessLifecycle mWakefulnessLifecycle;
private final DozeHost mDozeHost;
private final UiModeManager mUiModeManager;
private final DockManager mDockManager;
private final Part[] mParts;
@@ -156,18 +154,18 @@ public class DozeMachine {
private State mState = State.UNINITIALIZED;
private int mPulseReason;
private boolean mWakeLockHeldForCurrentState = false;
private int mUiModeType = Configuration.UI_MODE_TYPE_NORMAL;
@Inject
public DozeMachine(@WrappedService Service service, AmbientDisplayConfiguration config,
public DozeMachine(@WrappedService Service service,
AmbientDisplayConfiguration ambientDisplayConfig,
WakeLock wakeLock, WakefulnessLifecycle wakefulnessLifecycle,
UiModeManager uiModeManager,
DozeLog dozeLog, DockManager dockManager,
DozeHost dozeHost, Part[] parts) {
mDozeService = service;
mConfig = config;
mAmbientDisplayConfig = ambientDisplayConfig;
mWakefulnessLifecycle = wakefulnessLifecycle;
mWakeLock = wakeLock;
mUiModeManager = uiModeManager;
mDozeLog = dozeLog;
mDockManager = dockManager;
mDozeHost = dozeHost;
@@ -186,6 +184,18 @@ public class DozeMachine {
}
}
/**
* Notifies the {@link DozeMachine} that {@link Configuration} has changed.
*/
public void onConfigurationChanged(Configuration newConfiguration) {
int newUiModeType = newConfiguration.uiMode & Configuration.UI_MODE_TYPE_MASK;
if (mUiModeType == newUiModeType) return;
mUiModeType = newUiModeType;
for (Part part : mParts) {
part.onUiModeTypeChanged(mUiModeType);
}
}
/**
* Requests transitioning to {@code requestedState}.
*
@@ -211,6 +221,14 @@ public class DozeMachine {
requestState(State.DOZE_REQUEST_PULSE, pulseReason);
}
/**
* @return true if {@link DozeMachine} is currently in either {@link State#UNINITIALIZED}
* or {@link State#FINISH}
*/
public boolean isUninitializedOrFinished() {
return mState == State.UNINITIALIZED || mState == State.FINISH;
}
void onScreenState(int state) {
mDozeLog.traceDisplayState(state);
for (Part part : mParts) {
@@ -360,7 +378,7 @@ public class DozeMachine {
if (mState == State.FINISH) {
return State.FINISH;
}
if (mUiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR
if (mUiModeType == 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();
@@ -411,7 +429,7 @@ public class DozeMachine {
nextState = State.FINISH;
} else if (mDockManager.isDocked()) {
nextState = mDockManager.isHidden() ? State.DOZE : State.DOZE_AOD_DOCKED;
} else if (mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT)) {
} else if (mAmbientDisplayConfig.alwaysOnEnabled(UserHandle.USER_CURRENT)) {
nextState = State.DOZE_AOD;
} else {
nextState = State.DOZE;
@@ -427,6 +445,7 @@ public class DozeMachine {
/** Dumps the current state */
public void dump(PrintWriter pw) {
pw.print(" state="); pw.println(mState);
pw.print(" mUiModeType="); pw.println(mUiModeType);
pw.print(" wakeLockHeldForCurrentState="); pw.println(mWakeLockHeldForCurrentState);
pw.print(" wakeLock="); pw.println(mWakeLock);
pw.println("Parts:");
@@ -459,6 +478,19 @@ public class DozeMachine {
/** Sets the {@link DozeMachine} when this Part is associated with one. */
default void setDozeMachine(DozeMachine dozeMachine) {}
/**
* Notifies the Part about a change in {@link Configuration#uiMode}.
*
* @param newUiModeType {@link Configuration#UI_MODE_TYPE_NORMAL},
* {@link Configuration#UI_MODE_TYPE_DESK},
* {@link Configuration#UI_MODE_TYPE_CAR},
* {@link Configuration#UI_MODE_TYPE_TELEVISION},
* {@link Configuration#UI_MODE_TYPE_APPLIANCE},
* {@link Configuration#UI_MODE_TYPE_WATCH},
* or {@link Configuration#UI_MODE_TYPE_VR_HEADSET}
*/
default void onUiModeTypeChanged(int newUiModeType) {}
}
/** A wrapper interface for {@link android.service.dreams.DreamService} */

View File

@@ -17,6 +17,7 @@
package com.android.systemui.doze;
import android.content.Context;
import android.content.res.Configuration;
import android.os.PowerManager;
import android.os.SystemClock;
import android.service.dreams.DreamService;
@@ -59,6 +60,7 @@ public class DozeService extends DreamService
mPluginManager.addPluginListener(this, DozeServicePlugin.class, false /* allowMultiple */);
DozeComponent dozeComponent = mDozeComponentBuilder.build(this);
mDozeMachine = dozeComponent.getDozeMachine();
mDozeMachine.onConfigurationChanged(getResources().getConfiguration());
}
@Override
@@ -126,6 +128,12 @@ public class DozeService extends DreamService
}
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mDozeMachine.onConfigurationChanged(newConfig);
}
@Override
public void onRequestHideDoze() {
if (mDozeMachine != null) {

View File

@@ -16,21 +16,13 @@
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 android.content.res.Configuration.UI_MODE_TYPE_CAR;
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;
@@ -43,7 +35,9 @@ import dagger.Lazy;
/**
* Handles suppressing doze on:
* 1. INITIALIZED, don't allow dozing at all when:
* - in CAR_MODE
* - in CAR_MODE, in this scenario the device is asleep and won't listen for any triggers
* to wake up. In this state, no UI shows. Unlike other conditions, this suppression is only
* temporary and stops when the device exits CAR_MODE
* - device is NOT provisioned
* - there's a pending authentication
* 2. PowerSaveMode active
@@ -57,34 +51,46 @@ import dagger.Lazy;
*/
@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;
private boolean mIsCarModeEnabled = false;
@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 onUiModeTypeChanged(int newUiModeType) {
boolean isCarModeEnabled = newUiModeType == UI_MODE_TYPE_CAR;
if (mIsCarModeEnabled == isCarModeEnabled) {
return;
}
mIsCarModeEnabled = isCarModeEnabled;
// Do not handle the event if doze machine is not initialized yet.
// It will be handled upon initialization.
if (mMachine.isUninitializedOrFinished()) {
return;
}
if (mIsCarModeEnabled) {
handleCarModeStarted();
} else {
handleCarModeExited();
}
}
@Override
public void setDozeMachine(DozeMachine dozeMachine) {
mMachine = dozeMachine;
@@ -94,7 +100,6 @@ public class DozeSuppressor implements DozeMachine.Part {
public void transitionTo(DozeMachine.State oldState, DozeMachine.State newState) {
switch (newState) {
case INITIALIZED:
registerBroadcastReceiver();
mDozeHost.addCallback(mHostCallback);
checkShouldImmediatelyEndDoze();
checkShouldImmediatelySuspendDoze();
@@ -108,14 +113,12 @@ public class DozeSuppressor implements DozeMachine.Part {
@Override
public void destroy() {
unregisterBroadcastReceiver();
mDozeHost.removeCallback(mHostCallback);
}
private void checkShouldImmediatelySuspendDoze() {
if (mUiModeManager.getCurrentModeType() == Configuration.UI_MODE_TYPE_CAR) {
mDozeLog.traceCarModeStarted();
mMachine.requestState(DozeMachine.State.DOZE_SUSPEND_TRIGGERS);
if (mIsCarModeEnabled) {
handleCarModeStarted();
}
}
@@ -135,7 +138,7 @@ public class DozeSuppressor implements DozeMachine.Part {
@Override
public void dump(PrintWriter pw) {
pw.println(" uiMode=" + mUiModeManager.getCurrentModeType());
pw.println(" isCarModeEnabled=" + mIsCarModeEnabled);
pw.println(" hasPendingAuth="
+ mBiometricUnlockControllerLazy.get().hasPendingAuthentication());
pw.println(" isProvisioned=" + mDozeHost.isProvisioned());
@@ -143,40 +146,18 @@ public class DozeSuppressor implements DozeMachine.Part {
pw.println(" aodPowerSaveActive=" + mDozeHost.isPowerSaveActive());
}
private void registerBroadcastReceiver() {
if (mBroadcastReceiverRegistered) {
return;
}
IntentFilter filter = new IntentFilter(ACTION_ENTER_CAR_MODE);
filter.addAction(ACTION_EXIT_CAR_MODE);
mBroadcastDispatcher.registerReceiver(mBroadcastReceiver, filter);
mBroadcastReceiverRegistered = true;
private void handleCarModeExited() {
mDozeLog.traceCarModeEnded();
mMachine.requestState(mConfig.alwaysOnEnabled(UserHandle.USER_CURRENT)
? DozeMachine.State.DOZE_AOD : DozeMachine.State.DOZE);
}
private void unregisterBroadcastReceiver() {
if (!mBroadcastReceiverRegistered) {
return;
}
mBroadcastDispatcher.unregisterReceiver(mBroadcastReceiver);
mBroadcastReceiverRegistered = false;
private void handleCarModeStarted() {
mDozeLog.traceCarModeStarted();
mMachine.requestState(DozeMachine.State.DOZE_SUSPEND_TRIGGERS);
}
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_ENTER_CAR_MODE.equals(action)) {
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);
}
}
};
private DozeHost.Callback mHostCallback = new DozeHost.Callback() {
private final DozeHost.Callback mHostCallback = new DozeHost.Callback() {
@Override
public void onPowerSaveChanged(boolean active) {
// handles suppression changes, while DozeMachine#transitionPolicy handles gating

View File

@@ -16,6 +16,9 @@
package com.android.systemui.doze;
import static android.content.res.Configuration.UI_MODE_NIGHT_YES;
import static android.content.res.Configuration.UI_MODE_TYPE_CAR;
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_DOCKED;
@@ -38,16 +41,17 @@ import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.UiModeManager;
import android.content.res.Configuration;
import android.hardware.display.AmbientDisplayConfiguration;
import android.testing.AndroidTestingRunner;
import android.testing.UiThreadTest;
import android.view.Display;
import androidx.annotation.NonNull;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
@@ -78,25 +82,30 @@ public class DozeMachineTest extends SysuiTestCase {
@Mock
private DozeHost mHost;
@Mock
private UiModeManager mUiModeManager;
private DozeMachine.Part mPartMock;
@Mock
private DozeMachine.Part mAnotherPartMock;
private DozeServiceFake mServiceFake;
private WakeLockFake mWakeLockFake;
private AmbientDisplayConfiguration mConfigMock;
private DozeMachine.Part mPartMock;
private AmbientDisplayConfiguration mAmbientDisplayConfigMock;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
mServiceFake = new DozeServiceFake();
mWakeLockFake = new WakeLockFake();
mConfigMock = mock(AmbientDisplayConfiguration.class);
mPartMock = mock(DozeMachine.Part.class);
mAmbientDisplayConfigMock = mock(AmbientDisplayConfiguration.class);
when(mDockManager.isDocked()).thenReturn(false);
when(mDockManager.isHidden()).thenReturn(false);
mMachine = new DozeMachine(mServiceFake, mConfigMock, mWakeLockFake,
mWakefulnessLifecycle, mUiModeManager, mDozeLog, mDockManager,
mHost, new DozeMachine.Part[]{mPartMock});
mMachine = new DozeMachine(mServiceFake,
mAmbientDisplayConfigMock,
mWakeLockFake,
mWakefulnessLifecycle,
mDozeLog,
mDockManager,
mHost,
new DozeMachine.Part[]{mPartMock, mAnotherPartMock});
}
@Test
@@ -108,7 +117,7 @@ public class DozeMachineTest extends SysuiTestCase {
@Test
public void testInitialize_goesToDoze() {
when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(false);
when(mAmbientDisplayConfigMock.alwaysOnEnabled(anyInt())).thenReturn(false);
mMachine.requestState(INITIALIZED);
@@ -118,7 +127,7 @@ public class DozeMachineTest extends SysuiTestCase {
@Test
public void testInitialize_goesToAod() {
when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
when(mAmbientDisplayConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
mMachine.requestState(INITIALIZED);
@@ -138,7 +147,7 @@ public class DozeMachineTest extends SysuiTestCase {
@Test
public void testInitialize_afterDockPaused_goesToDoze() {
when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
when(mAmbientDisplayConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
when(mDockManager.isDocked()).thenReturn(true);
when(mDockManager.isHidden()).thenReturn(true);
@@ -151,7 +160,7 @@ public class DozeMachineTest extends SysuiTestCase {
@Test
public void testInitialize_alwaysOnSuppressed_alwaysOnDisabled_goesToDoze() {
when(mHost.isAlwaysOnSuppressed()).thenReturn(true);
when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(false);
when(mAmbientDisplayConfigMock.alwaysOnEnabled(anyInt())).thenReturn(false);
mMachine.requestState(INITIALIZED);
@@ -162,7 +171,7 @@ public class DozeMachineTest extends SysuiTestCase {
@Test
public void testInitialize_alwaysOnSuppressed_alwaysOnEnabled_goesToDoze() {
when(mHost.isAlwaysOnSuppressed()).thenReturn(true);
when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
when(mAmbientDisplayConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
mMachine.requestState(INITIALIZED);
@@ -184,7 +193,7 @@ public class DozeMachineTest extends SysuiTestCase {
@Test
public void testInitialize_alwaysOnSuppressed_alwaysOnDisabled_afterDockPaused_goesToDoze() {
when(mHost.isAlwaysOnSuppressed()).thenReturn(true);
when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(false);
when(mAmbientDisplayConfigMock.alwaysOnEnabled(anyInt())).thenReturn(false);
when(mDockManager.isDocked()).thenReturn(true);
when(mDockManager.isHidden()).thenReturn(true);
@@ -197,7 +206,7 @@ public class DozeMachineTest extends SysuiTestCase {
@Test
public void testInitialize_alwaysOnSuppressed_alwaysOnEnabled_afterDockPaused_goesToDoze() {
when(mHost.isAlwaysOnSuppressed()).thenReturn(true);
when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
when(mAmbientDisplayConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
when(mDockManager.isDocked()).thenReturn(true);
when(mDockManager.isHidden()).thenReturn(true);
@@ -209,7 +218,7 @@ public class DozeMachineTest extends SysuiTestCase {
@Test
public void testPulseDone_goesToDoze() {
when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(false);
when(mAmbientDisplayConfigMock.alwaysOnEnabled(anyInt())).thenReturn(false);
mMachine.requestState(INITIALIZED);
mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
mMachine.requestState(DOZE_PULSING);
@@ -222,7 +231,7 @@ public class DozeMachineTest extends SysuiTestCase {
@Test
public void testPulseDone_goesToAoD() {
when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
when(mAmbientDisplayConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
mMachine.requestState(INITIALIZED);
mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
mMachine.requestState(DOZE_PULSING);
@@ -236,7 +245,7 @@ public class DozeMachineTest extends SysuiTestCase {
@Test
public void testPulseDone_alwaysOnSuppressed_goesToSuppressed() {
when(mHost.isAlwaysOnSuppressed()).thenReturn(true);
when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
when(mAmbientDisplayConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
mMachine.requestState(INITIALIZED);
mMachine.requestPulse(DozeLog.PULSE_REASON_NOTIFICATION);
mMachine.requestState(DOZE_PULSING);
@@ -287,7 +296,7 @@ public class DozeMachineTest extends SysuiTestCase {
@Test
public void testPulseDone_afterDockPaused_goesToDoze() {
when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
when(mAmbientDisplayConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
when(mDockManager.isDocked()).thenReturn(true);
when(mDockManager.isHidden()).thenReturn(true);
mMachine.requestState(INITIALIZED);
@@ -303,7 +312,7 @@ public class DozeMachineTest extends SysuiTestCase {
@Test
public void testPulseDone_alwaysOnSuppressed_afterDockPaused_goesToDoze() {
when(mHost.isAlwaysOnSuppressed()).thenReturn(true);
when(mConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
when(mAmbientDisplayConfigMock.alwaysOnEnabled(anyInt())).thenReturn(true);
when(mDockManager.isDocked()).thenReturn(true);
when(mDockManager.isHidden()).thenReturn(true);
mMachine.requestState(INITIALIZED);
@@ -471,7 +480,9 @@ public class DozeMachineTest extends SysuiTestCase {
@Test
public void testTransitionToInitialized_carModeIsEnabled() {
when(mUiModeManager.getCurrentModeType()).thenReturn(Configuration.UI_MODE_TYPE_CAR);
Configuration configuration = configWithCarNightUiMode();
mMachine.onConfigurationChanged(configuration);
mMachine.requestState(INITIALIZED);
verify(mPartMock).transitionTo(UNINITIALIZED, INITIALIZED);
@@ -481,7 +492,9 @@ public class DozeMachineTest extends SysuiTestCase {
@Test
public void testTransitionToFinish_carModeIsEnabled() {
when(mUiModeManager.getCurrentModeType()).thenReturn(Configuration.UI_MODE_TYPE_CAR);
Configuration configuration = configWithCarNightUiMode();
mMachine.onConfigurationChanged(configuration);
mMachine.requestState(INITIALIZED);
mMachine.requestState(FINISH);
@@ -490,7 +503,9 @@ public class DozeMachineTest extends SysuiTestCase {
@Test
public void testDozeToDozeSuspendTriggers_carModeIsEnabled() {
when(mUiModeManager.getCurrentModeType()).thenReturn(Configuration.UI_MODE_TYPE_CAR);
Configuration configuration = configWithCarNightUiMode();
mMachine.onConfigurationChanged(configuration);
mMachine.requestState(INITIALIZED);
mMachine.requestState(DOZE);
@@ -499,7 +514,9 @@ public class DozeMachineTest extends SysuiTestCase {
@Test
public void testDozeAoDToDozeSuspendTriggers_carModeIsEnabled() {
when(mUiModeManager.getCurrentModeType()).thenReturn(Configuration.UI_MODE_TYPE_CAR);
Configuration configuration = configWithCarNightUiMode();
mMachine.onConfigurationChanged(configuration);
mMachine.requestState(INITIALIZED);
mMachine.requestState(DOZE_AOD);
@@ -508,7 +525,9 @@ public class DozeMachineTest extends SysuiTestCase {
@Test
public void testDozePulsingBrightDozeSuspendTriggers_carModeIsEnabled() {
when(mUiModeManager.getCurrentModeType()).thenReturn(Configuration.UI_MODE_TYPE_CAR);
Configuration configuration = configWithCarNightUiMode();
mMachine.onConfigurationChanged(configuration);
mMachine.requestState(INITIALIZED);
mMachine.requestState(DOZE_PULSING_BRIGHT);
@@ -517,15 +536,45 @@ public class DozeMachineTest extends SysuiTestCase {
@Test
public void testDozeAodDockedDozeSuspendTriggers_carModeIsEnabled() {
when(mUiModeManager.getCurrentModeType()).thenReturn(Configuration.UI_MODE_TYPE_CAR);
Configuration configuration = configWithCarNightUiMode();
mMachine.onConfigurationChanged(configuration);
mMachine.requestState(INITIALIZED);
mMachine.requestState(DOZE_AOD_DOCKED);
assertEquals(DOZE_SUSPEND_TRIGGERS, mMachine.getState());
}
@Test
public void testOnConfigurationChanged_propagatesUiModeTypeToParts() {
Configuration newConfig = configWithCarNightUiMode();
mMachine.onConfigurationChanged(newConfig);
verify(mPartMock).onUiModeTypeChanged(UI_MODE_TYPE_CAR);
verify(mAnotherPartMock).onUiModeTypeChanged(UI_MODE_TYPE_CAR);
}
@Test
public void testOnConfigurationChanged_propagatesOnlyUiModeChangesToParts() {
Configuration newConfig = configWithCarNightUiMode();
mMachine.onConfigurationChanged(newConfig);
mMachine.onConfigurationChanged(newConfig);
verify(mPartMock, times(1)).onUiModeTypeChanged(UI_MODE_TYPE_CAR);
verify(mAnotherPartMock, times(1)).onUiModeTypeChanged(UI_MODE_TYPE_CAR);
}
@Test
public void testDozeSuppressTriggers_screenState() {
assertEquals(Display.STATE_OFF, DOZE_SUSPEND_TRIGGERS.screenState(null));
}
@NonNull
private Configuration configWithCarNightUiMode() {
Configuration configuration = Configuration.EMPTY;
configuration.uiMode = UI_MODE_TYPE_CAR | UI_MODE_NIGHT_YES;
return configuration;
}
}

View File

@@ -10,14 +10,14 @@
* 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 andatest
* 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 static android.app.UiModeManager.ACTION_EXIT_CAR_MODE;
import static android.content.res.Configuration.UI_MODE_TYPE_CAR;
import static android.content.res.Configuration.UI_MODE_TYPE_NORMAL;
import static com.android.systemui.doze.DozeMachine.State.DOZE;
import static com.android.systemui.doze.DozeMachine.State.DOZE_AOD;
@@ -26,17 +26,16 @@ 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.UNINITIALIZED;
import static org.hamcrest.Matchers.containsInAnyOrder;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.app.UiModeManager;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.hardware.display.AmbientDisplayConfiguration;
import android.testing.AndroidTestingRunner;
import android.testing.UiThreadTest;
@@ -44,13 +43,13 @@ import android.testing.UiThreadTest;
import androidx.test.filters.SmallTest;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.statusbar.phone.BiometricUnlockController;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.AdditionalMatchers;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
@@ -71,10 +70,6 @@ public class DozeSuppressorTest extends SysuiTestCase {
@Mock
private AmbientDisplayConfiguration mConfig;
@Mock
private BroadcastDispatcher mBroadcastDispatcher;
@Mock
private UiModeManager mUiModeManager;
@Mock
private Lazy<BiometricUnlockController> mBiometricUnlockControllerLazy;
@Mock
private BiometricUnlockController mBiometricUnlockController;
@@ -82,13 +77,6 @@ public class DozeSuppressorTest extends SysuiTestCase {
@Mock
private DozeMachine mDozeMachine;
@Captor
private ArgumentCaptor<BroadcastReceiver> mBroadcastReceiverCaptor;
@Captor
private ArgumentCaptor<IntentFilter> mIntentFilterCaptor;
private BroadcastReceiver mBroadcastReceiver;
private IntentFilter mIntentFilter;
@Captor
private ArgumentCaptor<DozeHost.Callback> mDozeHostCaptor;
private DozeHost.Callback mDozeHostCallback;
@@ -106,8 +94,6 @@ public class DozeSuppressorTest extends SysuiTestCase {
mDozeHost,
mConfig,
mDozeLog,
mBroadcastDispatcher,
mUiModeManager,
mBiometricUnlockControllerLazy);
mDozeSuppressor.setDozeMachine(mDozeMachine);
@@ -122,36 +108,35 @@ public class DozeSuppressorTest extends SysuiTestCase {
public void testRegistersListenersOnInitialized_unregisteredOnFinish() {
// check that receivers and callbacks registered
mDozeSuppressor.transitionTo(UNINITIALIZED, INITIALIZED);
captureBroadcastReceiver();
captureDozeHostCallback();
// check that receivers and callbacks are unregistered
mDozeSuppressor.transitionTo(INITIALIZED, FINISH);
verify(mBroadcastDispatcher).unregisterReceiver(mBroadcastReceiver);
verify(mDozeHost).removeCallback(mDozeHostCallback);
}
@Test
public void testSuspendTriggersDoze_carMode() {
// GIVEN car mode
when(mUiModeManager.getCurrentModeType()).thenReturn(Configuration.UI_MODE_TYPE_CAR);
mDozeSuppressor.onUiModeTypeChanged(UI_MODE_TYPE_CAR);
// WHEN dozing begins
mDozeSuppressor.transitionTo(UNINITIALIZED, INITIALIZED);
// THEN doze continues with all doze triggers disabled.
verify(mDozeMachine).requestState(DOZE_SUSPEND_TRIGGERS);
verify(mDozeMachine, atLeastOnce()).requestState(DOZE_SUSPEND_TRIGGERS);
verify(mDozeMachine, never())
.requestState(AdditionalMatchers.not(eq(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));
mDozeSuppressor.onUiModeTypeChanged(UI_MODE_TYPE_CAR);
// THEN doze continues with all doze triggers disabled.
verify(mDozeMachine).requestState(DOZE_SUSPEND_TRIGGERS);
@@ -160,13 +145,13 @@ public class DozeSuppressorTest extends SysuiTestCase {
@Test
public void testDozeResume_exitCarMode() {
// GIVEN currently suspended, with AOD not enabled
mDozeSuppressor.onUiModeTypeChanged(UI_MODE_TYPE_CAR);
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));
mDozeSuppressor.onUiModeTypeChanged(UI_MODE_TYPE_NORMAL);
// THEN doze is resumed
verify(mDozeMachine).requestState(DOZE);
@@ -175,18 +160,52 @@ public class DozeSuppressorTest extends SysuiTestCase {
@Test
public void testDozeAoDResume_exitCarMode() {
// GIVEN currently suspended, with AOD not enabled
mDozeSuppressor.onUiModeTypeChanged(UI_MODE_TYPE_CAR);
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));
mDozeSuppressor.onUiModeTypeChanged(UI_MODE_TYPE_NORMAL);
// THEN doze AOD is resumed
verify(mDozeMachine).requestState(DOZE_AOD);
}
@Test
public void testUiModeDoesNotChange_noStateTransition() {
mDozeSuppressor.transitionTo(UNINITIALIZED, INITIALIZED);
clearInvocations(mDozeMachine);
mDozeSuppressor.onUiModeTypeChanged(UI_MODE_TYPE_CAR);
mDozeSuppressor.onUiModeTypeChanged(UI_MODE_TYPE_CAR);
mDozeSuppressor.onUiModeTypeChanged(UI_MODE_TYPE_CAR);
verify(mDozeMachine, times(1)).requestState(DOZE_SUSPEND_TRIGGERS);
verify(mDozeMachine, never())
.requestState(AdditionalMatchers.not(eq(DOZE_SUSPEND_TRIGGERS)));
}
@Test
public void testUiModeTypeChange_whenDozeMachineIsNotReady_doesNotDoAnything() {
when(mDozeMachine.isUninitializedOrFinished()).thenReturn(true);
mDozeSuppressor.onUiModeTypeChanged(UI_MODE_TYPE_CAR);
verify(mDozeMachine, never()).requestState(any());
}
@Test
public void testUiModeTypeChange_CarModeEnabledAndDozeMachineNotReady_suspendsTriggersAfter() {
when(mDozeMachine.isUninitializedOrFinished()).thenReturn(true);
mDozeSuppressor.onUiModeTypeChanged(UI_MODE_TYPE_CAR);
verify(mDozeMachine, never()).requestState(any());
mDozeSuppressor.transitionTo(UNINITIALIZED, INITIALIZED);
verify(mDozeMachine, times(1)).requestState(DOZE_SUSPEND_TRIGGERS);
}
@Test
public void testEndDoze_unprovisioned() {
// GIVEN device unprovisioned
@@ -276,14 +295,4 @@ public class DozeSuppressorTest extends SysuiTestCase {
verify(mDozeHost).addCallback(mDozeHostCaptor.capture());
mDozeHostCallback = mDozeHostCaptor.getValue();
}
private void captureBroadcastReceiver() {
verify(mBroadcastDispatcher).registerReceiver(mBroadcastReceiverCaptor.capture(),
mIntentFilterCaptor.capture());
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));
}
}