From 836dc0dae8c724fab9a5bab8c3eba0738500eb75 Mon Sep 17 00:00:00 2001 From: Darryl L Johnson Date: Wed, 3 Feb 2021 09:51:33 -0800 Subject: [PATCH] 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 --- core/api/test-current.txt | 2 + .../devicestate/DeviceStateManager.java | 6 ++ .../server/devicestate/DeviceState.java | 18 +++-- .../DeviceStateManagerService.java | 9 ++- .../devicestate/DeviceStateProvider.java | 9 ++- .../policy/DeviceStateProviderImpl.java | 4 +- .../DeviceStateManagerServiceTest.java | 3 +- .../server/devicestate/DeviceStateTest.java | 72 +++++++++++++++++++ 8 files changed, 110 insertions(+), 13 deletions(-) create mode 100644 services/tests/servicestests/src/com/android/server/devicestate/DeviceStateTest.java diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 06110319cb35c..0379ea48ba934 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -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 { diff --git a/core/java/android/hardware/devicestate/DeviceStateManager.java b/core/java/android/hardware/devicestate/DeviceStateManager.java index f175e7b00b7e2..2d4b2ccd75145 100644 --- a/core/java/android/hardware/devicestate/DeviceStateManager.java +++ b/core/java/android/hardware/devicestate/DeviceStateManager.java @@ -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 */ diff --git a/services/core/java/com/android/server/devicestate/DeviceState.java b/services/core/java/com/android/server/devicestate/DeviceState.java index e496d77deaf5a..e693bcc93f8f5 100644 --- a/services/core/java/com/android/server/devicestate/DeviceState.java +++ b/services/core/java/com/android/server/devicestate/DeviceState.java @@ -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; } diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java index 984a17694e07a..b3a6f263953f9 100644 --- a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java +++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java @@ -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); } diff --git a/services/core/java/com/android/server/devicestate/DeviceStateProvider.java b/services/core/java/com/android/server/devicestate/DeviceStateProvider.java index 2d4377f820fd8..109bf6358e8bc 100644 --- a/services/core/java/com/android/server/devicestate/DeviceStateProvider.java +++ b/services/core/java/com/android/server/devicestate/DeviceStateProvider.java @@ -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); } } diff --git a/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java b/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java index ac358db519394..4e1065a9d3af7 100644 --- a/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java +++ b/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java @@ -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/"; diff --git a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java index 1a2266139405d..a078a77b4498a 100644 --- a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java @@ -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; diff --git a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateTest.java b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateTest.java new file mode 100644 index 0000000000000..b5c8053ad77ea --- /dev/null +++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateTest.java @@ -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}. + *

+ * Run with atest DeviceStateTest. + */ +@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 */); + }); + } +}