Makes it so changes to device state that have the FLAG_CANCEL_OVERRIDE_REQUESTS

flag cancels all override requests

Previously if a device state with the FLAG_CANCEL_STICKY_REQUESTS flag
was entered, it only cancelled requests that were made from a process
that was no longer alive. This was causing undesirable behavior where
a device state that should act as a reset state was not cancelling
override requests. This change makes it so if the device enters a
state that is defined as a reset state (has the
FLAG_CANCEL_OVERRIDE_REQUESTS on it) all the override requests are
cancelled. This change also changes the flag name to
FLAG_CANCEL_OVERRIDE_REQUESTS to be more correct and descriptive.

Bug: 207686851
Test: DeviceStateTest, DeviceStateProviderImplTest
Change-Id: I0af1d2917a3d422b5d05f0210d627454c23f9636
This commit is contained in:
Kenneth Ford
2021-12-21 23:08:49 +00:00
parent 0835d0140e
commit 34ac32953c
7 changed files with 52 additions and 15 deletions

View File

@@ -43,14 +43,14 @@ import java.util.Objects;
*/
public final class DeviceState {
/**
* Flag that indicates sticky requests should be cancelled when this device state becomes the
* Flag that indicates override requests should be cancelled when this device state becomes the
* base device state.
*/
public static final int FLAG_CANCEL_STICKY_REQUESTS = 1 << 0;
public static final int FLAG_CANCEL_OVERRIDE_REQUESTS = 1 << 0;
/** @hide */
@IntDef(prefix = {"FLAG_"}, flag = true, value = {
FLAG_CANCEL_STICKY_REQUESTS,
FLAG_CANCEL_OVERRIDE_REQUESTS,
})
@Retention(RetentionPolicy.SOURCE)
public @interface DeviceStateFlags {}
@@ -114,4 +114,10 @@ public final class DeviceState {
public int hashCode() {
return Objects.hash(mIdentifier, mName, mFlags);
}
/** Checks if a specific flag is set
*/
public boolean hasFlag(int flagToCheckFor) {
return (mFlags & flagToCheckFor) == flagToCheckFor;
}
}

View File

@@ -20,6 +20,7 @@ import static android.Manifest.permission.CONTROL_DEVICE_STATE;
import static android.hardware.devicestate.DeviceStateManager.MAXIMUM_DEVICE_STATE;
import static android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE;
import static com.android.server.devicestate.DeviceState.FLAG_CANCEL_OVERRIDE_REQUESTS;
import static com.android.server.devicestate.OverrideRequestController.STATUS_ACTIVE;
import static com.android.server.devicestate.OverrideRequestController.STATUS_CANCELED;
import static com.android.server.devicestate.OverrideRequestController.STATUS_SUSPENDED;
@@ -273,14 +274,14 @@ public final class DeviceStateManagerService extends SystemService {
synchronized (mLock) {
final int[] oldStateIdentifiers = getSupportedStateIdentifiersLocked();
// Whether or not at least one device state has the flag FLAG_CANCEL_STICKY_REQUESTS
// Whether or not at least one device state has the flag FLAG_CANCEL_OVERRIDE_REQUESTS
// set. If set to true, the OverrideRequestController will be configured to allow sticky
// requests.
boolean hasTerminalDeviceState = false;
mDeviceStates.clear();
for (int i = 0; i < supportedDeviceStates.length; i++) {
DeviceState state = supportedDeviceStates[i];
if ((state.getFlags() & DeviceState.FLAG_CANCEL_STICKY_REQUESTS) != 0) {
if (state.hasFlag(FLAG_CANCEL_OVERRIDE_REQUESTS)) {
hasTerminalDeviceState = true;
}
mDeviceStates.put(state.getIdentifier(), state);
@@ -345,8 +346,8 @@ public final class DeviceStateManagerService extends SystemService {
}
mBaseState = Optional.of(baseState);
if ((baseState.getFlags() & DeviceState.FLAG_CANCEL_STICKY_REQUESTS) != 0) {
mOverrideRequestController.cancelStickyRequests();
if (baseState.hasFlag(FLAG_CANCEL_OVERRIDE_REQUESTS)) {
mOverrideRequestController.cancelOverrideRequests();
}
mOverrideRequestController.handleBaseStateChanged();
updatePendingStateLocked();

View File

@@ -152,6 +152,16 @@ final class OverrideRequestController {
cancelRequestsLocked(mTmpRequestsToCancel);
}
/**
* Cancels all override requests, this could be due to the device being put
* into a hardware state that declares the flag "FLAG_CANCEL_OVERRIDE_REQUESTS"
*/
void cancelOverrideRequests() {
mTmpRequestsToCancel.clear();
mTmpRequestsToCancel.addAll(mRequests);
cancelRequestsLocked(mTmpRequestsToCancel);
}
/**
* Returns {@code true} if this controller is current managing a request with the specified
* {@code token}, {@code false} otherwise.

View File

@@ -94,6 +94,7 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider,
private static final String VENDOR_CONFIG_FILE_PATH = "etc/devicestate/";
private static final String DATA_CONFIG_FILE_PATH = "system/devicestate/";
private static final String CONFIG_FILE_NAME = "device_state_configuration.xml";
private static final String FLAG_CANCEL_OVERRIDE_REQUESTS = "FLAG_CANCEL_OVERRIDE_REQUESTS";
/** Interface that allows reading the device state configuration. */
interface ReadableConfig {
@@ -141,8 +142,8 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider,
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;
case FLAG_CANCEL_OVERRIDE_REQUESTS:
flags |= DeviceState.FLAG_CANCEL_OVERRIDE_REQUESTS;
break;
default:
Slog.w(TAG, "Parsed unknown flag with name: "

View File

@@ -41,10 +41,10 @@ public final class DeviceStateTest {
@Test
public void testConstruct() {
final DeviceState state = new DeviceState(MINIMUM_DEVICE_STATE /* identifier */,
"CLOSED" /* name */, DeviceState.FLAG_CANCEL_STICKY_REQUESTS /* flags */);
"TEST_CLOSED" /* name */, DeviceState.FLAG_CANCEL_OVERRIDE_REQUESTS /* flags */);
assertEquals(state.getIdentifier(), MINIMUM_DEVICE_STATE);
assertEquals(state.getName(), "CLOSED");
assertEquals(state.getFlags(), DeviceState.FLAG_CANCEL_STICKY_REQUESTS);
assertEquals(state.getName(), "TEST_CLOSED");
assertEquals(state.getFlags(), DeviceState.FLAG_CANCEL_OVERRIDE_REQUESTS);
}
@Test

View File

@@ -213,6 +213,25 @@ public final class OverrideRequestControllerTest {
assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_CANCELED);
}
@Test
public void cancelOverrideRequestsTest() {
OverrideRequest firstRequest = new OverrideRequest(new Binder(), 0 /* pid */,
1 /* requestedState */, 0 /* flags */);
OverrideRequest secondRequest = new OverrideRequest(new Binder(), 0 /* pid */,
2 /* requestedState */, 0 /* flags */);
mController.addRequest(firstRequest);
mController.addRequest(secondRequest);
assertEquals(mStatusListener.getLastStatus(secondRequest).intValue(), STATUS_ACTIVE);
assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_SUSPENDED);
mController.cancelOverrideRequests();
assertEquals(mStatusListener.getLastStatus(secondRequest).intValue(), STATUS_CANCELED);
assertEquals(mStatusListener.getLastStatus(firstRequest).intValue(), STATUS_CANCELED);
}
private static final class TestStatusChangeListener implements
OverrideRequestController.StatusChangeListener {
private Map<OverrideRequest, Integer> mLastStatusMap = new HashMap<>();

View File

@@ -160,12 +160,12 @@ public final class DeviceStateProviderImplTest {
}
@Test
public void create_stateWithCancelStickyRequestFlag() {
public void create_stateWithCancelOverrideRequestFlag() {
String configString = "<device-state-config>\n"
+ " <device-state>\n"
+ " <identifier>1</identifier>\n"
+ " <flags>\n"
+ " <flag>FLAG_CANCEL_STICKY_REQUESTS</flag>\n"
+ " <flag>FLAG_CANCEL_OVERRIDE_REQUESTS</flag>\n"
+ " </flags>\n"
+ " <conditions/>\n"
+ " </device-state>\n"
@@ -183,7 +183,7 @@ public final class DeviceStateProviderImplTest {
verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture());
final DeviceState[] expectedStates = new DeviceState[]{
new DeviceState(1, "", DeviceState.FLAG_CANCEL_STICKY_REQUESTS),
new DeviceState(1, "", DeviceState.FLAG_CANCEL_OVERRIDE_REQUESTS),
new DeviceState(2, "", 0 /* flags */) };
assertArrayEquals(expectedStates, mDeviceStateArrayCaptor.getValue());
}