summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--AconfigFlags.bp14
-rw-r--r--core/api/system-current.txt33
-rw-r--r--core/api/test-current.txt22
-rw-r--r--core/java/android/hardware/devicestate/DeviceState.java255
-rw-r--r--core/java/android/hardware/devicestate/DeviceStateManager.java94
-rw-r--r--core/java/android/hardware/devicestate/feature/flags.aconfig9
-rw-r--r--core/tests/devicestatetests/src/android/hardware/devicestate/DeviceStateTest.java18
-rw-r--r--services/core/java/com/android/server/devicestate/DeviceStateManagerService.java13
-rw-r--r--services/core/java/com/android/server/devicestate/DeviceStateProvider.java12
-rw-r--r--services/core/java/com/android/server/policy/DeviceStateProviderImpl.java4
-rw-r--r--services/foldables/devicestateprovider/src/com/android/server/policy/FoldableDeviceStateProvider.java16
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,