diff options
| author | 2024-02-15 17:42:20 +0000 | |
|---|---|---|
| committer | 2024-02-15 21:35:46 +0000 | |
| commit | 93081e2a8dbba90031d813db85619a9aa2bcc878 (patch) | |
| tree | 64da07e344c4bc8c684fe26c75e6d7fdd7d69c21 | |
| parent | a6bf9b66535eef3c812f647f7d2cd466d1a14f98 (diff) | |
Promote DeviceStateManager to System API and update DeviceStateManager API's
Promote DeviceStateManager to System API
and add updated DeviceState property API's, as well
as DeviceStateManager callback API's to return DeviceState
objects instead of just integer identifiers.
Deprecated the previous constructor and
flag based API's on DeviceState
Revert of Revert submission 26246900-revert-26228978-device-state-callbacks-XJADFJXEAY
Reason for revert: Fixing test failures
Reverted changes: /q/submissionid:26246900-revert-26228978-device-state-callbacks-XJADFJXEAY
Bug: 293636629
Test: DeviceStateManagerTests
Change-Id: Idaa7331c551838c7d167828c7d191d72d39369ae
11 files changed, 434 insertions, 56 deletions
diff --git a/AconfigFlags.bp b/AconfigFlags.bp index 7fee81095774..bfe188d49ddb 100644 --- a/AconfigFlags.bp +++ b/AconfigFlags.bp @@ -37,6 +37,7 @@ aconfig_declarations_group { "android.credentials.flags-aconfig-java", "android.database.sqlite-aconfig-java", "android.hardware.biometrics.flags-aconfig-java", + "android.hardware.devicestate.feature.flags-aconfig-java", "android.hardware.flags-aconfig-java", "android.hardware.radio.flags-aconfig-java", "android.hardware.usb.flags-aconfig-java", @@ -163,6 +164,19 @@ java_aconfig_library { defaults: ["framework-minus-apex-aconfig-java-defaults"], } +// DeviceStateManager +aconfig_declarations { + name: "android.hardware.devicestate.feature.flags-aconfig", + package: "android.hardware.devicestate.feature.flags", + srcs: ["core/java/android/hardware/devicestate/feature/*.aconfig"], +} + +java_aconfig_library { + name: "android.hardware.devicestate.feature.flags-aconfig-java", + aconfig_declarations: "android.hardware.devicestate.feature.flags-aconfig", + defaults: ["framework-minus-apex-aconfig-java-defaults"], +} + // Input aconfig_declarations { name: "com.android.hardware.input.input-aconfig", diff --git a/core/api/system-current.txt b/core/api/system-current.txt index 59389893354a..dc4d40352344 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -4851,6 +4851,39 @@ package android.hardware.camera2.params { } +package android.hardware.devicestate { + + @FlaggedApi("android.hardware.devicestate.feature.flags.device_state_property_api") public final class DeviceState { + method @IntRange(from=0x0) public int getIdentifier(); + method @NonNull public String getName(); + method public boolean hasProperties(@NonNull int...); + method public boolean hasProperty(int); + field public static final int PROPERTY_EMULATED_ONLY = 10; // 0xa + field public static final int PROPERTY_EXTENDED_DEVICE_STATE_EXTERNAL_DISPLAY = 15; // 0xf + field public static final int PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT = 17; // 0x11 + field public static final int PROPERTY_FEATURE_REAR_DISPLAY = 16; // 0x10 + field public static final int PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY = 12; // 0xc + field public static final int PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY = 11; // 0xb + field public static final int PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED = 1; // 0x1 + field public static final int PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN = 2; // 0x2 + field public static final int PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN = 3; // 0x3 + field public static final int PROPERTY_POWER_CONFIGURATION_TRIGGER_SLEEP = 13; // 0xd + field public static final int PROPERTY_POWER_CONFIGURATION_TRIGGER_WAKE = 14; // 0xe + } + + @FlaggedApi("android.hardware.devicestate.feature.flags.device_state_property_api") public final class DeviceStateManager { + method @NonNull public java.util.List<android.hardware.devicestate.DeviceState> getSupportedDeviceStates(); + method public void registerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.hardware.devicestate.DeviceStateManager.DeviceStateCallback); + method public void unregisterCallback(@NonNull android.hardware.devicestate.DeviceStateManager.DeviceStateCallback); + } + + public static interface DeviceStateManager.DeviceStateCallback { + method public default void onDeviceStateChanged(@NonNull android.hardware.devicestate.DeviceState); + method public default void onSupportedStatesChanged(@NonNull java.util.List<android.hardware.devicestate.DeviceState>); + } + +} + package android.hardware.display { public final class AmbientBrightnessDayStats implements android.os.Parcelable { diff --git a/core/api/test-current.txt b/core/api/test-current.txt index f6366a2afbf0..334d9e63bb98 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -1620,22 +1620,26 @@ package android.hardware.camera2.params { package android.hardware.devicestate { - public final class DeviceStateManager { + @FlaggedApi("android.hardware.devicestate.feature.flags.device_state_property_api") public final class DeviceState { + ctor @Deprecated public DeviceState(@IntRange(from=android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE_IDENTIFIER, to=android.hardware.devicestate.DeviceStateManager.MAXIMUM_DEVICE_STATE_IDENTIFIER) int, @NonNull String, int); + ctor public DeviceState(@IntRange(from=android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE_IDENTIFIER, to=android.hardware.devicestate.DeviceStateManager.MAXIMUM_DEVICE_STATE_IDENTIFIER) int, @NonNull String, @NonNull java.util.Set<java.lang.Integer>); + field public static final int PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST = 8; // 0x8 + } + + @FlaggedApi("android.hardware.devicestate.feature.flags.device_state_property_api") public final class DeviceStateManager { method @RequiresPermission(android.Manifest.permission.CONTROL_DEVICE_STATE) public void cancelBaseStateOverride(); method @RequiresPermission(value=android.Manifest.permission.CONTROL_DEVICE_STATE, conditional=true) public void cancelStateRequest(); - method @NonNull public int[] getSupportedStates(); - method public void registerCallback(@NonNull java.util.concurrent.Executor, @NonNull android.hardware.devicestate.DeviceStateManager.DeviceStateCallback); + method @Deprecated @NonNull public int[] getSupportedStates(); method @RequiresPermission(android.Manifest.permission.CONTROL_DEVICE_STATE) public void requestBaseStateOverride(@NonNull android.hardware.devicestate.DeviceStateRequest, @Nullable java.util.concurrent.Executor, @Nullable android.hardware.devicestate.DeviceStateRequest.Callback); method @RequiresPermission(value=android.Manifest.permission.CONTROL_DEVICE_STATE, conditional=true) public void requestState(@NonNull android.hardware.devicestate.DeviceStateRequest, @Nullable java.util.concurrent.Executor, @Nullable android.hardware.devicestate.DeviceStateRequest.Callback); - method public void unregisterCallback(@NonNull android.hardware.devicestate.DeviceStateManager.DeviceStateCallback); - field public static final int MAXIMUM_DEVICE_STATE = 255; // 0xff - field public static final int MINIMUM_DEVICE_STATE = 0; // 0x0 + field public static final int MAXIMUM_DEVICE_STATE_IDENTIFIER = 10000; // 0x2710 + field public static final int MINIMUM_DEVICE_STATE_IDENTIFIER = 0; // 0x0 } public static interface DeviceStateManager.DeviceStateCallback { - method public default void onBaseStateChanged(int); - method public void onStateChanged(int); - method public default void onSupportedStatesChanged(@NonNull int[]); + method @Deprecated public default void onBaseStateChanged(int); + method @Deprecated public void onStateChanged(int); + method @Deprecated public default void onSupportedStatesChanged(@NonNull int[]); } public final class DeviceStateRequest { diff --git a/core/java/android/hardware/devicestate/DeviceState.java b/core/java/android/hardware/devicestate/DeviceState.java index 5a349050a28f..86293540dd36 100644 --- a/core/java/android/hardware/devicestate/DeviceState.java +++ b/core/java/android/hardware/devicestate/DeviceState.java @@ -16,18 +16,25 @@ package android.hardware.devicestate; -import static android.hardware.devicestate.DeviceStateManager.MAXIMUM_DEVICE_STATE; -import static android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE; +import static android.hardware.devicestate.DeviceStateManager.MAXIMUM_DEVICE_STATE_IDENTIFIER; +import static android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE_IDENTIFIER; +import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.IntRange; import android.annotation.NonNull; +import android.annotation.SystemApi; +import android.annotation.TestApi; import com.android.internal.util.Preconditions; +import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.util.Collections; import java.util.Objects; +import java.util.Set; /** * A state of the device defined by the {@link DeviceStateProvider} and managed by the @@ -37,21 +44,29 @@ import java.util.Objects; * 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. - * @hide * + * @hide * @see DeviceStateManager */ +@SystemApi +@FlaggedApi(android.hardware.devicestate.feature.flags.Flags.FLAG_DEVICE_STATE_PROPERTY_API) public final class DeviceState { /** * Flag that indicates override requests should be cancelled when this device state becomes the * base device state. + * @hide + * @deprecated use {@link #PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS} */ + @Deprecated public static final int FLAG_CANCEL_OVERRIDE_REQUESTS = 1 << 0; /** * Flag that indicates this device state is inaccessible for applications to be placed in. This - * could be a device-state where the {@link DEFAULT_DISPLAY} is not enabled. + * could be a device-state where the {@link Display#DEFAULT_DISPLAY} is not enabled. + * @hide + * @deprecated use {@link #PROPERTY_APP_INACCESSIBLE} */ + @Deprecated public static final int FLAG_APP_INACCESSIBLE = 1 << 1; /** @@ -60,7 +75,10 @@ public final class DeviceState { * through emulation and have no physical configuration to match. * * This flag indicates that the corresponding state can only be entered through emulation. + * @hide + * @deprecated use {@link #PROPERTY_EMULATED_ONLY} */ + @Deprecated public static final int FLAG_EMULATED_ONLY = 1 << 2; /** @@ -68,19 +86,28 @@ public final class DeviceState { * requesting app is no longer on top. The app is considered not on top when (1) the top * activity in the system is from a different app, (2) the device is in sleep mode, or * (3) the keyguard shows up. + * @hide + * @deprecated use {@link #PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP} */ + @Deprecated public static final int FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP = 1 << 3; /** * This flag indicates that the corresponding state should be disabled when the device is * overheating and reaching the critical status. + * @hide + * @deprecated use {@link #PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL} */ + @Deprecated public static final int FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL = 1 << 4; /** * This flag indicates that the corresponding state should be disabled when power save mode * is enabled. + * @hide + * @deprecated use {@link #PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE} */ + @Deprecated public static final int FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE = 1 << 5; /** @hide */ @@ -92,11 +119,157 @@ public final class DeviceState { FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL, FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE }) + @Deprecated @Retention(RetentionPolicy.SOURCE) public @interface DeviceStateFlags {} + /** + * Property that indicates that a fold-in style foldable device is currently in a fully closed + * configuration. + */ + public static final int PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED = 1; + + /** + * Property that indicates that a fold-in style foldable device is currently in a half-opened + * configuration. This signifies that the device's hinge is positioned somewhere around 90 + * degrees. Checking for display configuration properties as well can provide information + * on which display is currently active. + */ + public static final int PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN = 2; + + /** + * Property that indicates that a fold-in style foldable device is currently in a fully open + * configuration. + */ + public static final int PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN = 3; + + /** + * Property that indicates override requests should be cancelled when the device is physically + * put into this state. + * @hide + */ + public static final int PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS = 4; + + /** + * This property indicates that the corresponding state should be automatically canceled when + * the requesting app is no longer on top. The app is considered not on top when (1) the top + * activity in the system is from a different app, (2) the device is in sleep mode, or + * (3) the keyguard shows up. + * @hide + */ + public static final int PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP = 5; + + /** + * This property indicates that the corresponding state should be disabled when the device is + * overheating and reaching the critical status. + * @hide + */ + public static final int PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL = 6; + + /** + * This property indicates that the corresponding state should be disabled when power save mode + * is enabled. + * @hide + */ + public static final int PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE = 7; + + /** + * This property denotes that this state is available for applications to request and the system + * server should deny any request that comes from a process that does not hold the + * CONTROL_DEVICE_STATE permission if it is requesting a state that does not have this property + * on it. + * @hide + */ + @TestApi + public static final int PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST = 8; + + /** + * Property that indicates this device state is inaccessible for applications to be made + * visible to the user. This could be a device-state where the {@link Display#DEFAULT_DISPLAY} + * is not enabled. + * @hide + */ + public static final int PROPERTY_APP_INACCESSIBLE = 9; + + /** + * This property indidcates that this state can only be entered through emulation and has no + * physical configuration to match. + */ + public static final int PROPERTY_EMULATED_ONLY = 10; + + /** + * Property that indicates that the outer display area of a foldable device is currently the + * primary display area. + * + * Note: This does not necessarily mean that the outer display area is the + * @link Display#DEFAULT_DISPLAY}. + */ + public static final int PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY = 11; + + /** + * Property that indicates that the inner display area of a foldable device is currently the + * primary display area. + * + * Note: This does not necessarily mean that the inner display area is the + * {@link Display#DEFAULT_DISPLAY}. + */ + public static final int PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY = 12; + + /** + * Property that indicates that this device state will attempt to trigger the device to go to + * sleep. + */ + public static final int PROPERTY_POWER_CONFIGURATION_TRIGGER_SLEEP = 13; + + /** + * Property that indicates that this device state will attempt to trigger the device to wake up. + */ + public static final int PROPERTY_POWER_CONFIGURATION_TRIGGER_WAKE = 14; + + /** + * Property that indicates that an external display has been connected to the device. Specifics + * around display mode or properties around the display should be gathered through + * {@link android.hardware.display.DisplayManager} + */ + public static final int PROPERTY_EXTENDED_DEVICE_STATE_EXTERNAL_DISPLAY = 15; + /** + * Property that indicates that this state corresponds to the device state for rear display + * mode. This means that the active display is facing the same direction as the rear camera. + */ + public static final int PROPERTY_FEATURE_REAR_DISPLAY = 16; + + /** + * Property that indicates that this state corresponds to the device state where both displays + * on a foldable are active, with the internal display being the default display. + */ + public static final int PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT = 17; + + /** @hide */ + @IntDef(prefix = {"PROPERTY_"}, flag = true, value = { + PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED, + PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN, + PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN, + PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS, + PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP, + PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL, + PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE, + PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST, + PROPERTY_APP_INACCESSIBLE, + PROPERTY_EMULATED_ONLY, + PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY, + PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY, + PROPERTY_POWER_CONFIGURATION_TRIGGER_SLEEP, + PROPERTY_POWER_CONFIGURATION_TRIGGER_WAKE, + PROPERTY_EXTENDED_DEVICE_STATE_EXTERNAL_DISPLAY, + PROPERTY_FEATURE_REAR_DISPLAY, + PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT + }) + @Retention(RetentionPolicy.SOURCE) + @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) + public @interface DeviceStateProperties {} + /** Unique identifier for the device state. */ - @IntRange(from = MINIMUM_DEVICE_STATE, to = MAXIMUM_DEVICE_STATE) + @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER, to = MAXIMUM_DEVICE_STATE_IDENTIFIER) private final int mIdentifier; /** String description of the device state. */ @@ -106,20 +279,49 @@ public final class DeviceState { @DeviceStateFlags private final int mFlags; + private final Set<@DeviceStateProperties Integer> mProperties; + + /** + * @deprecated Deprecated in favor of {@link #DeviceState(int, String, Set)} + * @hide + */ + // TODO(b/325124054): Make non-default and remove deprecated callback methods. + @TestApi + @Deprecated public DeviceState( - @IntRange(from = MINIMUM_DEVICE_STATE, to = MAXIMUM_DEVICE_STATE) int identifier, + @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER, to = + MAXIMUM_DEVICE_STATE_IDENTIFIER) int identifier, @NonNull String name, @DeviceStateFlags int flags) { - Preconditions.checkArgumentInRange(identifier, MINIMUM_DEVICE_STATE, MAXIMUM_DEVICE_STATE, + Preconditions.checkArgumentInRange(identifier, MINIMUM_DEVICE_STATE_IDENTIFIER, + MAXIMUM_DEVICE_STATE_IDENTIFIER, "identifier"); mIdentifier = identifier; mName = name; mFlags = flags; + mProperties = Collections.emptySet(); + } + + /** @hide */ + @TestApi + public DeviceState( + @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER, to = + MAXIMUM_DEVICE_STATE_IDENTIFIER) int identifier, + @NonNull String name, + @NonNull Set<@DeviceStateProperties Integer> properties) { + Preconditions.checkArgumentInRange(identifier, MINIMUM_DEVICE_STATE_IDENTIFIER, + MAXIMUM_DEVICE_STATE_IDENTIFIER, + "identifier"); + + mIdentifier = identifier; + mName = name; + mProperties = Set.copyOf(properties); + mFlags = 0; } /** Returns the unique identifier for the device state. */ - @IntRange(from = MINIMUM_DEVICE_STATE, to = MAXIMUM_DEVICE_STATE) + @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER) public int getIdentifier() { return mIdentifier; } @@ -130,6 +332,12 @@ public final class DeviceState { return mName; } + /** + * @hide + * @deprecated in favor of {@link #hasProperty(int)} method + */ + // TODO(b/325124054): Make non-default and remove deprecated callback methods. + @Deprecated @DeviceStateFlags public int getFlags() { return mFlags; @@ -138,9 +346,9 @@ public final class DeviceState { @Override public String toString() { return "DeviceState{" + "identifier=" + mIdentifier + ", name='" + mName + '\'' - + ", app_accessible=" + !hasFlag(FLAG_APP_INACCESSIBLE) + + ", app_accessible=" + !hasProperty(PROPERTY_APP_INACCESSIBLE) + ", cancel_when_requester_not_on_top=" - + hasFlag(FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP) + + hasProperty(PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP) + "}"; } @@ -151,17 +359,40 @@ public final class DeviceState { DeviceState that = (DeviceState) o; return mIdentifier == that.mIdentifier && Objects.equals(mName, that.mName) - && mFlags == that.mFlags; + && Objects.equals(mProperties, that.mProperties); } @Override public int hashCode() { - return Objects.hash(mIdentifier, mName, mFlags); + return Objects.hash(mIdentifier, mName, mProperties); } /** Checks if a specific flag is set + * @hide + * @deprecated in favor of {@link #hasProperty(int)} */ + // TODO(b/325124054): Make non-default and remove deprecated callback methods. + @Deprecated public boolean hasFlag(int flagToCheckFor) { return (mFlags & flagToCheckFor) == flagToCheckFor; } + + /** + * Checks if a specific property is set on this state + */ + public boolean hasProperty(@DeviceStateProperties int propertyToCheckFor) { + return mProperties.contains(propertyToCheckFor); + } + + /** + * Checks if a list of properties are all set on this state + */ + public boolean hasProperties(@NonNull @DeviceStateProperties int... properties) { + for (int i = 0; i < properties.length; i++) { + if (mProperties.contains(properties[i])) { + return false; + } + } + return true; + } } diff --git a/core/java/android/hardware/devicestate/DeviceStateManager.java b/core/java/android/hardware/devicestate/DeviceStateManager.java index 6a667fe39974..e775dc6e6928 100644 --- a/core/java/android/hardware/devicestate/DeviceStateManager.java +++ b/core/java/android/hardware/devicestate/DeviceStateManager.java @@ -18,15 +18,19 @@ package android.hardware.devicestate; import android.Manifest; import android.annotation.CallbackExecutor; +import android.annotation.FlaggedApi; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresPermission; +import android.annotation.SuppressLint; +import android.annotation.SystemApi; import android.annotation.SystemService; import android.annotation.TestApi; import android.content.Context; import com.android.internal.util.ArrayUtils; +import java.util.List; import java.util.concurrent.Executor; import java.util.function.Consumer; @@ -36,7 +40,8 @@ import java.util.function.Consumer; * * @hide */ -@TestApi +@SystemApi +@FlaggedApi(android.hardware.devicestate.feature.flags.Flags.FLAG_DEVICE_STATE_PROPERTY_API) @SystemService(Context.DEVICE_STATE_SERVICE) public final class DeviceStateManager { /** @@ -46,11 +51,19 @@ 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 minimum allowed device state identifier. + * @hide + */ + @TestApi + public static final int MINIMUM_DEVICE_STATE_IDENTIFIER = 0; - /** The maximum allowed device state identifier. */ - public static final int MAXIMUM_DEVICE_STATE = 255; + /** + * The maximum allowed device state identifier. + * @hide + */ + @TestApi + public static final int MAXIMUM_DEVICE_STATE_IDENTIFIER = 10000; /** * Intent needed to launch the rear display overlay activity from SysUI @@ -83,13 +96,27 @@ public final class DeviceStateManager { /** * Returns the list of device states that are supported and can be requested with * {@link #requestState(DeviceStateRequest, Executor, DeviceStateRequest.Callback)}. + * @deprecated use {@link #getSupportedDeviceStates()} + * @hide */ + // TODO(b/325124054): Make non-default and remove deprecated callback methods. + @TestApi + @Deprecated @NonNull public int[] getSupportedStates() { return mGlobal.getSupportedStates(); } /** + * Returns the list of device states that are supported and can be requested with + * {@link #requestState(DeviceStateRequest, Executor, DeviceStateRequest.Callback)}. + */ + @NonNull + public List<DeviceState> getSupportedDeviceStates() { + return mGlobal.getSupportedDeviceStates(); + } + + /** * Submits a {@link DeviceStateRequest request} to modify the device state. * <p> * By default, the request is kept active until one of the following occurs: @@ -107,7 +134,10 @@ public final class DeviceStateManager { * the {@link android.Manifest.permission#CONTROL_DEVICE_STATE} permission is held. * * @see DeviceStateRequest + * @hide */ + @SuppressLint("RequiresPermission") // Lint doesn't handle conditional permission checks today + @TestApi @RequiresPermission(value = android.Manifest.permission.CONTROL_DEVICE_STATE, conditional = true) public void requestState(@NonNull DeviceStateRequest request, @@ -124,7 +154,10 @@ public final class DeviceStateManager { * * @throws SecurityException if the caller is neither the current top-focused activity nor if * the {@link android.Manifest.permission#CONTROL_DEVICE_STATE} permission is held. + * @hide */ + @SuppressLint("RequiresPermission") // Lint doesn't handle conditional permission checks today + @TestApi @RequiresPermission(value = android.Manifest.permission.CONTROL_DEVICE_STATE, conditional = true) public void cancelStateRequest() { @@ -151,11 +184,11 @@ public final class DeviceStateManager { * emulated override requests take priority. * * @throws IllegalArgumentException if the requested state is unsupported. - * @throws SecurityException if the caller does not hold the - * {@link android.Manifest.permission#CONTROL_DEVICE_STATE} permission. * * @see DeviceStateRequest + * @hide */ + @TestApi @RequiresPermission(android.Manifest.permission.CONTROL_DEVICE_STATE) public void requestBaseStateOverride(@NonNull DeviceStateRequest request, @Nullable @CallbackExecutor Executor executor, @@ -169,9 +202,9 @@ public final class DeviceStateManager { * <p> * This method is noop if there is no base state request currently active. * - * @throws SecurityException if the caller does not hold the - * {@link android.Manifest.permission#CONTROL_DEVICE_STATE} permission. + * @hide */ + @TestApi @RequiresPermission(Manifest.permission.CONTROL_DEVICE_STATE) public void cancelBaseStateOverride() { mGlobal.cancelBaseStateOverride(); @@ -209,10 +242,31 @@ public final class DeviceStateManager { * @param supportedStates the new supported states. * * @see DeviceStateManager#getSupportedStates() + * @deprecated use {@link #onSupportedStatesChanged(List)} + * @hide */ + // TODO(b/325124054): Make non-default and remove deprecated callback methods. + @TestApi + @Deprecated default void onSupportedStatesChanged(@NonNull int[] supportedStates) {} /** + * Called in response to a change in the states supported by the device. + * <p> + * Guaranteed to be called once on registration of the callback with the initial value and + * then on every subsequent change in the supported states. + * + * The supported device states may change due to certain states becoming unavailable + * due to device configuration or device conditions such as if the device is too hot or + * external monitors have been connected. + * + * @param supportedStates the new supported states. + * + * @see DeviceStateManager#getSupportedDeviceStates() + */ + default void onSupportedStatesChanged(@NonNull List<DeviceState> supportedStates) {} + + /** * Called in response to a change in the base device state. * <p> * The base state is the state of the device without considering any requests made through @@ -224,7 +278,13 @@ public final class DeviceStateManager { * then on every subsequent change in the non-override state. * * @param state the new base device state. + * @deprecated use {@link #onDeviceStateChanged(DeviceState)} and query for physical + * properties that are relevant to your needs. + * @hide */ + // TODO(b/325124054): Make non-default and remove deprecated callback methods. + @TestApi + @Deprecated default void onBaseStateChanged(int state) {} /** @@ -234,8 +294,24 @@ public final class DeviceStateManager { * then on every subsequent change in device state. * * @param state the new device state. + * @deprecated use {@link #onDeviceStateChanged(DeviceState)} + * @hide */ + // TODO(b/325124054): Make non-default and remove deprecated callback methods. + @TestApi + @Deprecated void onStateChanged(int state); + + /** + * Called in response to device state changes. + * <p> + * Guaranteed to be called once on registration of the callback with the initial value and + * then on every subsequent change in device state. + * + * @param state the new device state. + */ + // TODO(b/325124054): Make non-default and remove deprecated callback methods. + default void onDeviceStateChanged(@NonNull DeviceState state) {} } /** diff --git a/core/java/android/hardware/devicestate/feature/flags.aconfig b/core/java/android/hardware/devicestate/feature/flags.aconfig new file mode 100644 index 000000000000..73a9e346bd5d --- /dev/null +++ b/core/java/android/hardware/devicestate/feature/flags.aconfig @@ -0,0 +1,9 @@ +package: "android.hardware.devicestate.feature.flags" + +flag { + name: "device_state_property_api" + namespace: "windowing_sdk" + description: "Updated DeviceState hasProperty API" + bug: "293636629" + is_fixed_read_only: true +}
\ No newline at end of file diff --git a/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateTest.java b/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateTest.java index 396d403a1ada..fb5e5120c354 100644 --- a/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateTest.java +++ b/core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateTest.java @@ -16,8 +16,8 @@ package android.hardware.devicestate; -import static android.hardware.devicestate.DeviceStateManager.MAXIMUM_DEVICE_STATE; -import static android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE; +import static android.hardware.devicestate.DeviceStateManager.MAXIMUM_DEVICE_STATE_IDENTIFIER; +import static android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE_IDENTIFIER; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertNull; @@ -39,18 +39,18 @@ import org.junit.runners.JUnit4; public final class DeviceStateTest { @Test public void testConstruct() { - final DeviceState state = new DeviceState(MINIMUM_DEVICE_STATE /* identifier */, + final DeviceState state = new DeviceState(MINIMUM_DEVICE_STATE_IDENTIFIER /* identifier */, "TEST_CLOSED" /* name */, DeviceState.FLAG_CANCEL_OVERRIDE_REQUESTS /* flags */); - assertEquals(state.getIdentifier(), MINIMUM_DEVICE_STATE); + assertEquals(state.getIdentifier(), MINIMUM_DEVICE_STATE_IDENTIFIER); assertEquals(state.getName(), "TEST_CLOSED"); assertEquals(state.getFlags(), DeviceState.FLAG_CANCEL_OVERRIDE_REQUESTS); } @Test public void testConstruct_nullName() { - final DeviceState state = new DeviceState(MAXIMUM_DEVICE_STATE /* identifier */, + final DeviceState state = new DeviceState(MAXIMUM_DEVICE_STATE_IDENTIFIER /* identifier */, null /* name */, 0/* flags */); - assertEquals(state.getIdentifier(), MAXIMUM_DEVICE_STATE); + assertEquals(state.getIdentifier(), MAXIMUM_DEVICE_STATE_IDENTIFIER); assertNull(state.getName()); assertEquals(state.getFlags(), 0); } @@ -58,7 +58,8 @@ public final class DeviceStateTest { @Test public void testConstruct_tooLargeIdentifier() { assertThrows(IllegalArgumentException.class, () -> { - final DeviceState state = new DeviceState(MAXIMUM_DEVICE_STATE + 1 /* identifier */, + final DeviceState state = new DeviceState( + MAXIMUM_DEVICE_STATE_IDENTIFIER + 1 /* identifier */, null /* name */, 0 /* flags */); }); } @@ -66,7 +67,8 @@ public final class DeviceStateTest { @Test public void testConstruct_tooSmallIdentifier() { assertThrows(IllegalArgumentException.class, () -> { - final DeviceState state = new DeviceState(MINIMUM_DEVICE_STATE - 1 /* identifier */, + final DeviceState state = new DeviceState( + MINIMUM_DEVICE_STATE_IDENTIFIER - 1 /* identifier */, null /* name */, 0 /* flags */); }); } diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java index cd064ae38aa5..38051c13049c 100644 --- a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java +++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java @@ -21,8 +21,8 @@ import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREG import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.hardware.devicestate.DeviceState.FLAG_CANCEL_OVERRIDE_REQUESTS; import static android.hardware.devicestate.DeviceStateManager.INVALID_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.MAXIMUM_DEVICE_STATE_IDENTIFIER; +import static android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE_IDENTIFIER; import static com.android.server.devicestate.OverrideRequest.OVERRIDE_REQUEST_TYPE_BASE_STATE; import static com.android.server.devicestate.OverrideRequest.OVERRIDE_REQUEST_TYPE_EMULATED_STATE; @@ -1065,7 +1065,8 @@ public final class DeviceStateManagerService extends SystemService { } private final class DeviceStateProviderListener implements DeviceStateProvider.Listener { - @IntRange(from = MINIMUM_DEVICE_STATE, to = MAXIMUM_DEVICE_STATE) int mCurrentBaseState; + @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER, to = MAXIMUM_DEVICE_STATE_IDENTIFIER) + int mCurrentBaseState; @Override public void onSupportedDeviceStatesChanged(DeviceState[] newDeviceStates, @@ -1078,8 +1079,10 @@ public final class DeviceStateManagerService extends SystemService { @Override public void onStateChanged( - @IntRange(from = MINIMUM_DEVICE_STATE, to = MAXIMUM_DEVICE_STATE) int identifier) { - if (identifier < MINIMUM_DEVICE_STATE || identifier > MAXIMUM_DEVICE_STATE) { + @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER, to = + MAXIMUM_DEVICE_STATE_IDENTIFIER) int identifier) { + if (identifier < MINIMUM_DEVICE_STATE_IDENTIFIER + || identifier > MAXIMUM_DEVICE_STATE_IDENTIFIER) { 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 65b393ad94b9..b865c1d90a49 100644 --- a/services/core/java/com/android/server/devicestate/DeviceStateProvider.java +++ b/services/core/java/com/android/server/devicestate/DeviceStateProvider.java @@ -16,8 +16,8 @@ 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 android.hardware.devicestate.DeviceStateManager.MAXIMUM_DEVICE_STATE_IDENTIFIER; +import static android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE_IDENTIFIER; import android.annotation.IntDef; import android.annotation.IntRange; @@ -133,10 +133,12 @@ public interface DeviceStateProvider extends Dumpable { * * @param identifier the identifier of the new device state. * - * @throws IllegalArgumentException if the state is less than {@link MINIMUM_DEVICE_STATE} - * or greater than {@link MAXIMUM_DEVICE_STATE}. + * @throws IllegalArgumentException if the state is less than + * {@link MINIMUM_DEVICE_STATE_IDENTIFIER} or greater than + * {@link MAXIMUM_DEVICE_STATE_IDENTIFIER}. */ void onStateChanged( - @IntRange(from = MINIMUM_DEVICE_STATE, to = MAXIMUM_DEVICE_STATE) int identifier); + @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER, to = + MAXIMUM_DEVICE_STATE_IDENTIFIER) 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 76952b30c1e9..1b220a0b1485 100644 --- a/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java +++ b/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java @@ -17,7 +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 static android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE_IDENTIFIER; import android.annotation.NonNull; import android.annotation.Nullable; @@ -94,7 +94,7 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider, private static final BooleanSupplier FALSE_BOOLEAN_SUPPLIER = () -> false; @VisibleForTesting - static final DeviceState DEFAULT_DEVICE_STATE = new DeviceState(MINIMUM_DEVICE_STATE, + static final DeviceState DEFAULT_DEVICE_STATE = new DeviceState(MINIMUM_DEVICE_STATE_IDENTIFIER, "DEFAULT", 0 /* flags */); private static final String VENDOR_CONFIG_FILE_PATH = "etc/devicestate/"; diff --git a/services/foldables/devicestateprovider/src/com/android/server/policy/FoldableDeviceStateProvider.java b/services/foldables/devicestateprovider/src/com/android/server/policy/FoldableDeviceStateProvider.java index bf2619b52275..42e41d59cfeb 100644 --- a/services/foldables/devicestateprovider/src/com/android/server/policy/FoldableDeviceStateProvider.java +++ b/services/foldables/devicestateprovider/src/com/android/server/policy/FoldableDeviceStateProvider.java @@ -18,8 +18,8 @@ package com.android.server.policy; import static android.hardware.SensorManager.SENSOR_DELAY_FASTEST; import static android.hardware.devicestate.DeviceStateManager.INVALID_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.MAXIMUM_DEVICE_STATE_IDENTIFIER; +import static android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE_IDENTIFIER; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.TYPE_EXTERNAL; @@ -478,7 +478,8 @@ public final class FoldableDeviceStateProvider implements DeviceStateProvider, } public static DeviceStateConfiguration createConfig( - @IntRange(from = MINIMUM_DEVICE_STATE, to = MAXIMUM_DEVICE_STATE) int identifier, + @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER, to = + MAXIMUM_DEVICE_STATE_IDENTIFIER) int identifier, @NonNull String name, @DeviceState.DeviceStateFlags int flags, @NonNull Predicate<FoldableDeviceStateProvider> activeStatePredicate @@ -488,7 +489,8 @@ public final class FoldableDeviceStateProvider implements DeviceStateProvider, } public static DeviceStateConfiguration createConfig( - @IntRange(from = MINIMUM_DEVICE_STATE, to = MAXIMUM_DEVICE_STATE) int identifier, + @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER, to = + MAXIMUM_DEVICE_STATE_IDENTIFIER) int identifier, @NonNull String name, @NonNull Predicate<FoldableDeviceStateProvider> activeStatePredicate ) { @@ -498,7 +500,8 @@ public final class FoldableDeviceStateProvider implements DeviceStateProvider, /** Create a configuration with availability predicate **/ public static DeviceStateConfiguration createConfig( - @IntRange(from = MINIMUM_DEVICE_STATE, to = MAXIMUM_DEVICE_STATE) int identifier, + @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER, to = + MAXIMUM_DEVICE_STATE_IDENTIFIER) int identifier, @NonNull String name, @DeviceState.DeviceStateFlags int flags, @NonNull Predicate<FoldableDeviceStateProvider> activeStatePredicate, @@ -543,7 +546,8 @@ public final class FoldableDeviceStateProvider implements DeviceStateProvider, * @return device state configuration */ public static DeviceStateConfiguration createTentModeClosedState( - @IntRange(from = MINIMUM_DEVICE_STATE, to = MAXIMUM_DEVICE_STATE) int identifier, + @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER, to = + MAXIMUM_DEVICE_STATE_IDENTIFIER) int identifier, @NonNull String name, @DeviceState.DeviceStateFlags int flags, int minClosedAngleDegrees, |