Merge "Allow DeviceStateProvider to provide optional String name for device states." into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
dfe7df31c9
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (C) 2021 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.server.devicestate;
|
||||
|
||||
import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE;
|
||||
|
||||
import android.annotation.IntRange;
|
||||
import android.annotation.NonNull;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* A state of the device defined by the {@link DeviceStateProvider} and managed by the
|
||||
* {@link DeviceStateManagerService}.
|
||||
* <p>
|
||||
* Device state is an abstract concept that allows mapping the current state of the device to the
|
||||
* state of the system. This is useful for variable-state devices, like foldable or rollable
|
||||
* devices, that can be configured by users into differing hardware states, which each may have a
|
||||
* different expected use case.
|
||||
*
|
||||
* @see DeviceStateProvider
|
||||
* @see DeviceStateManagerService
|
||||
*/
|
||||
public final class DeviceState {
|
||||
/** Unique identifier for the device state. */
|
||||
@IntRange(from = INVALID_DEVICE_STATE)
|
||||
private final int mIdentifier;
|
||||
|
||||
/** String description of the device state. */
|
||||
@NonNull
|
||||
private final String mName;
|
||||
|
||||
public DeviceState(@IntRange(from = INVALID_DEVICE_STATE) int identifier,
|
||||
@NonNull String name) {
|
||||
if (identifier != INVALID_DEVICE_STATE && identifier < 0) {
|
||||
throw new IllegalArgumentException("Identifier must be greater than or equal to zero.");
|
||||
}
|
||||
mIdentifier = identifier;
|
||||
mName = name;
|
||||
}
|
||||
|
||||
/** Returns the unique identifier for the device state. */
|
||||
@IntRange(from = INVALID_DEVICE_STATE)
|
||||
public int getIdentifier() {
|
||||
return mIdentifier;
|
||||
}
|
||||
|
||||
/** Returns a string description of the device state. */
|
||||
@NonNull
|
||||
public String getName() {
|
||||
return mName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "DeviceState{" + "identifier=" + mIdentifier + ", name='" + mName + '\'' + '}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
DeviceState that = (DeviceState) o;
|
||||
return mIdentifier == that.mIdentifier
|
||||
&& Objects.equals(mName, that.mName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(mIdentifier, mName);
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,9 @@ package com.android.server.devicestate;
|
||||
import static android.Manifest.permission.CONTROL_DEVICE_STATE;
|
||||
import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE;
|
||||
|
||||
import android.annotation.IntRange;
|
||||
import android.annotation.NonNull;
|
||||
import android.annotation.Nullable;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.hardware.devicestate.IDeviceStateManager;
|
||||
@@ -29,7 +31,6 @@ import android.os.IBinder;
|
||||
import android.os.RemoteException;
|
||||
import android.os.ResultReceiver;
|
||||
import android.os.ShellCallback;
|
||||
import android.util.IntArray;
|
||||
import android.util.Slog;
|
||||
import android.util.SparseArray;
|
||||
|
||||
@@ -42,7 +43,7 @@ import com.android.server.policy.DeviceStatePolicyImpl;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* A system service that manages the state of a device with user-configurable hardware like a
|
||||
@@ -74,26 +75,31 @@ public final class DeviceStateManagerService extends SystemService {
|
||||
@NonNull
|
||||
private final BinderService mBinderService;
|
||||
|
||||
// All supported device states keyed by identifier.
|
||||
@GuardedBy("mLock")
|
||||
private IntArray mSupportedDeviceStates;
|
||||
private SparseArray<DeviceState> mDeviceStates = new SparseArray<>();
|
||||
|
||||
// The current committed device state.
|
||||
// The current committed device state. The default of INVALID_DEVICE_STATE will be replaced by
|
||||
// the current state after the initial callback from the DeviceStateProvider.
|
||||
@GuardedBy("mLock")
|
||||
private int mCommittedState = INVALID_DEVICE_STATE;
|
||||
@NonNull
|
||||
private DeviceState mCommittedState = new DeviceState(INVALID_DEVICE_STATE, "INVALID");
|
||||
// The device state that is currently awaiting callback from the policy to be committed.
|
||||
@GuardedBy("mLock")
|
||||
private int mPendingState = INVALID_DEVICE_STATE;
|
||||
@NonNull
|
||||
private Optional<DeviceState> mPendingState = Optional.empty();
|
||||
// Whether or not the policy is currently waiting to be notified of the current pending state.
|
||||
@GuardedBy("mLock")
|
||||
private boolean mIsPolicyWaitingForState = false;
|
||||
// The device state that is currently requested and is next to be configured and committed.
|
||||
// Can be overwritten by an override state value if requested.
|
||||
@GuardedBy("mLock")
|
||||
private int mRequestedState = INVALID_DEVICE_STATE;
|
||||
// The most recently requested override state, or INVALID_DEVICE_STATE if no override is
|
||||
// requested.
|
||||
@NonNull
|
||||
private Optional<DeviceState> mRequestedState = Optional.empty();
|
||||
// The most recently requested override state, or empty if no override is requested.
|
||||
@GuardedBy("mLock")
|
||||
private int mRequestedOverrideState = INVALID_DEVICE_STATE;
|
||||
@NonNull
|
||||
private Optional<DeviceState> mRequestedOverrideState = Optional.empty();
|
||||
|
||||
// List of registered callbacks indexed by process id.
|
||||
@GuardedBy("mLock")
|
||||
@@ -122,18 +128,20 @@ public final class DeviceStateManagerService extends SystemService {
|
||||
*
|
||||
* @see #getPendingState()
|
||||
*/
|
||||
int getCommittedState() {
|
||||
@NonNull
|
||||
DeviceState getCommittedState() {
|
||||
synchronized (mLock) {
|
||||
return mCommittedState;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the state the system is currently configuring, or {@link #INVALID_DEVICE_STATE} if
|
||||
* the system is not in the process of configuring a state.
|
||||
* Returns the state the system is currently configuring, or {@link Optional#empty()} if the
|
||||
* system is not in the process of configuring a state.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
int getPendingState() {
|
||||
@NonNull
|
||||
Optional<DeviceState> getPendingState() {
|
||||
synchronized (mLock) {
|
||||
return mPendingState;
|
||||
}
|
||||
@@ -143,7 +151,8 @@ public final class DeviceStateManagerService extends SystemService {
|
||||
* Returns the requested state. The service will configure the device to match the requested
|
||||
* state when possible.
|
||||
*/
|
||||
int getRequestedState() {
|
||||
@NonNull
|
||||
Optional<DeviceState> getRequestedState() {
|
||||
synchronized (mLock) {
|
||||
return mRequestedState;
|
||||
}
|
||||
@@ -165,7 +174,7 @@ public final class DeviceStateManagerService extends SystemService {
|
||||
return false;
|
||||
}
|
||||
|
||||
mRequestedOverrideState = overrideState;
|
||||
mRequestedOverrideState = getStateLocked(overrideState);
|
||||
updatePendingStateLocked();
|
||||
}
|
||||
|
||||
@@ -181,20 +190,24 @@ public final class DeviceStateManagerService extends SystemService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current requested override state, or {@link #INVALID_DEVICE_STATE} is no override
|
||||
* Returns the current requested override state, or {@link Optional#empty()} if no override
|
||||
* state is requested.
|
||||
*/
|
||||
int getOverrideState() {
|
||||
@NonNull
|
||||
Optional<DeviceState> getOverrideState() {
|
||||
synchronized (mLock) {
|
||||
return mRequestedOverrideState;
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the list of currently supported device states. */
|
||||
int[] getSupportedStates() {
|
||||
DeviceState[] getSupportedStates() {
|
||||
synchronized (mLock) {
|
||||
// Copy array to prevent external modification of internal state.
|
||||
return Arrays.copyOf(mSupportedDeviceStates.toArray(), mSupportedDeviceStates.size());
|
||||
DeviceState[] supportedStates = new DeviceState[mDeviceStates.size()];
|
||||
for (int i = 0; i < supportedStates.length; i++) {
|
||||
supportedStates[i] = mDeviceStates.valueAt(i);
|
||||
}
|
||||
return supportedStates;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,24 +216,26 @@ public final class DeviceStateManagerService extends SystemService {
|
||||
return mBinderService;
|
||||
}
|
||||
|
||||
private void updateSupportedStates(int[] supportedDeviceStates) {
|
||||
// Must ensure sorted as isSupportedStateLocked() impl uses binary search.
|
||||
Arrays.sort(supportedDeviceStates, 0, supportedDeviceStates.length);
|
||||
private void updateSupportedStates(DeviceState[] supportedDeviceStates) {
|
||||
synchronized (mLock) {
|
||||
mSupportedDeviceStates = IntArray.wrap(supportedDeviceStates);
|
||||
mDeviceStates.clear();
|
||||
for (int i = 0; i < supportedDeviceStates.length; i++) {
|
||||
DeviceState state = supportedDeviceStates[i];
|
||||
mDeviceStates.put(state.getIdentifier(), state);
|
||||
}
|
||||
|
||||
if (mRequestedState != INVALID_DEVICE_STATE
|
||||
&& !isSupportedStateLocked(mRequestedState)) {
|
||||
if (mRequestedState.isPresent()
|
||||
&& !isSupportedStateLocked(mRequestedState.get().getIdentifier())) {
|
||||
// The current requested state is no longer valid. We'll clear it here, though
|
||||
// we won't actually update the current state until a callback comes from the
|
||||
// provider with the most recent state.
|
||||
mRequestedState = INVALID_DEVICE_STATE;
|
||||
mRequestedState = Optional.empty();
|
||||
}
|
||||
if (mRequestedOverrideState != INVALID_DEVICE_STATE
|
||||
&& !isSupportedStateLocked(mRequestedOverrideState)) {
|
||||
if (mRequestedOverrideState.isPresent()
|
||||
&& !isSupportedStateLocked(mRequestedOverrideState.get().getIdentifier())) {
|
||||
// The current override state is no longer valid. We'll clear it here and update
|
||||
// the committed state if necessary.
|
||||
mRequestedOverrideState = INVALID_DEVICE_STATE;
|
||||
mRequestedOverrideState = Optional.empty();
|
||||
}
|
||||
updatePendingStateLocked();
|
||||
}
|
||||
@@ -230,10 +245,19 @@ public final class DeviceStateManagerService extends SystemService {
|
||||
|
||||
/**
|
||||
* Returns {@code true} if the provided state is supported. Requires that
|
||||
* {@link #mSupportedDeviceStates} is sorted prior to calling.
|
||||
* {@link #mDeviceStates} is sorted prior to calling.
|
||||
*/
|
||||
private boolean isSupportedStateLocked(int state) {
|
||||
return mSupportedDeviceStates.binarySearch(state) >= 0;
|
||||
private boolean isSupportedStateLocked(int identifier) {
|
||||
return mDeviceStates.contains(identifier);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link DeviceState} with the supplied {@code identifier}, or {@code null} if
|
||||
* there is no device state with the identifier.
|
||||
*/
|
||||
@Nullable
|
||||
private Optional<DeviceState> getStateLocked(int identifier) {
|
||||
return Optional.ofNullable(mDeviceStates.get(identifier));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -242,10 +266,11 @@ public final class DeviceStateManagerService extends SystemService {
|
||||
*
|
||||
* @see #isSupportedStateLocked(int)
|
||||
*/
|
||||
private void requestState(int state) {
|
||||
private void requestState(int identifier) {
|
||||
synchronized (mLock) {
|
||||
if (isSupportedStateLocked(state)) {
|
||||
mRequestedState = state;
|
||||
final Optional<DeviceState> requestedState = getStateLocked(identifier);
|
||||
if (requestedState.isPresent()) {
|
||||
mRequestedState = requestedState;
|
||||
}
|
||||
updatePendingStateLocked();
|
||||
}
|
||||
@@ -259,19 +284,19 @@ public final class DeviceStateManagerService extends SystemService {
|
||||
* changed.
|
||||
*/
|
||||
private void updatePendingStateLocked() {
|
||||
if (mPendingState != INVALID_DEVICE_STATE) {
|
||||
if (mPendingState.isPresent()) {
|
||||
// Have pending state, can not configure a new state until the state is committed.
|
||||
return;
|
||||
}
|
||||
|
||||
int stateToConfigure;
|
||||
if (mRequestedOverrideState != INVALID_DEVICE_STATE) {
|
||||
stateToConfigure = mRequestedOverrideState;
|
||||
final DeviceState stateToConfigure;
|
||||
if (mRequestedOverrideState.isPresent()) {
|
||||
stateToConfigure = mRequestedOverrideState.get();
|
||||
} else {
|
||||
stateToConfigure = mRequestedState;
|
||||
stateToConfigure = mRequestedState.orElse(null);
|
||||
}
|
||||
|
||||
if (stateToConfigure == INVALID_DEVICE_STATE) {
|
||||
if (stateToConfigure == null) {
|
||||
// No currently requested state.
|
||||
return;
|
||||
}
|
||||
@@ -281,7 +306,7 @@ public final class DeviceStateManagerService extends SystemService {
|
||||
return;
|
||||
}
|
||||
|
||||
mPendingState = stateToConfigure;
|
||||
mPendingState = Optional.of(stateToConfigure);
|
||||
mIsPolicyWaitingForState = true;
|
||||
}
|
||||
|
||||
@@ -302,7 +327,7 @@ public final class DeviceStateManagerService extends SystemService {
|
||||
return;
|
||||
}
|
||||
mIsPolicyWaitingForState = false;
|
||||
state = mPendingState;
|
||||
state = mPendingState.get().getIdentifier();
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
@@ -333,9 +358,9 @@ public final class DeviceStateManagerService extends SystemService {
|
||||
if (DEBUG) {
|
||||
Slog.d(TAG, "Committing state: " + mPendingState);
|
||||
}
|
||||
mCommittedState = mPendingState;
|
||||
newState = mCommittedState;
|
||||
mPendingState = INVALID_DEVICE_STATE;
|
||||
mCommittedState = mPendingState.get();
|
||||
newState = mCommittedState.getIdentifier();
|
||||
mPendingState = Optional.empty();
|
||||
updatePendingStateLocked();
|
||||
}
|
||||
|
||||
@@ -389,7 +414,7 @@ public final class DeviceStateManagerService extends SystemService {
|
||||
}
|
||||
|
||||
mCallbacks.put(callingPid, record);
|
||||
currentState = mCommittedState;
|
||||
currentState = mCommittedState.getIdentifier();
|
||||
}
|
||||
|
||||
// Notify the callback of the state at registration.
|
||||
@@ -406,10 +431,10 @@ public final class DeviceStateManagerService extends SystemService {
|
||||
pw.println("DEVICE STATE MANAGER (dumpsys device_state)");
|
||||
|
||||
synchronized (mLock) {
|
||||
pw.println(" mCommittedState=" + toString(mCommittedState));
|
||||
pw.println(" mPendingState=" + toString(mPendingState));
|
||||
pw.println(" mRequestedState=" + toString(mRequestedState));
|
||||
pw.println(" mRequestedOverrideState=" + toString(mRequestedOverrideState));
|
||||
pw.println(" mCommittedState=" + mCommittedState);
|
||||
pw.println(" mPendingState=" + mPendingState);
|
||||
pw.println(" mRequestedState=" + mRequestedState);
|
||||
pw.println(" mRequestedOverrideState=" + mRequestedOverrideState);
|
||||
|
||||
final int callbackCount = mCallbacks.size();
|
||||
pw.println();
|
||||
@@ -421,30 +446,28 @@ public final class DeviceStateManagerService extends SystemService {
|
||||
}
|
||||
}
|
||||
|
||||
private String toString(int state) {
|
||||
return state == INVALID_DEVICE_STATE ? "(none)" : String.valueOf(state);
|
||||
}
|
||||
|
||||
private final class DeviceStateProviderListener implements DeviceStateProvider.Listener {
|
||||
@Override
|
||||
public void onSupportedDeviceStatesChanged(int[] newDeviceStates) {
|
||||
public void onSupportedDeviceStatesChanged(DeviceState[] newDeviceStates) {
|
||||
if (newDeviceStates.length == 0) {
|
||||
throw new IllegalArgumentException("Supported device states must not be empty");
|
||||
}
|
||||
for (int i = 0; i < newDeviceStates.length; i++) {
|
||||
if (newDeviceStates[i] < 0) {
|
||||
throw new IllegalArgumentException("Supported device states includes invalid"
|
||||
+ " value: " + newDeviceStates[i]);
|
||||
if (newDeviceStates[i].getIdentifier() == INVALID_DEVICE_STATE) {
|
||||
throw new IllegalArgumentException(
|
||||
"Supported device states includes INVALID_DEVICE_STATE identifier");
|
||||
}
|
||||
}
|
||||
|
||||
updateSupportedStates(newDeviceStates);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStateChanged(int state) {
|
||||
if (state < 0) {
|
||||
throw new IllegalArgumentException("Invalid state: " + state);
|
||||
public void onStateChanged(@IntRange(from = 0) int identifier) {
|
||||
if (identifier < 0) {
|
||||
throw new IllegalArgumentException("Invalid identifier: " + identifier);
|
||||
}
|
||||
|
||||
requestState(state);
|
||||
requestState(identifier);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -16,11 +16,10 @@
|
||||
|
||||
package com.android.server.devicestate;
|
||||
|
||||
import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE;
|
||||
|
||||
import android.os.ShellCommand;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* ShellCommands for {@link DeviceStateManagerService}.
|
||||
@@ -52,24 +51,15 @@ public class DeviceStateManagerShellCommand extends ShellCommand {
|
||||
}
|
||||
|
||||
private void printState(PrintWriter pw) {
|
||||
int committedState = mInternal.getCommittedState();
|
||||
int requestedState = mInternal.getRequestedState();
|
||||
int requestedOverrideState = mInternal.getOverrideState();
|
||||
DeviceState committedState = mInternal.getCommittedState();
|
||||
Optional<DeviceState> requestedState = mInternal.getRequestedState();
|
||||
Optional<DeviceState> requestedOverrideState = mInternal.getOverrideState();
|
||||
|
||||
if (committedState == INVALID_DEVICE_STATE) {
|
||||
pw.println("Device state: (invalid)");
|
||||
} else {
|
||||
pw.println("Device state: " + committedState);
|
||||
}
|
||||
|
||||
if (requestedOverrideState != INVALID_DEVICE_STATE) {
|
||||
pw.println("Committed state: " + committedState);
|
||||
if (requestedOverrideState.isPresent()) {
|
||||
pw.println("----------------------");
|
||||
if (requestedState == INVALID_DEVICE_STATE) {
|
||||
pw.println("Base state: (invalid)");
|
||||
} else {
|
||||
pw.println("Base state: " + requestedState);
|
||||
}
|
||||
pw.println("Override state: " + committedState);
|
||||
pw.println("Base state: " + requestedState.orElse(null));
|
||||
pw.println("Override state: " + requestedOverrideState.get());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,15 +92,12 @@ public class DeviceStateManagerShellCommand extends ShellCommand {
|
||||
}
|
||||
|
||||
private int runPrintStates(PrintWriter pw) {
|
||||
int[] states = mInternal.getSupportedStates();
|
||||
pw.print("Supported states: [ ");
|
||||
DeviceState[] states = mInternal.getSupportedStates();
|
||||
pw.print("Supported states: [\n");
|
||||
for (int i = 0; i < states.length; i++) {
|
||||
pw.print(states[i]);
|
||||
if (i < states.length - 1) {
|
||||
pw.print(", ");
|
||||
}
|
||||
pw.print(" " + states[i] + ",\n");
|
||||
}
|
||||
pw.println(" ]");
|
||||
pw.println("]");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -16,9 +16,11 @@
|
||||
|
||||
package com.android.server.devicestate;
|
||||
|
||||
import android.annotation.IntRange;
|
||||
|
||||
/**
|
||||
* Responsible for providing the set of currently supported device states and well as the current
|
||||
* device state.
|
||||
* Responsible for providing the set of supported {@link DeviceState device states} as well as the
|
||||
* current device state.
|
||||
*
|
||||
* @see DeviceStatePolicy
|
||||
*/
|
||||
@@ -26,8 +28,8 @@ public interface DeviceStateProvider {
|
||||
/**
|
||||
* Registers a listener for changes in provider state.
|
||||
* <p>
|
||||
* It is <b>required</b> that {@link Listener#onSupportedDeviceStatesChanged(int[])} be called
|
||||
* followed by {@link Listener#onStateChanged(int)} with the initial values on successful
|
||||
* It is <b>required</b> that {@link Listener#onSupportedDeviceStatesChanged(DeviceState[])} be
|
||||
* called followed by {@link Listener#onStateChanged(int)} with the initial values on successful
|
||||
* registration of the listener.
|
||||
*/
|
||||
void setListener(Listener listener);
|
||||
@@ -35,35 +37,36 @@ public interface DeviceStateProvider {
|
||||
/** Callback for changes in {@link DeviceStateProvider} state. */
|
||||
interface Listener {
|
||||
/**
|
||||
* Called to notify the listener of a change in supported device states. Required to be
|
||||
* called once on successful registration of the listener and then once on every
|
||||
* subsequent change in supported device states.
|
||||
* Called to notify the listener of a change in supported {@link DeviceState device states}.
|
||||
* Required to be called once on successful registration of the listener and then once on
|
||||
* every subsequent change in supported device states.
|
||||
* <p>
|
||||
* The set of device states can change based on the current hardware state of the device.
|
||||
* For example, if a device state depends on a particular peripheral device (display, etc)
|
||||
* it would only be reported as supported when the device is plugged. Otherwise, it should
|
||||
* not be included in the set of supported states.
|
||||
* <p>
|
||||
* All values provided must be greater than or equal to zero and there must always be at
|
||||
* least one supported device state.
|
||||
* The identifier for every provided device state must be unique and greater than or equal
|
||||
* to zero and there must always be at least one supported device state.
|
||||
*
|
||||
* @param newDeviceStates array of supported device states.
|
||||
*
|
||||
* @throws IllegalArgumentException if the list of device states is empty or if one of the
|
||||
* provided states is less than 0.
|
||||
* provided states contains an invalid identifier.
|
||||
*/
|
||||
void onSupportedDeviceStatesChanged(int[] newDeviceStates);
|
||||
void onSupportedDeviceStatesChanged(DeviceState[] newDeviceStates);
|
||||
|
||||
/**
|
||||
* Called to notify the listener of a change in current device state. Required to be called
|
||||
* once on successful registration of the listener and then once on every subsequent change
|
||||
* in device state. Value must have been included in the set of supported device states
|
||||
* provided in the most recent call to {@link #onSupportedDeviceStatesChanged(int[])}.
|
||||
* provided in the most recent call to
|
||||
* {@link #onSupportedDeviceStatesChanged(DeviceState[])}.
|
||||
*
|
||||
* @param state the new device state.
|
||||
* @param identifier the identifier of the new device state.
|
||||
*
|
||||
* @throws IllegalArgumentException if the state is less than 0.
|
||||
*/
|
||||
void onStateChanged(int state);
|
||||
void onStateChanged(@IntRange(from = 0) int identifier);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,10 +34,11 @@ import android.util.SparseArray;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.util.Preconditions;
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.devicestate.DeviceState;
|
||||
import com.android.server.devicestate.DeviceStateProvider;
|
||||
import com.android.server.policy.devicestate.config.Conditions;
|
||||
import com.android.server.policy.devicestate.config.DeviceState;
|
||||
import com.android.server.policy.devicestate.config.DeviceStateConfig;
|
||||
import com.android.server.policy.devicestate.config.LidSwitchCondition;
|
||||
import com.android.server.policy.devicestate.config.NumericRange;
|
||||
@@ -54,6 +55,7 @@ import java.io.InputStream;
|
||||
import java.math.BigDecimal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BooleanSupplier;
|
||||
@@ -82,7 +84,7 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider,
|
||||
private static final BooleanSupplier TRUE_BOOLEAN_SUPPLIER = () -> true;
|
||||
|
||||
@VisibleForTesting
|
||||
static final int DEFAULT_DEVICE_STATE = 0;
|
||||
static final DeviceState DEFAULT_DEVICE_STATE = new DeviceState(0, "DEFAULT");
|
||||
|
||||
private static final String VENDOR_CONFIG_FILE_PATH = "etc/devicestate/";
|
||||
private static final String DATA_CONFIG_FILE_PATH = "system/devicestate/";
|
||||
@@ -116,31 +118,38 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider,
|
||||
@VisibleForTesting
|
||||
static DeviceStateProviderImpl createFromConfig(@NonNull Context context,
|
||||
@Nullable ReadableConfig readableConfig) {
|
||||
SparseArray<Conditions> conditionsForState = new SparseArray<>();
|
||||
List<DeviceState> deviceStateList = new ArrayList<>();
|
||||
List<Conditions> conditionsList = new ArrayList<>();
|
||||
|
||||
if (readableConfig != null) {
|
||||
DeviceStateConfig config = parseConfig(readableConfig);
|
||||
if (config != null) {
|
||||
for (DeviceState stateConfig : config.getDeviceState()) {
|
||||
int state = stateConfig.getIdentifier().intValue();
|
||||
Conditions conditions = stateConfig.getConditions();
|
||||
conditionsForState.put(state, conditions);
|
||||
for (com.android.server.policy.devicestate.config.DeviceState stateConfig :
|
||||
config.getDeviceState()) {
|
||||
final int state = stateConfig.getIdentifier().intValue();
|
||||
final String name = stateConfig.getName() == null ? "" : stateConfig.getName();
|
||||
deviceStateList.add(new DeviceState(state, name));
|
||||
|
||||
final Conditions condition = stateConfig.getConditions();
|
||||
conditionsList.add(condition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (conditionsForState.size() == 0) {
|
||||
conditionsForState.put(DEFAULT_DEVICE_STATE, null);
|
||||
if (deviceStateList.size() == 0) {
|
||||
deviceStateList.add(DEFAULT_DEVICE_STATE);
|
||||
conditionsList.add(null);
|
||||
}
|
||||
return new DeviceStateProviderImpl(context, conditionsForState);
|
||||
return new DeviceStateProviderImpl(context, deviceStateList, conditionsList);
|
||||
}
|
||||
|
||||
// Lock for internal state.
|
||||
private final Object mLock = new Object();
|
||||
private final Context mContext;
|
||||
// List of supported states in ascending order.
|
||||
private final int[] mOrderedStates;
|
||||
// Map of state to a boolean supplier that returns true when all required conditions are met for
|
||||
// the device to be in the state.
|
||||
// List of supported states in ascending order based on their identifier.
|
||||
private final DeviceState[] mOrderedStates;
|
||||
// Map of state identifier to a boolean supplier that returns true when all required conditions
|
||||
// are met for the device to be in the state.
|
||||
private final SparseArray<BooleanSupplier> mStateConditions;
|
||||
|
||||
@Nullable
|
||||
@@ -155,12 +164,16 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider,
|
||||
private final Map<Sensor, SensorEvent> mLatestSensorEvent = new ArrayMap<>();
|
||||
|
||||
private DeviceStateProviderImpl(@NonNull Context context,
|
||||
@NonNull SparseArray<Conditions> conditionsForState) {
|
||||
@NonNull List<DeviceState> deviceStates,
|
||||
@NonNull List<Conditions> stateConditions) {
|
||||
Preconditions.checkArgument(deviceStates.size() == stateConditions.size(),
|
||||
"Number of device states must be equal to the number of device state conditions.");
|
||||
|
||||
mContext = context;
|
||||
mOrderedStates = new int[conditionsForState.size()];
|
||||
for (int i = 0; i < conditionsForState.size(); i++) {
|
||||
mOrderedStates[i] = conditionsForState.keyAt(i);
|
||||
}
|
||||
|
||||
DeviceState[] orderedStates = deviceStates.toArray(new DeviceState[deviceStates.size()]);
|
||||
Arrays.sort(orderedStates, Comparator.comparingInt(DeviceState::getIdentifier));
|
||||
mOrderedStates = orderedStates;
|
||||
|
||||
// Whether or not this instance should register to receive lid switch notifications from
|
||||
// InputManagerInternal. If there are no device state conditions that are based on the lid
|
||||
@@ -171,9 +184,9 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider,
|
||||
final ArraySet<Sensor> sensorsToListenTo = new ArraySet<>();
|
||||
|
||||
mStateConditions = new SparseArray<>();
|
||||
for (int i = 0; i < mOrderedStates.length; i++) {
|
||||
int state = mOrderedStates[i];
|
||||
Conditions conditions = conditionsForState.get(state);
|
||||
for (int i = 0; i < stateConditions.size(); i++) {
|
||||
final int state = deviceStates.get(i).getIdentifier();
|
||||
final Conditions conditions = stateConditions.get(i);
|
||||
if (conditions == null) {
|
||||
mStateConditions.put(state, TRUE_BOOLEAN_SUPPLIER);
|
||||
continue;
|
||||
@@ -261,7 +274,7 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider,
|
||||
|
||||
/** Notifies the listener that the set of supported device states has changed. */
|
||||
private void notifySupportedStatesChanged() {
|
||||
int[] supportedStates;
|
||||
DeviceState[] supportedStates;
|
||||
synchronized (mLock) {
|
||||
if (mListener == null) {
|
||||
return;
|
||||
@@ -281,9 +294,9 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider,
|
||||
return;
|
||||
}
|
||||
|
||||
int newState = mOrderedStates[0];
|
||||
int newState = mOrderedStates[0].getIdentifier();
|
||||
for (int i = 0; i < mOrderedStates.length; i++) {
|
||||
int state = mOrderedStates[i];
|
||||
int state = mOrderedStates[i].getIdentifier();
|
||||
if (mStateConditions.get(state).getAsBoolean()) {
|
||||
newState = state;
|
||||
break;
|
||||
|
||||
@@ -33,6 +33,8 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
@@ -43,9 +45,9 @@ import javax.annotation.Nullable;
|
||||
@Presubmit
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public final class DeviceStateManagerServiceTest {
|
||||
private static final int DEFAULT_DEVICE_STATE = 0;
|
||||
private static final int OTHER_DEVICE_STATE = 1;
|
||||
private static final int UNSUPPORTED_DEVICE_STATE = 999;
|
||||
private static final DeviceState DEFAULT_DEVICE_STATE = new DeviceState(0, "DEFAULT");
|
||||
private static final DeviceState OTHER_DEVICE_STATE = new DeviceState(1, "OTHER");
|
||||
private static final DeviceState UNSUPPORTED_DEVICE_STATE = new DeviceState(999, "UNSUPPORTED");
|
||||
|
||||
private TestDeviceStatePolicy mPolicy;
|
||||
private TestDeviceStateProvider mProvider;
|
||||
@@ -61,47 +63,53 @@ public final class DeviceStateManagerServiceTest {
|
||||
@Test
|
||||
public void requestStateChange() {
|
||||
assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mService.getPendingState(), INVALID_DEVICE_STATE);
|
||||
assertEquals(mService.getRequestedState(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mService.getPendingState(), Optional.empty());
|
||||
assertEquals(mService.getRequestedState().get(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
|
||||
DEFAULT_DEVICE_STATE.getIdentifier());
|
||||
|
||||
mProvider.notifyRequestState(OTHER_DEVICE_STATE);
|
||||
mProvider.notifyRequestState(OTHER_DEVICE_STATE.getIdentifier());
|
||||
assertEquals(mService.getCommittedState(), OTHER_DEVICE_STATE);
|
||||
assertEquals(mService.getPendingState(), INVALID_DEVICE_STATE);
|
||||
assertEquals(mService.getRequestedState(), OTHER_DEVICE_STATE);
|
||||
assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), OTHER_DEVICE_STATE);
|
||||
assertEquals(mService.getPendingState(), Optional.empty());
|
||||
assertEquals(mService.getRequestedState().get(), OTHER_DEVICE_STATE);
|
||||
assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
|
||||
OTHER_DEVICE_STATE.getIdentifier());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requestStateChange_pendingState() {
|
||||
mPolicy.blockConfigure();
|
||||
|
||||
mProvider.notifyRequestState(OTHER_DEVICE_STATE);
|
||||
mProvider.notifyRequestState(OTHER_DEVICE_STATE.getIdentifier());
|
||||
assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mService.getPendingState(), OTHER_DEVICE_STATE);
|
||||
assertEquals(mService.getRequestedState(), OTHER_DEVICE_STATE);
|
||||
assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), OTHER_DEVICE_STATE);
|
||||
assertEquals(mService.getPendingState().get(), OTHER_DEVICE_STATE);
|
||||
assertEquals(mService.getRequestedState().get(), OTHER_DEVICE_STATE);
|
||||
assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
|
||||
OTHER_DEVICE_STATE.getIdentifier());
|
||||
|
||||
mProvider.notifyRequestState(DEFAULT_DEVICE_STATE);
|
||||
mProvider.notifyRequestState(DEFAULT_DEVICE_STATE.getIdentifier());
|
||||
assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mService.getPendingState(), OTHER_DEVICE_STATE);
|
||||
assertEquals(mService.getRequestedState(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), OTHER_DEVICE_STATE);
|
||||
assertEquals(mService.getPendingState().get(), OTHER_DEVICE_STATE);
|
||||
assertEquals(mService.getRequestedState().get(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
|
||||
OTHER_DEVICE_STATE.getIdentifier());
|
||||
|
||||
mPolicy.resumeConfigure();
|
||||
assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mService.getPendingState(), INVALID_DEVICE_STATE);
|
||||
assertEquals(mService.getRequestedState(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mService.getPendingState(), Optional.empty());
|
||||
assertEquals(mService.getRequestedState().get(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
|
||||
DEFAULT_DEVICE_STATE.getIdentifier());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requestStateChange_unsupportedState() {
|
||||
mProvider.notifyRequestState(UNSUPPORTED_DEVICE_STATE);
|
||||
mProvider.notifyRequestState(UNSUPPORTED_DEVICE_STATE.getIdentifier());
|
||||
assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mService.getPendingState(), INVALID_DEVICE_STATE);
|
||||
assertEquals(mService.getRequestedState(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mService.getPendingState(), Optional.empty());
|
||||
assertEquals(mService.getRequestedState().get(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
|
||||
DEFAULT_DEVICE_STATE.getIdentifier());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -113,85 +121,83 @@ public final class DeviceStateManagerServiceTest {
|
||||
|
||||
@Test
|
||||
public void requestOverrideState() {
|
||||
mService.setOverrideState(OTHER_DEVICE_STATE);
|
||||
mService.setOverrideState(OTHER_DEVICE_STATE.getIdentifier());
|
||||
// Committed state changes as there is a requested override.
|
||||
assertEquals(mService.getCommittedState(), OTHER_DEVICE_STATE);
|
||||
assertEquals(mService.getRequestedState(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), OTHER_DEVICE_STATE);
|
||||
assertEquals(mService.getRequestedState().get(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
|
||||
OTHER_DEVICE_STATE.getIdentifier());
|
||||
|
||||
// Committed state is set back to the requested state once the override is cleared.
|
||||
mService.clearOverrideState();
|
||||
assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mService.getRequestedState(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mService.getRequestedState().get(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
|
||||
DEFAULT_DEVICE_STATE.getIdentifier());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void requestOverrideState_unsupportedState() {
|
||||
mService.setOverrideState(UNSUPPORTED_DEVICE_STATE);
|
||||
mService.setOverrideState(UNSUPPORTED_DEVICE_STATE.getIdentifier());
|
||||
// Committed state remains the same as the override state is unsupported.
|
||||
assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mService.getRequestedState(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mService.getRequestedState().get(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
|
||||
DEFAULT_DEVICE_STATE.getIdentifier());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportedStatesChanged() {
|
||||
assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mService.getPendingState(), INVALID_DEVICE_STATE);
|
||||
assertEquals(mService.getRequestedState(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mService.getPendingState(), Optional.empty());
|
||||
assertEquals(mService.getRequestedState().get(), DEFAULT_DEVICE_STATE);
|
||||
|
||||
mProvider.notifySupportedDeviceStates(new int []{ 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.getPendingState(), INVALID_DEVICE_STATE);
|
||||
assertEquals(mService.getRequestedState(), DEFAULT_DEVICE_STATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportedStatesChanged_invalidState() {
|
||||
assertThrows(IllegalArgumentException.class, () -> {
|
||||
mProvider.notifySupportedDeviceStates(new int []{ INVALID_DEVICE_STATE });
|
||||
});
|
||||
assertEquals(mService.getPendingState(), Optional.empty());
|
||||
assertEquals(mService.getRequestedState().get(), DEFAULT_DEVICE_STATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportedStatesChanged_unsupportedRequestedState() {
|
||||
assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mService.getPendingState(), INVALID_DEVICE_STATE);
|
||||
assertEquals(mService.getRequestedState(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mService.getPendingState(), Optional.empty());
|
||||
assertEquals(mService.getRequestedState().get(), DEFAULT_DEVICE_STATE);
|
||||
|
||||
mProvider.notifySupportedDeviceStates(new int []{ OTHER_DEVICE_STATE });
|
||||
mProvider.notifySupportedDeviceStates(new DeviceState[]{ OTHER_DEVICE_STATE });
|
||||
|
||||
// The current requested state is cleared because it is no longer supported.
|
||||
assertEquals(mService.getCommittedState(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mService.getPendingState(), INVALID_DEVICE_STATE);
|
||||
assertEquals(mService.getRequestedState(), INVALID_DEVICE_STATE);
|
||||
assertEquals(mService.getPendingState(), Optional.empty());
|
||||
assertEquals(mService.getRequestedState(), Optional.empty());
|
||||
|
||||
mProvider.notifyRequestState(OTHER_DEVICE_STATE);
|
||||
mProvider.notifyRequestState(OTHER_DEVICE_STATE.getIdentifier());
|
||||
|
||||
assertEquals(mService.getCommittedState(), OTHER_DEVICE_STATE);
|
||||
assertEquals(mService.getPendingState(), INVALID_DEVICE_STATE);
|
||||
assertEquals(mService.getRequestedState(), OTHER_DEVICE_STATE);
|
||||
assertEquals(mService.getPendingState(), Optional.empty());
|
||||
assertEquals(mService.getRequestedState().get(), OTHER_DEVICE_STATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void supportedStatesChanged_unsupportedOverrideState() {
|
||||
mService.setOverrideState(OTHER_DEVICE_STATE);
|
||||
mService.setOverrideState(OTHER_DEVICE_STATE.getIdentifier());
|
||||
// Committed state changes as there is a requested override.
|
||||
assertEquals(mService.getCommittedState(), OTHER_DEVICE_STATE);
|
||||
assertEquals(mService.getRequestedState(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), OTHER_DEVICE_STATE);
|
||||
assertEquals(mService.getRequestedState().get(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
|
||||
OTHER_DEVICE_STATE.getIdentifier());
|
||||
|
||||
mProvider.notifySupportedDeviceStates(new int []{ DEFAULT_DEVICE_STATE });
|
||||
mProvider.notifySupportedDeviceStates(new DeviceState[]{ DEFAULT_DEVICE_STATE });
|
||||
|
||||
// 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.getRequestedState(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mService.getRequestedState().get(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(),
|
||||
DEFAULT_DEVICE_STATE.getIdentifier());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -199,23 +205,27 @@ public final class DeviceStateManagerServiceTest {
|
||||
TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
|
||||
mService.getBinderService().registerCallback(callback);
|
||||
|
||||
mProvider.notifyRequestState(OTHER_DEVICE_STATE);
|
||||
mProvider.notifyRequestState(OTHER_DEVICE_STATE.getIdentifier());
|
||||
assertNotNull(callback.getLastNotifiedValue());
|
||||
assertEquals(callback.getLastNotifiedValue().intValue(), OTHER_DEVICE_STATE);
|
||||
assertEquals(callback.getLastNotifiedValue().intValue(),
|
||||
OTHER_DEVICE_STATE.getIdentifier());
|
||||
|
||||
mProvider.notifyRequestState(DEFAULT_DEVICE_STATE);
|
||||
assertEquals(callback.getLastNotifiedValue().intValue(), DEFAULT_DEVICE_STATE);
|
||||
mProvider.notifyRequestState(DEFAULT_DEVICE_STATE.getIdentifier());
|
||||
assertEquals(callback.getLastNotifiedValue().intValue(),
|
||||
DEFAULT_DEVICE_STATE.getIdentifier());
|
||||
|
||||
mPolicy.blockConfigure();
|
||||
mProvider.notifyRequestState(OTHER_DEVICE_STATE);
|
||||
mProvider.notifyRequestState(OTHER_DEVICE_STATE.getIdentifier());
|
||||
// The callback should not have been notified of the state change as the policy is still
|
||||
// pending callback.
|
||||
assertEquals(callback.getLastNotifiedValue().intValue(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(callback.getLastNotifiedValue().intValue(),
|
||||
DEFAULT_DEVICE_STATE.getIdentifier());
|
||||
|
||||
mPolicy.resumeConfigure();
|
||||
// Now that the policy is finished processing the callback should be notified of the state
|
||||
// change.
|
||||
assertEquals(callback.getLastNotifiedValue().intValue(), OTHER_DEVICE_STATE);
|
||||
assertEquals(callback.getLastNotifiedValue().intValue(),
|
||||
OTHER_DEVICE_STATE.getIdentifier());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -223,7 +233,8 @@ public final class DeviceStateManagerServiceTest {
|
||||
TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback();
|
||||
mService.getBinderService().registerCallback(callback);
|
||||
assertNotNull(callback.getLastNotifiedValue());
|
||||
assertEquals(callback.getLastNotifiedValue().intValue(), DEFAULT_DEVICE_STATE);
|
||||
assertEquals(callback.getLastNotifiedValue().intValue(),
|
||||
DEFAULT_DEVICE_STATE.getIdentifier());
|
||||
}
|
||||
|
||||
private static final class TestDeviceStatePolicy implements DeviceStatePolicy {
|
||||
@@ -275,9 +286,8 @@ public final class DeviceStateManagerServiceTest {
|
||||
}
|
||||
|
||||
private static final class TestDeviceStateProvider implements DeviceStateProvider {
|
||||
private int[] mSupportedDeviceStates = new int[]{ DEFAULT_DEVICE_STATE,
|
||||
private DeviceState[] mSupportedDeviceStates = new DeviceState[]{ DEFAULT_DEVICE_STATE,
|
||||
OTHER_DEVICE_STATE };
|
||||
private int mCurrentDeviceState = DEFAULT_DEVICE_STATE;
|
||||
private Listener mListener;
|
||||
|
||||
@Override
|
||||
@@ -288,17 +298,16 @@ public final class DeviceStateManagerServiceTest {
|
||||
|
||||
mListener = listener;
|
||||
mListener.onSupportedDeviceStatesChanged(mSupportedDeviceStates);
|
||||
mListener.onStateChanged(mCurrentDeviceState);
|
||||
mListener.onStateChanged(mSupportedDeviceStates[0].getIdentifier());
|
||||
}
|
||||
|
||||
public void notifySupportedDeviceStates(int[] supportedDeviceStates) {
|
||||
public void notifySupportedDeviceStates(DeviceState[] supportedDeviceStates) {
|
||||
mSupportedDeviceStates = supportedDeviceStates;
|
||||
mListener.onSupportedDeviceStatesChanged(supportedDeviceStates);
|
||||
}
|
||||
|
||||
public void notifyRequestState(int state) {
|
||||
mCurrentDeviceState = state;
|
||||
mListener.onStateChanged(state);
|
||||
public void notifyRequestState(int identifier) {
|
||||
mListener.onStateChanged(identifier);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ import android.hardware.input.InputManagerInternal;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.server.LocalServices;
|
||||
import com.android.server.devicestate.DeviceState;
|
||||
import com.android.server.devicestate.DeviceStateProvider;
|
||||
|
||||
import org.junit.After;
|
||||
@@ -61,7 +62,8 @@ import java.util.List;
|
||||
* Run with <code>atest DeviceStateProviderImplTest</code>.
|
||||
*/
|
||||
public final class DeviceStateProviderImplTest {
|
||||
private final ArgumentCaptor<int[]> mIntArrayCaptor = ArgumentCaptor.forClass(int[].class);
|
||||
private final ArgumentCaptor<DeviceState[]> mDeviceStateArrayCaptor = ArgumentCaptor.forClass(
|
||||
DeviceState[].class);
|
||||
private final ArgumentCaptor<Integer> mIntegerCaptor = ArgumentCaptor.forClass(Integer.class);
|
||||
|
||||
private Context mContext;
|
||||
@@ -120,11 +122,12 @@ public final class DeviceStateProviderImplTest {
|
||||
DeviceStateProvider.Listener listener = mock(DeviceStateProvider.Listener.class);
|
||||
provider.setListener(listener);
|
||||
|
||||
verify(listener).onSupportedDeviceStatesChanged(mIntArrayCaptor.capture());
|
||||
assertArrayEquals(new int[] { DEFAULT_DEVICE_STATE }, mIntArrayCaptor.getValue());
|
||||
verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture());
|
||||
assertArrayEquals(new DeviceState[]{DEFAULT_DEVICE_STATE},
|
||||
mDeviceStateArrayCaptor.getValue());
|
||||
|
||||
verify(listener).onStateChanged(mIntegerCaptor.capture());
|
||||
assertEquals(DEFAULT_DEVICE_STATE, mIntegerCaptor.getValue().intValue());
|
||||
assertEquals(DEFAULT_DEVICE_STATE.getIdentifier(), mIntegerCaptor.getValue().intValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -146,8 +149,10 @@ public final class DeviceStateProviderImplTest {
|
||||
DeviceStateProvider.Listener listener = mock(DeviceStateProvider.Listener.class);
|
||||
provider.setListener(listener);
|
||||
|
||||
verify(listener).onSupportedDeviceStatesChanged(mIntArrayCaptor.capture());
|
||||
assertArrayEquals(new int[] { 1, 2 }, mIntArrayCaptor.getValue());
|
||||
verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture());
|
||||
final DeviceState[] expectedStates = new DeviceState[]{ new DeviceState(1, null),
|
||||
new DeviceState(2, null) };
|
||||
assertArrayEquals(expectedStates, mDeviceStateArrayCaptor.getValue());
|
||||
|
||||
verify(listener).onStateChanged(mIntegerCaptor.capture());
|
||||
assertEquals(1, mIntegerCaptor.getValue().intValue());
|
||||
@@ -166,6 +171,7 @@ public final class DeviceStateProviderImplTest {
|
||||
+ " </device-state>\n"
|
||||
+ " <device-state>\n"
|
||||
+ " <identifier>2</identifier>\n"
|
||||
+ " <name>CLOSED</name>\n"
|
||||
+ " <conditions>\n"
|
||||
+ " <lid-switch>\n"
|
||||
+ " <open>false</open>\n"
|
||||
@@ -180,8 +186,10 @@ public final class DeviceStateProviderImplTest {
|
||||
DeviceStateProvider.Listener listener = mock(DeviceStateProvider.Listener.class);
|
||||
provider.setListener(listener);
|
||||
|
||||
verify(listener).onSupportedDeviceStatesChanged(mIntArrayCaptor.capture());
|
||||
assertArrayEquals(new int[] { 1, 2 }, mIntArrayCaptor.getValue());
|
||||
verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture());
|
||||
final DeviceState[] expectedStates = new DeviceState[]{ new DeviceState(1, null),
|
||||
new DeviceState(2, "CLOSED") };
|
||||
assertArrayEquals(expectedStates, mDeviceStateArrayCaptor.getValue());
|
||||
|
||||
verify(listener).onStateChanged(mIntegerCaptor.capture());
|
||||
assertEquals(2, mIntegerCaptor.getValue().intValue());
|
||||
@@ -189,8 +197,7 @@ public final class DeviceStateProviderImplTest {
|
||||
Mockito.clearInvocations(listener);
|
||||
|
||||
provider.notifyLidSwitchChanged(0, true /* lidOpen */);
|
||||
|
||||
verify(listener, never()).onSupportedDeviceStatesChanged(mIntArrayCaptor.capture());
|
||||
verify(listener, never()).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture());
|
||||
verify(listener).onStateChanged(mIntegerCaptor.capture());
|
||||
assertEquals(1, mIntegerCaptor.getValue().intValue());
|
||||
}
|
||||
@@ -203,6 +210,7 @@ public final class DeviceStateProviderImplTest {
|
||||
String configString = "<device-state-config>\n"
|
||||
+ " <device-state>\n"
|
||||
+ " <identifier>1</identifier>\n"
|
||||
+ " <name>CLOSED</name>\n"
|
||||
+ " <conditions>\n"
|
||||
+ " <sensor>\n"
|
||||
+ " <type>" + sensor.getStringType() + "</type>\n"
|
||||
@@ -215,6 +223,7 @@ public final class DeviceStateProviderImplTest {
|
||||
+ " </device-state>\n"
|
||||
+ " <device-state>\n"
|
||||
+ " <identifier>2</identifier>\n"
|
||||
+ " <name>HALF_OPENED</name>\n"
|
||||
+ " <conditions>\n"
|
||||
+ " <sensor>\n"
|
||||
+ " <type>" + sensor.getStringType() + "</type>\n"
|
||||
@@ -228,6 +237,7 @@ public final class DeviceStateProviderImplTest {
|
||||
+ " </device-state>\n"
|
||||
+ " <device-state>\n"
|
||||
+ " <identifier>3</identifier>\n"
|
||||
+ " <name>OPENED</name>\n"
|
||||
+ " <conditions>\n"
|
||||
+ " <sensor>\n"
|
||||
+ " <type>" + sensor.getStringType() + "</type>\n"
|
||||
@@ -246,8 +256,10 @@ public final class DeviceStateProviderImplTest {
|
||||
DeviceStateProvider.Listener listener = mock(DeviceStateProvider.Listener.class);
|
||||
provider.setListener(listener);
|
||||
|
||||
verify(listener).onSupportedDeviceStatesChanged(mIntArrayCaptor.capture());
|
||||
assertArrayEquals(new int[] { 1, 2, 3 }, mIntArrayCaptor.getValue());
|
||||
verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture());
|
||||
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());
|
||||
@@ -256,11 +268,11 @@ public final class DeviceStateProviderImplTest {
|
||||
|
||||
SensorEvent event0 = mock(SensorEvent.class);
|
||||
event0.sensor = sensor;
|
||||
FieldSetter.setField(event0, event0.getClass().getField("values"), new float[] { 180 });
|
||||
FieldSetter.setField(event0, event0.getClass().getField("values"), new float[]{180});
|
||||
|
||||
provider.onSensorChanged(event0);
|
||||
|
||||
verify(listener, never()).onSupportedDeviceStatesChanged(mIntArrayCaptor.capture());
|
||||
verify(listener, never()).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture());
|
||||
verify(listener).onStateChanged(mIntegerCaptor.capture());
|
||||
assertEquals(3, mIntegerCaptor.getValue().intValue());
|
||||
|
||||
@@ -268,11 +280,11 @@ public final class DeviceStateProviderImplTest {
|
||||
|
||||
SensorEvent event1 = mock(SensorEvent.class);
|
||||
event1.sensor = sensor;
|
||||
FieldSetter.setField(event1, event1.getClass().getField("values"), new float[] { 90 });
|
||||
FieldSetter.setField(event1, event1.getClass().getField("values"), new float[]{90});
|
||||
|
||||
provider.onSensorChanged(event1);
|
||||
|
||||
verify(listener, never()).onSupportedDeviceStatesChanged(mIntArrayCaptor.capture());
|
||||
verify(listener, never()).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture());
|
||||
verify(listener).onStateChanged(mIntegerCaptor.capture());
|
||||
assertEquals(2, mIntegerCaptor.getValue().intValue());
|
||||
|
||||
@@ -280,11 +292,11 @@ public final class DeviceStateProviderImplTest {
|
||||
|
||||
SensorEvent event2 = mock(SensorEvent.class);
|
||||
event2.sensor = sensor;
|
||||
FieldSetter.setField(event2, event2.getClass().getField("values"), new float[] { 0 });
|
||||
FieldSetter.setField(event2, event2.getClass().getField("values"), new float[]{0});
|
||||
|
||||
provider.onSensorChanged(event2);
|
||||
|
||||
verify(listener, never()).onSupportedDeviceStatesChanged(mIntArrayCaptor.capture());
|
||||
verify(listener, never()).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture());
|
||||
verify(listener).onStateChanged(mIntegerCaptor.capture());
|
||||
assertEquals(1, mIntegerCaptor.getValue().intValue());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user