Add MAX/MIN_DEVICE_STATE constants to restrict possible states to range.

This adds a MAXIMUM_DEVICE_STATE and MINIMUM_DEVICE_STATE constant to
DeviceStateManager that contains the max allowed device state indentifier
which reserves any larger values for future defined constants in the
platform. The constant will be used by CTS to validate that the set
of supported states is in the range
[MINIMUM_DEVICE_STATE, MAXIMUM_DEVICE_STATE].

The values match the max allowed value returned by the default provider
impl which is defined in the XSD schema.

Bug: 159401801
Bug: 177235528
Test: atest DeviceStateTest
Change-Id: Ia5a8e2841bac19d36e9d6cd00950d09628a7f719
This commit is contained in:
Darryl L Johnson
2021-02-03 09:51:33 -08:00
parent 8dcb37ccc1
commit 836dc0dae8
8 changed files with 110 additions and 13 deletions

View File

@@ -913,6 +913,8 @@ package android.hardware.devicestate {
method @NonNull public int[] getSupportedStates();
method public void removeDeviceStateListener(@NonNull android.hardware.devicestate.DeviceStateManager.DeviceStateListener);
method @RequiresPermission(android.Manifest.permission.CONTROL_DEVICE_STATE) public void requestState(@NonNull android.hardware.devicestate.DeviceStateRequest, @Nullable java.util.concurrent.Executor, @Nullable android.hardware.devicestate.DeviceStateRequest.Callback);
field public static final int MAXIMUM_DEVICE_STATE = 255; // 0xff
field public static final int MINIMUM_DEVICE_STATE = 0; // 0x0
}
public static interface DeviceStateManager.DeviceStateListener {

View File

@@ -42,6 +42,12 @@ public final class DeviceStateManager {
*/
public static final int INVALID_DEVICE_STATE = -1;
/** The minimum allowed device state identifier. */
public static final int MINIMUM_DEVICE_STATE = 0;
/** The maximum allowed device state identifier. */
public static final int MAXIMUM_DEVICE_STATE = 255;
private final DeviceStateManagerGlobal mGlobal;
/** @hide */

View File

@@ -16,9 +16,14 @@
package com.android.server.devicestate;
import static android.hardware.devicestate.DeviceStateManager.MAXIMUM_DEVICE_STATE;
import static android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE;
import android.annotation.IntRange;
import android.annotation.NonNull;
import com.android.internal.util.Preconditions;
import java.util.Objects;
/**
@@ -35,24 +40,25 @@ import java.util.Objects;
*/
public final class DeviceState {
/** Unique identifier for the device state. */
@IntRange(from = 0)
@IntRange(from = MINIMUM_DEVICE_STATE, to = MAXIMUM_DEVICE_STATE)
private final int mIdentifier;
/** String description of the device state. */
@NonNull
private final String mName;
public DeviceState(@IntRange(from = 0) int identifier,
public DeviceState(
@IntRange(from = MINIMUM_DEVICE_STATE, to = MAXIMUM_DEVICE_STATE) int identifier,
@NonNull String name) {
if (identifier < 0) {
throw new IllegalArgumentException("Identifier must be greater than or equal to zero.");
}
Preconditions.checkArgumentInRange(identifier, MINIMUM_DEVICE_STATE, MAXIMUM_DEVICE_STATE,
"identifier");
mIdentifier = identifier;
mName = name;
}
/** Returns the unique identifier for the device state. */
@IntRange(from = 0)
@IntRange(from = MINIMUM_DEVICE_STATE, to = MAXIMUM_DEVICE_STATE)
public int getIdentifier() {
return mIdentifier;
}

View File

@@ -17,6 +17,8 @@
package com.android.server.devicestate;
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 android.hardware.devicestate.DeviceStateRequest.FLAG_CANCEL_WHEN_BASE_CHANGES;
import android.annotation.IntRange;
@@ -89,7 +91,7 @@ public final class DeviceStateManagerService extends SystemService {
// the current state after the initial callback from the DeviceStateProvider.
@GuardedBy("mLock")
@NonNull
private DeviceState mCommittedState = new DeviceState(0, "UNSET");
private DeviceState mCommittedState = new DeviceState(MINIMUM_DEVICE_STATE, "UNSET");
// The device state that is currently awaiting callback from the policy to be committed.
@GuardedBy("mLock")
@NonNull
@@ -598,8 +600,9 @@ public final class DeviceStateManagerService extends SystemService {
}
@Override
public void onStateChanged(@IntRange(from = 0) int identifier) {
if (identifier < 0) {
public void onStateChanged(
@IntRange(from = MINIMUM_DEVICE_STATE, to = MAXIMUM_DEVICE_STATE) int identifier) {
if (identifier < MINIMUM_DEVICE_STATE || identifier > MAXIMUM_DEVICE_STATE) {
throw new IllegalArgumentException("Invalid identifier: " + identifier);
}

View File

@@ -16,6 +16,9 @@
package com.android.server.devicestate;
import static android.hardware.devicestate.DeviceStateManager.MAXIMUM_DEVICE_STATE;
import static android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE;
import android.annotation.IntRange;
/**
@@ -65,8 +68,10 @@ public interface DeviceStateProvider {
*
* @param identifier the identifier of the new device state.
*
* @throws IllegalArgumentException if the state is less than 0.
* @throws IllegalArgumentException if the state is less than {@link MINIMUM_DEVICE_STATE}
* or greater than {@link MAXIMUM_DEVICE_STATE}.
*/
void onStateChanged(@IntRange(from = 0) int identifier);
void onStateChanged(
@IntRange(from = MINIMUM_DEVICE_STATE, to = MAXIMUM_DEVICE_STATE) int identifier);
}
}

View File

@@ -17,6 +17,7 @@
package com.android.server.policy;
import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE;
import static android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -84,7 +85,8 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider,
private static final BooleanSupplier TRUE_BOOLEAN_SUPPLIER = () -> true;
@VisibleForTesting
static final DeviceState DEFAULT_DEVICE_STATE = new DeviceState(0, "DEFAULT");
static final DeviceState DEFAULT_DEVICE_STATE = new DeviceState(MINIMUM_DEVICE_STATE,
"DEFAULT");
private static final String VENDOR_CONFIG_FILE_PATH = "etc/devicestate/";
private static final String DATA_CONFIG_FILE_PATH = "system/devicestate/";

View File

@@ -52,7 +52,8 @@ import javax.annotation.Nullable;
public final class DeviceStateManagerServiceTest {
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");
// 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 TestDeviceStatePolicy mPolicy;
private TestDeviceStateProvider mProvider;

View File

@@ -0,0 +1,72 @@
/*
* 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.MAXIMUM_DEVICE_STATE;
import static android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
import static org.testng.Assert.assertThrows;
import android.platform.test.annotations.Presubmit;
import androidx.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
/**
* Unit tests for {@link DeviceState}.
* <p/>
* Run with <code>atest DeviceStateTest</code>.
*/
@Presubmit
@RunWith(AndroidJUnit4.class)
public final class DeviceStateTest {
@Test
public void testConstruct() {
final DeviceState state = new DeviceState(MINIMUM_DEVICE_STATE /* identifier */,
"CLOSED" /* name */);
assertEquals(state.getIdentifier(), MINIMUM_DEVICE_STATE);
assertEquals(state.getName(), "CLOSED");
}
@Test
public void testConstruct_nullName() {
final DeviceState state = new DeviceState(MAXIMUM_DEVICE_STATE /* identifier */,
null /* name */);
assertEquals(state.getIdentifier(), MAXIMUM_DEVICE_STATE);
assertNull(state.getName());
}
@Test
public void testConstruct_tooLargeIdentifier() {
assertThrows(IllegalArgumentException.class, () -> {
final DeviceState state = new DeviceState(MAXIMUM_DEVICE_STATE + 1 /* identifier */,
null /* name */);
});
}
@Test
public void testConstruct_tooSmallIdentifier() {
assertThrows(IllegalArgumentException.class, () -> {
final DeviceState state = new DeviceState(MINIMUM_DEVICE_STATE - 1 /* identifier */,
null /* name */);
});
}
}