diff options
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, |