Allow override requests to outlive the requesting process. am: 7dde391fc1
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15377221 Change-Id: I828547ba4716ebdc0a1190423538887f839b279d
This commit is contained in:
@@ -75,13 +75,13 @@ public final class DeviceStateManager {
|
|||||||
/**
|
/**
|
||||||
* Submits a {@link DeviceStateRequest request} to modify the device state.
|
* Submits a {@link DeviceStateRequest request} to modify the device state.
|
||||||
* <p>
|
* <p>
|
||||||
* By default, the request is kept active until a call to
|
* By default, the request is kept active until one of the following occurs:
|
||||||
* {@link #cancelRequest(DeviceStateRequest)} or until one of the following occurs:
|
|
||||||
* <ul>
|
* <ul>
|
||||||
|
* <li>The system deems the request can no longer be honored, for example if the requested
|
||||||
|
* state becomes unsupported.
|
||||||
|
* <li>A call to {@link #cancelRequest(DeviceStateRequest)}.
|
||||||
* <li>Another processes submits a request succeeding this request in which case the request
|
* <li>Another processes submits a request succeeding this request in which case the request
|
||||||
* will be suspended until the interrupting request is canceled.
|
* will be suspended until the interrupting request is canceled.
|
||||||
* <li>The requested state has become unsupported.
|
|
||||||
* <li>The process submitting the request dies.
|
|
||||||
* </ul>
|
* </ul>
|
||||||
* However, this behavior can be changed by setting flags on the {@link DeviceStateRequest}.
|
* However, this behavior can be changed by setting flags on the {@link DeviceStateRequest}.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -19,11 +19,14 @@ package com.android.server.devicestate;
|
|||||||
import static android.hardware.devicestate.DeviceStateManager.MAXIMUM_DEVICE_STATE;
|
import static android.hardware.devicestate.DeviceStateManager.MAXIMUM_DEVICE_STATE;
|
||||||
import static android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE;
|
import static android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE;
|
||||||
|
|
||||||
|
import android.annotation.IntDef;
|
||||||
import android.annotation.IntRange;
|
import android.annotation.IntRange;
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
|
|
||||||
import com.android.internal.util.Preconditions;
|
import com.android.internal.util.Preconditions;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -39,6 +42,19 @@ import java.util.Objects;
|
|||||||
* @see DeviceStateManagerService
|
* @see DeviceStateManagerService
|
||||||
*/
|
*/
|
||||||
public final class DeviceState {
|
public final class DeviceState {
|
||||||
|
/**
|
||||||
|
* Flag that indicates sticky requests should be cancelled when this device state becomes the
|
||||||
|
* base device state.
|
||||||
|
*/
|
||||||
|
public static final int FLAG_CANCEL_STICKY_REQUESTS = 1 << 0;
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
|
@IntDef(prefix = {"FLAG_"}, flag = true, value = {
|
||||||
|
FLAG_CANCEL_STICKY_REQUESTS,
|
||||||
|
})
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
public @interface DeviceStateFlags {}
|
||||||
|
|
||||||
/** Unique identifier for the device state. */
|
/** Unique identifier for the device state. */
|
||||||
@IntRange(from = MINIMUM_DEVICE_STATE, to = MAXIMUM_DEVICE_STATE)
|
@IntRange(from = MINIMUM_DEVICE_STATE, to = MAXIMUM_DEVICE_STATE)
|
||||||
private final int mIdentifier;
|
private final int mIdentifier;
|
||||||
@@ -47,14 +63,19 @@ public final class DeviceState {
|
|||||||
@NonNull
|
@NonNull
|
||||||
private final String mName;
|
private final String mName;
|
||||||
|
|
||||||
|
@DeviceStateFlags
|
||||||
|
private final int mFlags;
|
||||||
|
|
||||||
public DeviceState(
|
public DeviceState(
|
||||||
@IntRange(from = MINIMUM_DEVICE_STATE, to = MAXIMUM_DEVICE_STATE) int identifier,
|
@IntRange(from = MINIMUM_DEVICE_STATE, to = MAXIMUM_DEVICE_STATE) int identifier,
|
||||||
@NonNull String name) {
|
@NonNull String name,
|
||||||
|
@DeviceStateFlags int flags) {
|
||||||
Preconditions.checkArgumentInRange(identifier, MINIMUM_DEVICE_STATE, MAXIMUM_DEVICE_STATE,
|
Preconditions.checkArgumentInRange(identifier, MINIMUM_DEVICE_STATE, MAXIMUM_DEVICE_STATE,
|
||||||
"identifier");
|
"identifier");
|
||||||
|
|
||||||
mIdentifier = identifier;
|
mIdentifier = identifier;
|
||||||
mName = name;
|
mName = name;
|
||||||
|
mFlags = flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the unique identifier for the device state. */
|
/** Returns the unique identifier for the device state. */
|
||||||
@@ -69,6 +90,11 @@ public final class DeviceState {
|
|||||||
return mName;
|
return mName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@DeviceStateFlags
|
||||||
|
public int getFlags() {
|
||||||
|
return mFlags;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "DeviceState{" + "identifier=" + mIdentifier + ", name='" + mName + '\'' + '}';
|
return "DeviceState{" + "identifier=" + mIdentifier + ", name='" + mName + '\'' + '}';
|
||||||
@@ -80,11 +106,12 @@ public final class DeviceState {
|
|||||||
if (o == null || getClass() != o.getClass()) return false;
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
DeviceState that = (DeviceState) o;
|
DeviceState that = (DeviceState) o;
|
||||||
return mIdentifier == that.mIdentifier
|
return mIdentifier == that.mIdentifier
|
||||||
&& Objects.equals(mName, that.mName);
|
&& Objects.equals(mName, that.mName)
|
||||||
|
&& mFlags == that.mFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return Objects.hash(mIdentifier, mName);
|
return Objects.hash(mIdentifier, mName, mFlags);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -275,12 +275,21 @@ public final class DeviceStateManagerService extends SystemService {
|
|||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
final int[] oldStateIdentifiers = getSupportedStateIdentifiersLocked();
|
final int[] oldStateIdentifiers = getSupportedStateIdentifiersLocked();
|
||||||
|
|
||||||
|
// Whether or not at least one device state has the flag FLAG_CANCEL_STICKY_REQUESTS
|
||||||
|
// set. If set to true, the OverrideRequestController will be configured to allow sticky
|
||||||
|
// requests.
|
||||||
|
boolean hasTerminalDeviceState = false;
|
||||||
mDeviceStates.clear();
|
mDeviceStates.clear();
|
||||||
for (int i = 0; i < supportedDeviceStates.length; i++) {
|
for (int i = 0; i < supportedDeviceStates.length; i++) {
|
||||||
DeviceState state = supportedDeviceStates[i];
|
DeviceState state = supportedDeviceStates[i];
|
||||||
|
if ((state.getFlags() & DeviceState.FLAG_CANCEL_STICKY_REQUESTS) != 0) {
|
||||||
|
hasTerminalDeviceState = true;
|
||||||
|
}
|
||||||
mDeviceStates.put(state.getIdentifier(), state);
|
mDeviceStates.put(state.getIdentifier(), state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mOverrideRequestController.setStickyRequestsAllowed(hasTerminalDeviceState);
|
||||||
|
|
||||||
final int[] newStateIdentifiers = getSupportedStateIdentifiersLocked();
|
final int[] newStateIdentifiers = getSupportedStateIdentifiersLocked();
|
||||||
if (Arrays.equals(oldStateIdentifiers, newStateIdentifiers)) {
|
if (Arrays.equals(oldStateIdentifiers, newStateIdentifiers)) {
|
||||||
return;
|
return;
|
||||||
@@ -338,6 +347,9 @@ public final class DeviceStateManagerService extends SystemService {
|
|||||||
}
|
}
|
||||||
mBaseState = Optional.of(baseState);
|
mBaseState = Optional.of(baseState);
|
||||||
|
|
||||||
|
if ((baseState.getFlags() & DeviceState.FLAG_CANCEL_STICKY_REQUESTS) != 0) {
|
||||||
|
mOverrideRequestController.cancelStickyRequests();
|
||||||
|
}
|
||||||
mOverrideRequestController.handleBaseStateChanged();
|
mOverrideRequestController.handleBaseStateChanged();
|
||||||
updatePendingStateLocked();
|
updatePendingStateLocked();
|
||||||
|
|
||||||
|
|||||||
@@ -84,10 +84,28 @@ final class OverrideRequestController {
|
|||||||
// List of override requests with the most recent override request at the end.
|
// List of override requests with the most recent override request at the end.
|
||||||
private final ArrayList<OverrideRequest> mRequests = new ArrayList<>();
|
private final ArrayList<OverrideRequest> mRequests = new ArrayList<>();
|
||||||
|
|
||||||
|
private boolean mStickyRequestsAllowed;
|
||||||
|
// List of override requests that have outlived their process and will only be cancelled through
|
||||||
|
// a call to cancelStickyRequests().
|
||||||
|
private final ArrayList<OverrideRequest> mStickyRequests = new ArrayList<>();
|
||||||
|
|
||||||
OverrideRequestController(@NonNull StatusChangeListener listener) {
|
OverrideRequestController(@NonNull StatusChangeListener listener) {
|
||||||
mListener = listener;
|
mListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets sticky requests as either allowed or disallowed. When sticky requests are allowed a call
|
||||||
|
* to {@link #handleProcessDied(int)} will not result in the request being cancelled
|
||||||
|
* immediately. Instead, the request will be marked sticky and must be cancelled with a call
|
||||||
|
* to {@link #cancelStickyRequests()}.
|
||||||
|
*/
|
||||||
|
void setStickyRequestsAllowed(boolean stickyRequestsAllowed) {
|
||||||
|
mStickyRequestsAllowed = stickyRequestsAllowed;
|
||||||
|
if (!mStickyRequestsAllowed) {
|
||||||
|
cancelStickyRequests();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a request to the top of the stack and notifies the listener of all changes to request
|
* Adds a request to the top of the stack and notifies the listener of all changes to request
|
||||||
* status as a result of this operation.
|
* status as a result of this operation.
|
||||||
@@ -122,6 +140,18 @@ final class OverrideRequestController {
|
|||||||
mListener.onStatusChanged(request, STATUS_CANCELED);
|
mListener.onStatusChanged(request, STATUS_CANCELED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancels all requests that are currently marked sticky and notifies the listener of all
|
||||||
|
* changes to request status as a result of this operation.
|
||||||
|
*
|
||||||
|
* @see #setStickyRequestsAllowed(boolean)
|
||||||
|
*/
|
||||||
|
void cancelStickyRequests() {
|
||||||
|
mTmpRequestsToCancel.clear();
|
||||||
|
mTmpRequestsToCancel.addAll(mStickyRequests);
|
||||||
|
cancelRequestsLocked(mTmpRequestsToCancel);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns {@code true} if this controller is current managing a request with the specified
|
* Returns {@code true} if this controller is current managing a request with the specified
|
||||||
* {@code token}, {@code false} otherwise.
|
* {@code token}, {@code false} otherwise.
|
||||||
@@ -140,6 +170,7 @@ final class OverrideRequestController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mTmpRequestsToCancel.clear();
|
||||||
OverrideRequest prevActiveRequest = getLast(mRequests);
|
OverrideRequest prevActiveRequest = getLast(mRequests);
|
||||||
for (OverrideRequest request : mRequests) {
|
for (OverrideRequest request : mRequests) {
|
||||||
if (request.getPid() == pid) {
|
if (request.getPid() == pid) {
|
||||||
@@ -147,18 +178,14 @@ final class OverrideRequestController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mRequests.removeAll(mTmpRequestsToCancel);
|
if (mStickyRequestsAllowed) {
|
||||||
if (!mRequests.isEmpty()) {
|
// Do not cancel the requests now because sticky requests are allowed. These
|
||||||
OverrideRequest newActiveRequest = getLast(mRequests);
|
// requests will be cancelled on a call to cancelStickyRequests().
|
||||||
if (newActiveRequest != prevActiveRequest) {
|
mStickyRequests.addAll(mTmpRequestsToCancel);
|
||||||
mListener.onStatusChanged(newActiveRequest, STATUS_ACTIVE);
|
return;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < mTmpRequestsToCancel.size(); i++) {
|
cancelRequestsLocked(mTmpRequestsToCancel);
|
||||||
mListener.onStatusChanged(mTmpRequestsToCancel.get(i), STATUS_CANCELED);
|
|
||||||
}
|
|
||||||
mTmpRequestsToCancel.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -173,6 +200,7 @@ final class OverrideRequestController {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mTmpRequestsToCancel.clear();
|
||||||
OverrideRequest prevActiveRequest = getLast(mRequests);
|
OverrideRequest prevActiveRequest = getLast(mRequests);
|
||||||
for (int i = 0; i < mRequests.size(); i++) {
|
for (int i = 0; i < mRequests.size(); i++) {
|
||||||
OverrideRequest request = mRequests.get(i);
|
OverrideRequest request = mRequests.get(i);
|
||||||
@@ -181,21 +209,8 @@ final class OverrideRequestController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mRequests.removeAll(mTmpRequestsToCancel);
|
final boolean newActiveRequest = cancelRequestsLocked(mTmpRequestsToCancel);
|
||||||
OverrideRequest newActiveRequest = null;
|
return newActiveRequest;
|
||||||
if (!mRequests.isEmpty()) {
|
|
||||||
newActiveRequest = getLast(mRequests);
|
|
||||||
if (newActiveRequest != prevActiveRequest) {
|
|
||||||
mListener.onStatusChanged(newActiveRequest, STATUS_ACTIVE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < mTmpRequestsToCancel.size(); i++) {
|
|
||||||
mListener.onStatusChanged(mTmpRequestsToCancel.get(i), STATUS_CANCELED);
|
|
||||||
}
|
|
||||||
mTmpRequestsToCancel.clear();
|
|
||||||
|
|
||||||
return newActiveRequest != prevActiveRequest;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -210,7 +225,7 @@ final class OverrideRequestController {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
OverrideRequest prevActiveRequest = getLast(mRequests);
|
mTmpRequestsToCancel.clear();
|
||||||
for (int i = 0; i < mRequests.size(); i++) {
|
for (int i = 0; i < mRequests.size(); i++) {
|
||||||
OverrideRequest request = mRequests.get(i);
|
OverrideRequest request = mRequests.get(i);
|
||||||
if (!contains(newSupportedStates, request.getRequestedState())) {
|
if (!contains(newSupportedStates, request.getRequestedState())) {
|
||||||
@@ -218,21 +233,8 @@ final class OverrideRequestController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mRequests.removeAll(mTmpRequestsToCancel);
|
final boolean newActiveRequest = cancelRequestsLocked(mTmpRequestsToCancel);
|
||||||
OverrideRequest newActiveRequest = null;
|
return newActiveRequest;
|
||||||
if (!mRequests.isEmpty()) {
|
|
||||||
newActiveRequest = getLast(mRequests);
|
|
||||||
if (newActiveRequest != prevActiveRequest) {
|
|
||||||
mListener.onStatusChanged(newActiveRequest, STATUS_ACTIVE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < mTmpRequestsToCancel.size(); i++) {
|
|
||||||
mListener.onStatusChanged(mTmpRequestsToCancel.get(i), STATUS_CANCELED);
|
|
||||||
}
|
|
||||||
mTmpRequestsToCancel.clear();
|
|
||||||
|
|
||||||
return newActiveRequest != prevActiveRequest;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void dumpInternal(PrintWriter pw) {
|
void dumpInternal(PrintWriter pw) {
|
||||||
@@ -249,6 +251,36 @@ final class OverrideRequestController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles cancelling a set of requests. If the set of requests to cancel will lead to a new
|
||||||
|
* request becoming active this request will also be notified of its change in state.
|
||||||
|
*
|
||||||
|
* @return {@code true} if calling this method has lead to a new active request, {@code false}
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
private boolean cancelRequestsLocked(List<OverrideRequest> requestsToCancel) {
|
||||||
|
if (requestsToCancel.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
OverrideRequest prevActiveRequest = getLast(mRequests);
|
||||||
|
boolean causedNewRequestToBecomeActive = false;
|
||||||
|
mRequests.removeAll(requestsToCancel);
|
||||||
|
mStickyRequests.removeAll(requestsToCancel);
|
||||||
|
if (!mRequests.isEmpty()) {
|
||||||
|
OverrideRequest newActiveRequest = getLast(mRequests);
|
||||||
|
if (newActiveRequest != prevActiveRequest) {
|
||||||
|
mListener.onStatusChanged(newActiveRequest, STATUS_ACTIVE);
|
||||||
|
causedNewRequestToBecomeActive = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < requestsToCancel.size(); i++) {
|
||||||
|
mListener.onStatusChanged(requestsToCancel.get(i), STATUS_CANCELED);
|
||||||
|
}
|
||||||
|
return causedNewRequestToBecomeActive;
|
||||||
|
}
|
||||||
|
|
||||||
private int getRequestIndex(@NonNull IBinder token) {
|
private int getRequestIndex(@NonNull IBinder token) {
|
||||||
final int numberOfRequests = mRequests.size();
|
final int numberOfRequests = mRequests.size();
|
||||||
if (numberOfRequests == 0) {
|
if (numberOfRequests == 0) {
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ import com.android.server.devicestate.DeviceState;
|
|||||||
import com.android.server.devicestate.DeviceStateProvider;
|
import com.android.server.devicestate.DeviceStateProvider;
|
||||||
import com.android.server.policy.devicestate.config.Conditions;
|
import com.android.server.policy.devicestate.config.Conditions;
|
||||||
import com.android.server.policy.devicestate.config.DeviceStateConfig;
|
import com.android.server.policy.devicestate.config.DeviceStateConfig;
|
||||||
|
import com.android.server.policy.devicestate.config.Flags;
|
||||||
import com.android.server.policy.devicestate.config.LidSwitchCondition;
|
import com.android.server.policy.devicestate.config.LidSwitchCondition;
|
||||||
import com.android.server.policy.devicestate.config.NumericRange;
|
import com.android.server.policy.devicestate.config.NumericRange;
|
||||||
import com.android.server.policy.devicestate.config.SensorCondition;
|
import com.android.server.policy.devicestate.config.SensorCondition;
|
||||||
@@ -87,7 +88,7 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider,
|
|||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final DeviceState DEFAULT_DEVICE_STATE = new DeviceState(MINIMUM_DEVICE_STATE,
|
static final DeviceState DEFAULT_DEVICE_STATE = new DeviceState(MINIMUM_DEVICE_STATE,
|
||||||
"DEFAULT");
|
"DEFAULT", 0 /* flags */);
|
||||||
|
|
||||||
private static final String VENDOR_CONFIG_FILE_PATH = "etc/devicestate/";
|
private static final String VENDOR_CONFIG_FILE_PATH = "etc/devicestate/";
|
||||||
private static final String DATA_CONFIG_FILE_PATH = "system/devicestate/";
|
private static final String DATA_CONFIG_FILE_PATH = "system/devicestate/";
|
||||||
@@ -131,7 +132,26 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider,
|
|||||||
config.getDeviceState()) {
|
config.getDeviceState()) {
|
||||||
final int state = stateConfig.getIdentifier().intValue();
|
final int state = stateConfig.getIdentifier().intValue();
|
||||||
final String name = stateConfig.getName() == null ? "" : stateConfig.getName();
|
final String name = stateConfig.getName() == null ? "" : stateConfig.getName();
|
||||||
deviceStateList.add(new DeviceState(state, name));
|
|
||||||
|
int flags = 0;
|
||||||
|
final Flags configFlags = stateConfig.getFlags();
|
||||||
|
if (configFlags != null) {
|
||||||
|
List<String> configFlagStrings = configFlags.getFlag();
|
||||||
|
for (int i = 0; i < configFlagStrings.size(); i++) {
|
||||||
|
final String configFlagString = configFlagStrings.get(i);
|
||||||
|
switch (configFlagString) {
|
||||||
|
case "FLAG_CANCEL_STICKY_REQUESTS":
|
||||||
|
flags |= DeviceState.FLAG_CANCEL_STICKY_REQUESTS;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
Slog.w(TAG, "Parsed unknown flag with name: "
|
||||||
|
+ configFlagString);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
deviceStateList.add(new DeviceState(state, name, flags));
|
||||||
|
|
||||||
final Conditions condition = stateConfig.getConditions();
|
final Conditions condition = stateConfig.getConditions();
|
||||||
conditionsList.add(condition);
|
conditionsList.add(condition);
|
||||||
|
|||||||
@@ -40,10 +40,19 @@
|
|||||||
<xs:element name="name" type="xs:string" minOccurs="0">
|
<xs:element name="name" type="xs:string" minOccurs="0">
|
||||||
<xs:annotation name="nullable" />
|
<xs:annotation name="nullable" />
|
||||||
</xs:element>
|
</xs:element>
|
||||||
|
<xs:element name="flags" type="flags" />
|
||||||
<xs:element name="conditions" type="conditions" />
|
<xs:element name="conditions" type="conditions" />
|
||||||
</xs:sequence>
|
</xs:sequence>
|
||||||
</xs:complexType>
|
</xs:complexType>
|
||||||
|
|
||||||
|
<xs:complexType name="flags">
|
||||||
|
<xs:sequence>
|
||||||
|
<xs:element name="flag" type="xs:string" minOccurs="0" maxOccurs="unbounded">
|
||||||
|
<xs:annotation name="nullable" />
|
||||||
|
</xs:element>
|
||||||
|
</xs:sequence>
|
||||||
|
</xs:complexType>
|
||||||
|
|
||||||
<xs:complexType name="conditions">
|
<xs:complexType name="conditions">
|
||||||
<xs:sequence>
|
<xs:sequence>
|
||||||
<xs:element name="lid-switch" type="lidSwitchCondition" minOccurs="0">
|
<xs:element name="lid-switch" type="lidSwitchCondition" minOccurs="0">
|
||||||
|
|||||||
@@ -11,9 +11,11 @@ package com.android.server.policy.devicestate.config {
|
|||||||
public class DeviceState {
|
public class DeviceState {
|
||||||
ctor public DeviceState();
|
ctor public DeviceState();
|
||||||
method public com.android.server.policy.devicestate.config.Conditions getConditions();
|
method public com.android.server.policy.devicestate.config.Conditions getConditions();
|
||||||
|
method public com.android.server.policy.devicestate.config.Flags getFlags();
|
||||||
method public java.math.BigInteger getIdentifier();
|
method public java.math.BigInteger getIdentifier();
|
||||||
method @Nullable public String getName();
|
method @Nullable public String getName();
|
||||||
method public void setConditions(com.android.server.policy.devicestate.config.Conditions);
|
method public void setConditions(com.android.server.policy.devicestate.config.Conditions);
|
||||||
|
method public void setFlags(com.android.server.policy.devicestate.config.Flags);
|
||||||
method public void setIdentifier(java.math.BigInteger);
|
method public void setIdentifier(java.math.BigInteger);
|
||||||
method public void setName(@Nullable String);
|
method public void setName(@Nullable String);
|
||||||
}
|
}
|
||||||
@@ -23,6 +25,11 @@ package com.android.server.policy.devicestate.config {
|
|||||||
method public java.util.List<com.android.server.policy.devicestate.config.DeviceState> getDeviceState();
|
method public java.util.List<com.android.server.policy.devicestate.config.DeviceState> getDeviceState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class Flags {
|
||||||
|
ctor public Flags();
|
||||||
|
method @Nullable public java.util.List<java.lang.String> getFlag();
|
||||||
|
}
|
||||||
|
|
||||||
public class LidSwitchCondition {
|
public class LidSwitchCondition {
|
||||||
ctor public LidSwitchCondition();
|
ctor public LidSwitchCondition();
|
||||||
method public boolean getOpen();
|
method public boolean getOpen();
|
||||||
|
|||||||
@@ -55,10 +55,13 @@ import javax.annotation.Nullable;
|
|||||||
@Presubmit
|
@Presubmit
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(AndroidJUnit4.class)
|
||||||
public final class DeviceStateManagerServiceTest {
|
public final class DeviceStateManagerServiceTest {
|
||||||
private static final DeviceState DEFAULT_DEVICE_STATE = new DeviceState(0, "DEFAULT");
|
private static final DeviceState DEFAULT_DEVICE_STATE =
|
||||||
private static final DeviceState OTHER_DEVICE_STATE = new DeviceState(1, "OTHER");
|
new DeviceState(0, "DEFAULT", 0 /* flags */);
|
||||||
|
private static final DeviceState OTHER_DEVICE_STATE =
|
||||||
|
new DeviceState(1, "OTHER", 0 /* flags */);
|
||||||
// A device state that is not reported as being supported for the default test provider.
|
// A device state that is not reported as being supported for the default test provider.
|
||||||
private static final DeviceState UNSUPPORTED_DEVICE_STATE = new DeviceState(255, "UNSUPPORTED");
|
private static final DeviceState UNSUPPORTED_DEVICE_STATE =
|
||||||
|
new DeviceState(255, "UNSUPPORTED", 0 /* flags */);
|
||||||
|
|
||||||
private TestDeviceStatePolicy mPolicy;
|
private TestDeviceStatePolicy mPolicy;
|
||||||
private TestDeviceStateProvider mProvider;
|
private TestDeviceStateProvider mProvider;
|
||||||
|
|||||||
@@ -41,24 +41,26 @@ public final class DeviceStateTest {
|
|||||||
@Test
|
@Test
|
||||||
public void testConstruct() {
|
public void testConstruct() {
|
||||||
final DeviceState state = new DeviceState(MINIMUM_DEVICE_STATE /* identifier */,
|
final DeviceState state = new DeviceState(MINIMUM_DEVICE_STATE /* identifier */,
|
||||||
"CLOSED" /* name */);
|
"CLOSED" /* name */, DeviceState.FLAG_CANCEL_STICKY_REQUESTS /* flags */);
|
||||||
assertEquals(state.getIdentifier(), MINIMUM_DEVICE_STATE);
|
assertEquals(state.getIdentifier(), MINIMUM_DEVICE_STATE);
|
||||||
assertEquals(state.getName(), "CLOSED");
|
assertEquals(state.getName(), "CLOSED");
|
||||||
|
assertEquals(state.getFlags(), DeviceState.FLAG_CANCEL_STICKY_REQUESTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConstruct_nullName() {
|
public void testConstruct_nullName() {
|
||||||
final DeviceState state = new DeviceState(MAXIMUM_DEVICE_STATE /* identifier */,
|
final DeviceState state = new DeviceState(MAXIMUM_DEVICE_STATE /* identifier */,
|
||||||
null /* name */);
|
null /* name */, 0/* flags */);
|
||||||
assertEquals(state.getIdentifier(), MAXIMUM_DEVICE_STATE);
|
assertEquals(state.getIdentifier(), MAXIMUM_DEVICE_STATE);
|
||||||
assertNull(state.getName());
|
assertNull(state.getName());
|
||||||
|
assertEquals(state.getFlags(), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConstruct_tooLargeIdentifier() {
|
public void testConstruct_tooLargeIdentifier() {
|
||||||
assertThrows(IllegalArgumentException.class, () -> {
|
assertThrows(IllegalArgumentException.class, () -> {
|
||||||
final DeviceState state = new DeviceState(MAXIMUM_DEVICE_STATE + 1 /* identifier */,
|
final DeviceState state = new DeviceState(MAXIMUM_DEVICE_STATE + 1 /* identifier */,
|
||||||
null /* name */);
|
null /* name */, 0 /* flags */);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -66,7 +68,7 @@ public final class DeviceStateTest {
|
|||||||
public void testConstruct_tooSmallIdentifier() {
|
public void testConstruct_tooSmallIdentifier() {
|
||||||
assertThrows(IllegalArgumentException.class, () -> {
|
assertThrows(IllegalArgumentException.class, () -> {
|
||||||
final DeviceState state = new DeviceState(MINIMUM_DEVICE_STATE - 1 /* identifier */,
|
final DeviceState state = new DeviceState(MINIMUM_DEVICE_STATE - 1 /* identifier */,
|
||||||
null /* name */);
|
null /* name */, 0 /* flags */);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -164,6 +164,32 @@ public final class OverrideRequestControllerTest {
|
|||||||
assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_CANCELED);
|
assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_CANCELED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void handleProcessDied_stickyRequests() {
|
||||||
|
mController.setStickyRequestsAllowed(true);
|
||||||
|
|
||||||
|
OverrideRequest firstRequest = new OverrideRequest(new Binder(), 0 /* pid */,
|
||||||
|
0 /* requestedState */, 0 /* flags */);
|
||||||
|
OverrideRequest secondRequest = new OverrideRequest(new Binder(), 1 /* pid */,
|
||||||
|
0 /* requestedState */, 0 /* flags */);
|
||||||
|
|
||||||
|
mController.addRequest(firstRequest);
|
||||||
|
mController.addRequest(secondRequest);
|
||||||
|
|
||||||
|
assertEquals(mStatusListener.getLastStatus(secondRequest).intValue(), STATUS_ACTIVE);
|
||||||
|
assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_SUSPENDED);
|
||||||
|
|
||||||
|
mController.handleProcessDied(1);
|
||||||
|
|
||||||
|
assertEquals(mStatusListener.getLastStatus(secondRequest).intValue(), STATUS_ACTIVE);
|
||||||
|
assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_SUSPENDED);
|
||||||
|
|
||||||
|
mController.cancelStickyRequests();
|
||||||
|
|
||||||
|
assertEquals(mStatusListener.getLastStatus(secondRequest).intValue(), STATUS_CANCELED);
|
||||||
|
assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_ACTIVE);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void handleNewSupportedStates() {
|
public void handleNewSupportedStates() {
|
||||||
OverrideRequest firstRequest = new OverrideRequest(new Binder(), 0 /* pid */,
|
OverrideRequest firstRequest = new OverrideRequest(new Binder(), 0 /* pid */,
|
||||||
|
|||||||
@@ -150,8 +150,9 @@ public final class DeviceStateProviderImplTest {
|
|||||||
provider.setListener(listener);
|
provider.setListener(listener);
|
||||||
|
|
||||||
verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture());
|
verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture());
|
||||||
final DeviceState[] expectedStates = new DeviceState[]{ new DeviceState(1, ""),
|
final DeviceState[] expectedStates = new DeviceState[]{
|
||||||
new DeviceState(2, "") };
|
new DeviceState(1, "", 0 /* flags */),
|
||||||
|
new DeviceState(2, "", 0 /* flags */) };
|
||||||
assertArrayEquals(expectedStates, mDeviceStateArrayCaptor.getValue());
|
assertArrayEquals(expectedStates, mDeviceStateArrayCaptor.getValue());
|
||||||
|
|
||||||
verify(listener).onStateChanged(mIntegerCaptor.capture());
|
verify(listener).onStateChanged(mIntegerCaptor.capture());
|
||||||
@@ -187,8 +188,9 @@ public final class DeviceStateProviderImplTest {
|
|||||||
provider.setListener(listener);
|
provider.setListener(listener);
|
||||||
|
|
||||||
verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture());
|
verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture());
|
||||||
final DeviceState[] expectedStates = new DeviceState[]{ new DeviceState(1, ""),
|
final DeviceState[] expectedStates = new DeviceState[]{
|
||||||
new DeviceState(2, "CLOSED") };
|
new DeviceState(1, "", 0 /* flags */),
|
||||||
|
new DeviceState(2, "CLOSED", 0 /* flags */) };
|
||||||
assertArrayEquals(expectedStates, mDeviceStateArrayCaptor.getValue());
|
assertArrayEquals(expectedStates, mDeviceStateArrayCaptor.getValue());
|
||||||
|
|
||||||
// onStateChanged() should not be called because the provider has not yet been notified of
|
// onStateChanged() should not be called because the provider has not yet been notified of
|
||||||
@@ -264,8 +266,11 @@ public final class DeviceStateProviderImplTest {
|
|||||||
|
|
||||||
verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture());
|
verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture());
|
||||||
assertArrayEquals(
|
assertArrayEquals(
|
||||||
new DeviceState[]{ new DeviceState(1, "CLOSED"), new DeviceState(2, "HALF_OPENED"),
|
new DeviceState[]{
|
||||||
new DeviceState(3, "OPENED") }, mDeviceStateArrayCaptor.getValue());
|
new DeviceState(1, "CLOSED", 0 /* flags */),
|
||||||
|
new DeviceState(2, "HALF_OPENED", 0 /* flags */),
|
||||||
|
new DeviceState(3, "OPENED", 0 /* flags */) },
|
||||||
|
mDeviceStateArrayCaptor.getValue());
|
||||||
// onStateChanged() should not be called because the provider has not yet been notified of
|
// onStateChanged() should not be called because the provider has not yet been notified of
|
||||||
// the initial sensor state.
|
// the initial sensor state.
|
||||||
verify(listener, never()).onStateChanged(mIntegerCaptor.capture());
|
verify(listener, never()).onStateChanged(mIntegerCaptor.capture());
|
||||||
@@ -350,8 +355,10 @@ public final class DeviceStateProviderImplTest {
|
|||||||
|
|
||||||
verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture());
|
verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture());
|
||||||
assertArrayEquals(
|
assertArrayEquals(
|
||||||
new DeviceState[]{ new DeviceState(1, "CLOSED"), new DeviceState(2, "HALF_OPENED"),
|
new DeviceState[]{
|
||||||
}, mDeviceStateArrayCaptor.getValue());
|
new DeviceState(1, "CLOSED", 0 /* flags */),
|
||||||
|
new DeviceState(2, "HALF_OPENED", 0 /* flags */)
|
||||||
|
}, mDeviceStateArrayCaptor.getValue());
|
||||||
// onStateChanged() should be called because the provider could not find the sensor.
|
// onStateChanged() should be called because the provider could not find the sensor.
|
||||||
verify(listener).onStateChanged(mIntegerCaptor.capture());
|
verify(listener).onStateChanged(mIntegerCaptor.capture());
|
||||||
assertEquals(1, mIntegerCaptor.getValue().intValue());
|
assertEquals(1, mIntegerCaptor.getValue().intValue());
|
||||||
|
|||||||
Reference in New Issue
Block a user