diff options
8 files changed, 172 insertions, 106 deletions
diff --git a/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java b/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java index 1b37fb9fdad3..904a54b00fa3 100644 --- a/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java +++ b/core/java/android/hardware/devicestate/DeviceStateManagerGlobal.java @@ -179,8 +179,6 @@ public final class DeviceStateManagerGlobal { @VisibleForTesting(visibility = Visibility.PACKAGE) public void registerDeviceStateCallback(@NonNull DeviceStateCallback callback, @NonNull Executor executor) { - DeviceStateCallbackWrapper wrapper; - DeviceStateInfo currentInfo; synchronized (mLock) { int index = findCallbackLocked(callback); if (index != -1) { @@ -189,25 +187,22 @@ public final class DeviceStateManagerGlobal { } registerCallbackIfNeededLocked(); - if (mLastReceivedInfo == null) { - // Initialize the last received info with the current info if this is the first - // callback being registered. - try { - mLastReceivedInfo = mDeviceStateManager.getDeviceStateInfo(); - } catch (RemoteException ex) { - throw ex.rethrowFromSystemServer(); - } - } - currentInfo = new DeviceStateInfo(mLastReceivedInfo); - - wrapper = new DeviceStateCallbackWrapper(callback, executor); + // Add the callback wrapper to the mCallbacks array after registering the callback as + // the callback could be triggered immediately if the mDeviceStateManager IBinder is in + // the same process as this instance. + DeviceStateCallbackWrapper wrapper = new DeviceStateCallbackWrapper(callback, executor); mCallbacks.add(wrapper); - } - wrapper.notifySupportedStatesChanged(currentInfo.supportedStates); - wrapper.notifyBaseStateChanged(currentInfo.baseState); - wrapper.notifyStateChanged(currentInfo.currentState); + if (mLastReceivedInfo != null) { + // Copy the array to prevent the callback from modifying the internal state. + final int[] supportedStates = Arrays.copyOf(mLastReceivedInfo.supportedStates, + mLastReceivedInfo.supportedStates.length); + wrapper.notifySupportedStatesChanged(supportedStates); + wrapper.notifyBaseStateChanged(mLastReceivedInfo.baseState); + wrapper.notifyStateChanged(mLastReceivedInfo.currentState); + } + } } /** @@ -267,7 +262,7 @@ public final class DeviceStateManagerGlobal { callbacks = new ArrayList<>(mCallbacks); } - final int diff = oldInfo == null ? 1 : info.diff(oldInfo); + final int diff = oldInfo == null ? ~0 : info.diff(oldInfo); if ((diff & DeviceStateInfo.CHANGED_SUPPORTED_STATES) > 0) { for (int i = 0; i < callbacks.size(); i++) { // Copy the array to prevent callbacks from modifying the internal state. diff --git a/core/java/android/hardware/devicestate/IDeviceStateManagerCallback.aidl b/core/java/android/hardware/devicestate/IDeviceStateManagerCallback.aidl index 593be867fe28..efb9888fb6ba 100644 --- a/core/java/android/hardware/devicestate/IDeviceStateManagerCallback.aidl +++ b/core/java/android/hardware/devicestate/IDeviceStateManagerCallback.aidl @@ -21,7 +21,8 @@ import android.hardware.devicestate.DeviceStateInfo; /** @hide */ interface IDeviceStateManagerCallback { /** - * Called in response to a change in {@link DeviceStateInfo}. + * Called in response to a change in {@link DeviceStateInfo}. Guaranteed to be called once + * after successful registration of the callback with the initial value. * * @param info the new device state info. * diff --git a/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateManagerGlobalTest.java b/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateManagerGlobalTest.java index 79b4d8bc5f1c..055fc7171fa0 100644 --- a/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateManagerGlobalTest.java +++ b/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateManagerGlobalTest.java @@ -208,6 +208,11 @@ public final class DeviceStateManagerGlobalTest { } mCallbacks.add(callback); + try { + callback.onDeviceStateInfoChanged(getInfo()); + } catch (RemoteException e) { + // Do nothing. Should never happen. + } } @Override diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java index 658d27f43313..217f1cd56598 100644 --- a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java +++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java @@ -78,9 +78,6 @@ import java.util.Optional; public final class DeviceStateManagerService extends SystemService { private static final String TAG = "DeviceStateManagerService"; private static final boolean DEBUG = false; - // The device state to use as a placeholder before callback from the DeviceStateProvider occurs. - private static final DeviceState UNSPECIFIED_DEVICE_STATE = - new DeviceState(MINIMUM_DEVICE_STATE, "UNSPECIFIED"); private final Object mLock = new Object(); @NonNull @@ -92,11 +89,11 @@ public final class DeviceStateManagerService extends SystemService { @GuardedBy("mLock") private SparseArray<DeviceState> mDeviceStates = new SparseArray<>(); - // The current committed device state. The default of UNSPECIFIED_DEVICE_STATE will be replaced - // by the current state after the initial callback from the DeviceStateProvider. + // The current committed device state. Will be empty until the first device state provided by + // the DeviceStateProvider is committed. @GuardedBy("mLock") @NonNull - private DeviceState mCommittedState = UNSPECIFIED_DEVICE_STATE; + private Optional<DeviceState> mCommittedState = Optional.empty(); // The device state that is currently awaiting callback from the policy to be committed. @GuardedBy("mLock") @NonNull @@ -105,10 +102,11 @@ public final class DeviceStateManagerService extends SystemService { @GuardedBy("mLock") private boolean mIsPolicyWaitingForState = false; - // The device state that is set by the device state provider. + // The device state that is set by the DeviceStateProvider. Will be empty until the first + // callback from the provider and then will always contain the most recent value. @GuardedBy("mLock") @NonNull - private DeviceState mBaseState = UNSPECIFIED_DEVICE_STATE; + private Optional<DeviceState> mBaseState = Optional.empty(); // List of processes registered to receive notifications about changes to device state and // request status indexed by process id. @@ -142,11 +140,14 @@ public final class DeviceStateManagerService extends SystemService { /** * Returns the current state the system is in. Note that the system may be in the process of * configuring a different state. + * <p> + * Note: This method will return {@link Optional#empty()} if called before the first state has + * been committed, otherwise it will return the last committed state. * * @see #getPendingState() */ @NonNull - DeviceState getCommittedState() { + Optional<DeviceState> getCommittedState() { synchronized (mLock) { return mCommittedState; } @@ -167,11 +168,15 @@ public final class DeviceStateManagerService extends SystemService { /** * Returns the base state. The service will configure the device to match the base state when * there is no active request to override the base state. + * <p> + * Note: This method will return {@link Optional#empty()} if called before a base state is + * provided to the service by the {@link DeviceStateProvider}, otherwise it will return the + * most recent provided value. * * @see #getOverrideState() */ @NonNull - DeviceState getBaseState() { + Optional<DeviceState> getBaseState() { synchronized (mLock) { return mBaseState; } @@ -223,9 +228,14 @@ public final class DeviceStateManagerService extends SystemService { @NonNull private DeviceStateInfo getDeviceStateInfoLocked() { + if (!mBaseState.isPresent() || !mCommittedState.isPresent()) { + throw new IllegalStateException("Trying to get the current DeviceStateInfo before the" + + " initial state has been committed."); + } + final int[] supportedStates = getSupportedStateIdentifiersLocked(); - final int baseState = mBaseState.getIdentifier(); - final int currentState = mCommittedState.getIdentifier(); + final int baseState = mBaseState.get().getIdentifier(); + final int currentState = mCommittedState.get().getIdentifier(); return new DeviceStateInfo(supportedStates, baseState, currentState); } @@ -237,6 +247,7 @@ public final class DeviceStateManagerService extends SystemService { private void updateSupportedStates(DeviceState[] supportedDeviceStates) { boolean updatedPendingState; + boolean hasBaseState; synchronized (mLock) { final int[] oldStateIdentifiers = getSupportedStateIdentifiersLocked(); @@ -260,9 +271,10 @@ public final class DeviceStateManagerService extends SystemService { } updatedPendingState = updatePendingStateLocked(); + hasBaseState = mBaseState.isPresent(); } - if (!updatedPendingState) { + if (hasBaseState && !updatedPendingState) { // If the change in the supported states didn't result in a change of the pending state // commitPendingState() will never be called and the callbacks will never be notified // of the change. @@ -306,11 +318,11 @@ public final class DeviceStateManagerService extends SystemService { } final DeviceState baseState = baseStateOptional.get(); - if (mBaseState.equals(baseState)) { + if (mBaseState.isPresent() && mBaseState.get().equals(baseState)) { // Base state hasn't changed. Nothing to do. return; } - mBaseState = baseState; + mBaseState = Optional.of(baseState); final int requestSize = mRequestRecords.size(); for (int i = 0; i < requestSize; i++) { @@ -351,9 +363,10 @@ public final class DeviceStateManagerService extends SystemService { final DeviceState stateToConfigure; if (!mRequestRecords.isEmpty()) { stateToConfigure = mRequestRecords.get(mRequestRecords.size() - 1).mRequestedState; - } else if (isSupportedStateLocked(mBaseState.getIdentifier())) { + } else if (mBaseState.isPresent() + && isSupportedStateLocked(mBaseState.get().getIdentifier())) { // Base state could have recently become unsupported after a change in supported states. - stateToConfigure = mBaseState; + stateToConfigure = mBaseState.get(); } else { stateToConfigure = null; } @@ -363,7 +376,7 @@ public final class DeviceStateManagerService extends SystemService { return false; } - if (stateToConfigure.equals(mCommittedState)) { + if (mCommittedState.isPresent() && stateToConfigure.equals(mCommittedState.get())) { // The state requesting to be committed already matches the current committed state. return false; } @@ -417,15 +430,15 @@ public final class DeviceStateManagerService extends SystemService { private void commitPendingState() { // Update the current state. synchronized (mLock) { + final DeviceState newState = mPendingState.get(); if (DEBUG) { - Slog.d(TAG, "Committing state: " + mPendingState); + Slog.d(TAG, "Committing state: " + newState); } - mCommittedState = mPendingState.get(); if (!mRequestRecords.isEmpty()) { final OverrideRequestRecord topRequest = mRequestRecords.get(mRequestRecords.size() - 1); - if (topRequest.mRequestedState.getIdentifier() == mCommittedState.getIdentifier()) { + if (topRequest.mRequestedState.getIdentifier() == newState.getIdentifier()) { // The top request could have come in while the service was awaiting callback // from the policy. In that case we only set it to active if it matches the // current committed state, otherwise it will be set to active when its @@ -434,6 +447,7 @@ public final class DeviceStateManagerService extends SystemService { } } + mCommittedState = Optional.of(newState); mPendingState = Optional.empty(); updatePendingStateLocked(); } @@ -503,19 +517,30 @@ public final class DeviceStateManagerService extends SystemService { } private void registerProcess(int pid, IDeviceStateManagerCallback callback) { + DeviceStateInfo currentInfo; + ProcessRecord record; + // Grab the lock to register the callback and get the current state. synchronized (mLock) { if (mProcessRecords.contains(pid)) { throw new SecurityException("The calling process has already registered an" + " IDeviceStateManagerCallback."); } - ProcessRecord record = new ProcessRecord(callback, pid); + record = new ProcessRecord(callback, pid); try { callback.asBinder().linkToDeath(record, 0); } catch (RemoteException ex) { throw new RuntimeException(ex); } mProcessRecords.put(pid, record); + + currentInfo = mCommittedState.isPresent() ? getDeviceStateInfoLocked() : null; + } + + if (currentInfo != null) { + // If there is not a committed state we'll wait to notify the process of the initial + // value. + record.notifyDeviceStateInfoAsync(currentInfo); } } diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerShellCommand.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerShellCommand.java index f3466006bd30..56b68b73cb57 100644 --- a/services/core/java/com/android/server/devicestate/DeviceStateManagerShellCommand.java +++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerShellCommand.java @@ -18,6 +18,7 @@ package com.android.server.devicestate; import static android.Manifest.permission.CONTROL_DEVICE_STATE; +import android.annotation.NonNull; import android.annotation.Nullable; import android.content.Context; import android.hardware.devicestate.DeviceStateManager; @@ -63,14 +64,14 @@ public class DeviceStateManagerShellCommand extends ShellCommand { } private void printState(PrintWriter pw) { - DeviceState committedState = mService.getCommittedState(); - DeviceState baseState = mService.getBaseState(); + Optional<DeviceState> committedState = mService.getCommittedState(); + Optional<DeviceState> baseState = mService.getBaseState(); Optional<DeviceState> overrideState = mService.getOverrideState(); - pw.println("Committed state: " + committedState); + pw.println("Committed state: " + toString(committedState)); if (overrideState.isPresent()) { pw.println("----------------------"); - pw.println("Base state: " + baseState); + pw.println("Base state: " + toString(baseState)); pw.println("Override state: " + overrideState.get()); } } @@ -143,4 +144,8 @@ public class DeviceStateManagerShellCommand extends ShellCommand { pw.println(" print-states"); pw.println(" Return list of currently supported device states."); } + + private static String toString(@NonNull Optional<DeviceState> state) { + return state.isPresent() ? state.get().toString() : "(none)"; + } } diff --git a/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java b/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java index 4e1065a9d3af..cd7f6854a37d 100644 --- a/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java +++ b/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java @@ -161,7 +161,7 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider, private int mLastReportedState = INVALID_DEVICE_STATE; @GuardedBy("mLock") - private boolean mIsLidOpen; + private Boolean mIsLidOpen; @GuardedBy("mLock") private final Map<Sensor, SensorEvent> mLatestSensorEvent = new ArrayMap<>(); @@ -299,7 +299,17 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider, int newState = mOrderedStates[0].getIdentifier(); for (int i = 0; i < mOrderedStates.length; i++) { int state = mOrderedStates[i].getIdentifier(); - if (mStateConditions.get(state).getAsBoolean()) { + boolean conditionSatisfied; + try { + conditionSatisfied = mStateConditions.get(state).getAsBoolean(); + } catch (IllegalStateException e) { + // Failed to compute the current state based on current available data. Return + // with the expectation that notifyDeviceStateChangedIfNeeded() will be called + // when a callback with the missing data is triggered. + return; + } + + if (conditionSatisfied) { newState = state; break; } @@ -351,6 +361,10 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider, @Override public boolean getAsBoolean() { synchronized (mLock) { + if (mIsLidOpen == null) { + throw new IllegalStateException("Have not received lid switch value."); + } + return mIsLidOpen == mExpectedOpen; } } @@ -377,13 +391,11 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider, synchronized (mLock) { SensorEvent latestEvent = mLatestSensorEvent.get(mSensor); if (latestEvent == null) { - // Default to returning false if we have not yet received a sensor event for the - // sensor. - return false; + throw new IllegalStateException("Have not received sensor event."); } if (latestEvent.values.length != mExpectedValues.size()) { - throw new IllegalStateException("Number of supplied numeric range(s) does not " + throw new RuntimeException("Number of supplied numeric range(s) does not " + "match the number of values in the latest sensor event for sensor: " + mSensor); } diff --git a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java index a97ea268b1c8..ff8fbda6c83e 100644 --- a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java @@ -73,16 +73,16 @@ public final class DeviceStateManagerServiceTest { @Test public void baseStateChanged() { - assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE)); assertEquals(mService.getPendingState(), Optional.empty()); - assertEquals(mService.getBaseState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE)); assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), DEFAULT_DEVICE_STATE.getIdentifier()); mProvider.setState(OTHER_DEVICE_STATE.getIdentifier()); - assertEquals(mService.getCommittedState(), OTHER_DEVICE_STATE); + assertEquals(mService.getCommittedState(), Optional.of(OTHER_DEVICE_STATE)); assertEquals(mService.getPendingState(), Optional.empty()); - assertEquals(mService.getBaseState(), OTHER_DEVICE_STATE); + assertEquals(mService.getBaseState(), Optional.of(OTHER_DEVICE_STATE)); assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), OTHER_DEVICE_STATE.getIdentifier()); } @@ -92,23 +92,23 @@ public final class DeviceStateManagerServiceTest { mPolicy.blockConfigure(); mProvider.setState(OTHER_DEVICE_STATE.getIdentifier()); - assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE); - assertEquals(mService.getPendingState().get(), OTHER_DEVICE_STATE); - assertEquals(mService.getBaseState(), OTHER_DEVICE_STATE); + assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE)); + assertEquals(mService.getPendingState(), Optional.of(OTHER_DEVICE_STATE)); + assertEquals(mService.getBaseState(), Optional.of(OTHER_DEVICE_STATE)); assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), OTHER_DEVICE_STATE.getIdentifier()); mProvider.setState(DEFAULT_DEVICE_STATE.getIdentifier()); - assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE); - assertEquals(mService.getPendingState().get(), OTHER_DEVICE_STATE); - assertEquals(mService.getBaseState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE)); + assertEquals(mService.getPendingState(), Optional.of(OTHER_DEVICE_STATE)); + assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE)); assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), OTHER_DEVICE_STATE.getIdentifier()); mPolicy.resumeConfigure(); - assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE)); assertEquals(mService.getPendingState(), Optional.empty()); - assertEquals(mService.getBaseState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE)); assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), DEFAULT_DEVICE_STATE.getIdentifier()); } @@ -119,9 +119,9 @@ public final class DeviceStateManagerServiceTest { mProvider.setState(UNSUPPORTED_DEVICE_STATE.getIdentifier()); }); - assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE)); assertEquals(mService.getPendingState(), Optional.empty()); - assertEquals(mService.getBaseState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE)); assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), DEFAULT_DEVICE_STATE.getIdentifier()); } @@ -132,9 +132,9 @@ public final class DeviceStateManagerServiceTest { mProvider.setState(INVALID_DEVICE_STATE); }); - assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE)); assertEquals(mService.getPendingState(), Optional.empty()); - assertEquals(mService.getBaseState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE)); assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), DEFAULT_DEVICE_STATE.getIdentifier()); } @@ -144,17 +144,17 @@ public final class DeviceStateManagerServiceTest { TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback(); mService.getBinderService().registerCallback(callback); - assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE)); assertEquals(mService.getPendingState(), Optional.empty()); - assertEquals(mService.getBaseState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE)); mProvider.notifySupportedDeviceStates(new DeviceState[]{ DEFAULT_DEVICE_STATE }); // The current committed and requests states do not change because the current state remains // supported. - assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE)); assertEquals(mService.getPendingState(), Optional.empty()); - assertEquals(mService.getBaseState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE)); assertArrayEquals(callback.getLastNotifiedInfo().supportedStates, new int[] { DEFAULT_DEVICE_STATE.getIdentifier() }); @@ -165,18 +165,21 @@ public final class DeviceStateManagerServiceTest { TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback(); mService.getBinderService().registerCallback(callback); - assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE); + // An initial callback will be triggered on registration, so we clear it here. + callback.clearLastNotifiedInfo(); + + assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE)); assertEquals(mService.getPendingState(), Optional.empty()); - assertEquals(mService.getBaseState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE)); mProvider.notifySupportedDeviceStates(new DeviceState[]{ DEFAULT_DEVICE_STATE, OTHER_DEVICE_STATE }); // The current committed and requests states do not change because the current state remains // supported. - assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE)); assertEquals(mService.getPendingState(), Optional.empty()); - assertEquals(mService.getBaseState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE)); // The callback wasn't notified about a change in supported states as the states have not // changed. @@ -230,6 +233,17 @@ public final class DeviceStateManagerServiceTest { } @Test + public void registerCallback_emitsInitialValue() throws RemoteException { + TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback(); + mService.getBinderService().registerCallback(callback); + assertNotNull(callback.getLastNotifiedInfo()); + assertEquals(callback.getLastNotifiedInfo().baseState, + DEFAULT_DEVICE_STATE.getIdentifier()); + assertEquals(callback.getLastNotifiedInfo().currentState, + DEFAULT_DEVICE_STATE.getIdentifier()); + } + + @Test public void requestState() throws RemoteException { TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback(); mService.getBinderService().registerCallback(callback); @@ -244,8 +258,8 @@ public final class DeviceStateManagerServiceTest { assertEquals(callback.getLastNotifiedStatus(token), TestDeviceStateManagerCallback.STATUS_ACTIVE); // Committed state changes as there is a requested override. - assertEquals(mService.getCommittedState(), OTHER_DEVICE_STATE); - assertEquals(mService.getBaseState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getCommittedState(), Optional.of(OTHER_DEVICE_STATE)); + assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE)); assertEquals(mService.getOverrideState().get(), OTHER_DEVICE_STATE); assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), OTHER_DEVICE_STATE.getIdentifier()); @@ -261,8 +275,8 @@ public final class DeviceStateManagerServiceTest { assertEquals(callback.getLastNotifiedStatus(token), TestDeviceStateManagerCallback.STATUS_CANCELED); // Committed state is set back to the requested state once the override is cleared. - assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE); - assertEquals(mService.getBaseState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE)); + assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE)); assertFalse(mService.getOverrideState().isPresent()); assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), DEFAULT_DEVICE_STATE.getIdentifier()); @@ -290,9 +304,9 @@ public final class DeviceStateManagerServiceTest { mService.getBinderService().requestState(firstRequestToken, OTHER_DEVICE_STATE.getIdentifier(), 0 /* flags */); - assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE); - assertEquals(mService.getPendingState().get(), OTHER_DEVICE_STATE); - assertEquals(mService.getBaseState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE)); + assertEquals(mService.getPendingState(), Optional.of(OTHER_DEVICE_STATE)); + assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE)); assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), OTHER_DEVICE_STATE.getIdentifier()); @@ -309,17 +323,17 @@ public final class DeviceStateManagerServiceTest { assertEquals(callback.getLastNotifiedStatus(secondRequestToken), TestDeviceStateManagerCallback.STATUS_UNKNOWN); - assertEquals(mService.getCommittedState(), OTHER_DEVICE_STATE); - assertEquals(mService.getPendingState().get(), DEFAULT_DEVICE_STATE); - assertEquals(mService.getBaseState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getCommittedState(), Optional.of(OTHER_DEVICE_STATE)); + assertEquals(mService.getPendingState(), Optional.of(DEFAULT_DEVICE_STATE)); + assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE)); assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), DEFAULT_DEVICE_STATE.getIdentifier()); mPolicy.resumeConfigure(); - assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE)); assertEquals(mService.getPendingState(), Optional.empty()); - assertEquals(mService.getBaseState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE)); assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), DEFAULT_DEVICE_STATE.getIdentifier()); @@ -331,9 +345,9 @@ public final class DeviceStateManagerServiceTest { assertEquals(callback.getLastNotifiedStatus(secondRequestToken), TestDeviceStateManagerCallback.STATUS_CANCELED); - assertEquals(mService.getCommittedState(), OTHER_DEVICE_STATE); + assertEquals(mService.getCommittedState(), Optional.of(OTHER_DEVICE_STATE)); assertEquals(mService.getPendingState(), Optional.empty()); - assertEquals(mService.getBaseState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE)); assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), OTHER_DEVICE_STATE.getIdentifier()); } @@ -370,8 +384,8 @@ public final class DeviceStateManagerServiceTest { TestDeviceStateManagerCallback.STATUS_ACTIVE); // Committed state changes as there is a requested override. - assertEquals(mService.getCommittedState(), OTHER_DEVICE_STATE); - assertEquals(mService.getBaseState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getCommittedState(), Optional.of(OTHER_DEVICE_STATE)); + assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE)); assertEquals(mService.getOverrideState().get(), OTHER_DEVICE_STATE); assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), OTHER_DEVICE_STATE.getIdentifier()); @@ -382,8 +396,8 @@ public final class DeviceStateManagerServiceTest { assertEquals(callback.getLastNotifiedStatus(token), TestDeviceStateManagerCallback.STATUS_CANCELED); // Committed state is set back to the requested state once the override is cleared. - assertEquals(mService.getCommittedState(), OTHER_DEVICE_STATE); - assertEquals(mService.getBaseState(), OTHER_DEVICE_STATE); + assertEquals(mService.getCommittedState(), Optional.of(OTHER_DEVICE_STATE)); + assertEquals(mService.getBaseState(), Optional.of(OTHER_DEVICE_STATE)); assertFalse(mService.getOverrideState().isPresent()); assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), OTHER_DEVICE_STATE.getIdentifier()); @@ -404,8 +418,8 @@ public final class DeviceStateManagerServiceTest { assertEquals(callback.getLastNotifiedStatus(token), TestDeviceStateManagerCallback.STATUS_ACTIVE); // Committed state changes as there is a requested override. - assertEquals(mService.getCommittedState(), OTHER_DEVICE_STATE); - assertEquals(mService.getBaseState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getCommittedState(), Optional.of(OTHER_DEVICE_STATE)); + assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE)); assertEquals(mService.getOverrideState().get(), OTHER_DEVICE_STATE); assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), OTHER_DEVICE_STATE.getIdentifier()); @@ -417,8 +431,8 @@ public final class DeviceStateManagerServiceTest { TestDeviceStateManagerCallback.STATUS_CANCELED); // Committed state is set back to the requested state as the override state is no longer // supported. - assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE); - assertEquals(mService.getBaseState(), DEFAULT_DEVICE_STATE); + assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE)); + assertEquals(mService.getBaseState(), Optional.of(DEFAULT_DEVICE_STATE)); assertFalse(mService.getOverrideState().isPresent()); assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), DEFAULT_DEVICE_STATE.getIdentifier()); @@ -551,7 +565,6 @@ public final class DeviceStateManagerServiceTest { @Nullable private DeviceStateInfo mLastNotifiedInfo; - private boolean mNotifiedOfChangeInSupportedStates; private final HashMap<IBinder, Integer> mLastNotifiedStatus = new HashMap<>(); @Override @@ -579,6 +592,10 @@ public final class DeviceStateManagerServiceTest { return mLastNotifiedInfo; } + void clearLastNotifiedInfo() { + mLastNotifiedInfo = null; + } + int getLastNotifiedStatus(IBinder requestToken) { return mLastNotifiedStatus.getOrDefault(requestToken, STATUS_UNKNOWN); } diff --git a/services/tests/servicestests/src/com/android/server/policy/DeviceStateProviderImplTest.java b/services/tests/servicestests/src/com/android/server/policy/DeviceStateProviderImplTest.java index 4f36c8ae99ae..d13687ce3254 100644 --- a/services/tests/servicestests/src/com/android/server/policy/DeviceStateProviderImplTest.java +++ b/services/tests/servicestests/src/com/android/server/policy/DeviceStateProviderImplTest.java @@ -150,8 +150,8 @@ public final class DeviceStateProviderImplTest { provider.setListener(listener); verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture()); - final DeviceState[] expectedStates = new DeviceState[]{ new DeviceState(1, null), - new DeviceState(2, null) }; + final DeviceState[] expectedStates = new DeviceState[]{ new DeviceState(1, ""), + new DeviceState(2, "") }; assertArrayEquals(expectedStates, mDeviceStateArrayCaptor.getValue()); verify(listener).onStateChanged(mIntegerCaptor.capture()); @@ -187,16 +187,22 @@ public final class DeviceStateProviderImplTest { provider.setListener(listener); verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture()); - final DeviceState[] expectedStates = new DeviceState[]{ new DeviceState(1, null), + final DeviceState[] expectedStates = new DeviceState[]{ new DeviceState(1, ""), new DeviceState(2, "CLOSED") }; assertArrayEquals(expectedStates, mDeviceStateArrayCaptor.getValue()); + // onStateChanged() should not be called because the provider has not yet been notified of + // the initial lid switch state. + verify(listener, never()).onStateChanged(mIntegerCaptor.capture()); + + provider.notifyLidSwitchChanged(0, false /* lidOpen */); + verify(listener).onStateChanged(mIntegerCaptor.capture()); assertEquals(2, mIntegerCaptor.getValue().intValue()); Mockito.clearInvocations(listener); - provider.notifyLidSwitchChanged(0, true /* lidOpen */); + provider.notifyLidSwitchChanged(1, true /* lidOpen */); verify(listener, never()).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture()); verify(listener).onStateChanged(mIntegerCaptor.capture()); assertEquals(1, mIntegerCaptor.getValue().intValue()); @@ -260,9 +266,9 @@ public final class DeviceStateProviderImplTest { assertArrayEquals( new DeviceState[]{ new DeviceState(1, "CLOSED"), new DeviceState(2, "HALF_OPENED"), new DeviceState(3, "OPENED") }, mDeviceStateArrayCaptor.getValue()); - - verify(listener).onStateChanged(mIntegerCaptor.capture()); - assertEquals(1, mIntegerCaptor.getValue().intValue()); + // onStateChanged() should not be called because the provider has not yet been notified of + // the initial sensor state. + verify(listener, never()).onStateChanged(mIntegerCaptor.capture()); Mockito.clearInvocations(listener); |