diff options
13 files changed, 497 insertions, 224 deletions
diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 15f1eb4148cd..892567c6a587 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -1624,8 +1624,6 @@ package android.hardware.camera2.params { package android.hardware.devicestate { @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 } diff --git a/core/java/android/hardware/devicestate/DeviceState.java b/core/java/android/hardware/devicestate/DeviceState.java index e35e80126388..be129c4362c4 100644 --- a/core/java/android/hardware/devicestate/DeviceState.java +++ b/core/java/android/hardware/devicestate/DeviceState.java @@ -26,8 +26,6 @@ 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; @@ -268,68 +266,87 @@ public final class DeviceState { @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) public @interface DeviceStateProperties {} - /** Unique identifier for the device state. */ - @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER, to = MAXIMUM_DEVICE_STATE_IDENTIFIER) - private final int mIdentifier; + /** @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 + }) + @Retention(RetentionPolicy.SOURCE) + @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) + public @interface PhysicalDeviceStateProperties {} + + /** @hide */ + @IntDef(prefix = {"PROPERTY_"}, flag = true, value = { + 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 SystemDeviceStateProperties {} - /** String description of the device state. */ @NonNull - private final String mName; + private DeviceState.Configuration mDeviceStateConfiguration; @DeviceStateFlags private final int mFlags; - private final Set<@DeviceStateProperties Integer> mProperties; + /** @hide */ + public DeviceState(@NonNull DeviceState.Configuration deviceStateConfiguration) { + mDeviceStateConfiguration = deviceStateConfiguration; + mFlags = 0; + } + + /** @hide */ + public DeviceState( + @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER, to = + MAXIMUM_DEVICE_STATE_IDENTIFIER) int identifier, + @NonNull String name, + @NonNull Set<@DeviceStateProperties Integer> properties) { + mDeviceStateConfiguration = new DeviceState.Configuration(identifier, name, properties, + Collections.emptySet()); + mFlags = 0; + } /** * @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_IDENTIFIER, to = MAXIMUM_DEVICE_STATE_IDENTIFIER) int identifier, @NonNull String name, @DeviceStateFlags int flags) { - Preconditions.checkArgumentInRange(identifier, MINIMUM_DEVICE_STATE_IDENTIFIER, - MAXIMUM_DEVICE_STATE_IDENTIFIER, - "identifier"); - mIdentifier = identifier; - mName = name; + mDeviceStateConfiguration = new DeviceState.Configuration(identifier, name, + Collections.emptySet(), Collections.emptySet()); 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_IDENTIFIER) public int getIdentifier() { - return mIdentifier; + return mDeviceStateConfiguration.getIdentifier(); } /** Returns a string description of the device state. */ @NonNull public String getName() { - return mName; + return mDeviceStateConfiguration.getName(); } /** @@ -345,10 +362,13 @@ public final class DeviceState { @Override public String toString() { - return "DeviceState{" + "identifier=" + mIdentifier + ", name='" + mName + '\'' - + ", app_accessible=" + !hasProperty(PROPERTY_APP_INACCESSIBLE) + return "DeviceState{" + "identifier=" + mDeviceStateConfiguration.getIdentifier() + + ", name='" + mDeviceStateConfiguration.getName() + '\'' + + ", app_accessible=" + !mDeviceStateConfiguration.getSystemProperties().contains( + PROPERTY_APP_INACCESSIBLE) + ", cancel_when_requester_not_on_top=" - + hasProperty(PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP) + + mDeviceStateConfiguration.getSystemProperties().contains( + PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP) + "}"; } @@ -357,14 +377,12 @@ public final class DeviceState { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; DeviceState that = (DeviceState) o; - return mIdentifier == that.mIdentifier - && Objects.equals(mName, that.mName) - && Objects.equals(mProperties, that.mProperties); + return Objects.equals(mDeviceStateConfiguration, that.mDeviceStateConfiguration); } @Override public int hashCode() { - return Objects.hash(mIdentifier, mName, mProperties); + return Objects.hash(mDeviceStateConfiguration); } /** Checks if a specific flag is set @@ -381,7 +399,8 @@ public final class DeviceState { * Checks if a specific property is set on this state */ public boolean hasProperty(@DeviceStateProperties int propertyToCheckFor) { - return mProperties.contains(propertyToCheckFor); + return mDeviceStateConfiguration.mSystemProperties.contains(propertyToCheckFor) + || mDeviceStateConfiguration.mPhysicalProperties.contains(propertyToCheckFor); } /** @@ -389,10 +408,145 @@ public final class DeviceState { */ public boolean hasProperties(@NonNull @DeviceStateProperties int... properties) { for (int i = 0; i < properties.length; i++) { - if (mProperties.contains(properties[i])) { + if (!mDeviceStateConfiguration.mSystemProperties.contains(properties[i]) + || !mDeviceStateConfiguration.mPhysicalProperties.contains(properties[i])) { return false; } } return true; } + + /** + * Returns the underlying {@link DeviceState.Configuration} object used to model the + * device state. + * @hide + */ + public Configuration getConfiguration() { + return mDeviceStateConfiguration; + } + + /** + * Detailed description of a {@link DeviceState} that includes separated sets of + * {@link DeviceStateProperties} for properties that correspond to the state of the system when + * the device is in this state, as well as physical properties that describe this state. + * + * Instantiation of this class should only be done by the system server, and clients of + * {@link DeviceStateManager} will receive {@link DeviceState} objects. + * + * @see DeviceStateManager + * @hide + */ + public static class Configuration { + /** Unique identifier for the device state. */ + @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER, to = MAXIMUM_DEVICE_STATE_IDENTIFIER) + private final int mIdentifier; + + /** String description of the device state. */ + @NonNull + private final String mName; + + /** {@link Set} of system properties that apply to this state. */ + @NonNull + private final Set<@SystemDeviceStateProperties Integer> mSystemProperties; + + /** {@link Set} of physical device properties that apply to this state. */ + @NonNull + private final Set<@PhysicalDeviceStateProperties Integer> mPhysicalProperties; + + private Configuration(int identifier, @NonNull String name, + @NonNull Set<@SystemDeviceStateProperties Integer> systemProperties, + @NonNull Set<@PhysicalDeviceStateProperties Integer> physicalProperties) { + mIdentifier = identifier; + mName = name; + mSystemProperties = systemProperties; + mPhysicalProperties = physicalProperties; + } + + /** Returns the unique identifier for the device state. */ + public int getIdentifier() { + return mIdentifier; + } + + /** Returns a string description of the device state. */ + @NonNull + public String getName() { + return mName; + } + + /** Returns the {@link Set} of system properties that apply to this state. */ + @NonNull + public Set<@SystemDeviceStateProperties Integer> getSystemProperties() { + return mSystemProperties; + } + + /** Returns the {@link Set} of physical device properties that apply to this state. */ + @NonNull + public Set<@DeviceStateProperties Integer> getPhysicalProperties() { + return mPhysicalProperties; + } + + @Override + public String toString() { + return "DeviceState{" + "identifier=" + mIdentifier + + ", name='" + mName + '\'' + + ", app_accessible=" + mSystemProperties.contains(PROPERTY_APP_INACCESSIBLE) + + ", cancel_when_requester_not_on_top=" + + mSystemProperties.contains(PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP) + + "}"; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + DeviceState.Configuration that = (DeviceState.Configuration) o; + return mIdentifier == that.mIdentifier + && Objects.equals(mName, that.mName) + && Objects.equals(mSystemProperties, that.mSystemProperties) + && Objects.equals(mPhysicalProperties, that.mPhysicalProperties); + } + + @Override + public int hashCode() { + return Objects.hash(mIdentifier, mName, mSystemProperties, mPhysicalProperties); + } + + /** @hide */ + public static class Builder { + private final int mIdentifier; + private final String mName; + private Set<@SystemDeviceStateProperties Integer> mSystemProperties = + Collections.emptySet(); + private Set<@PhysicalDeviceStateProperties Integer> mPhysicalProperties = + Collections.emptySet(); + + public Builder(int identifier, String name) { + mIdentifier = identifier; + mName = name; + } + + /** Sets the system properties for this {@link DeviceState.Configuration.Builder} */ + public Builder setSystemProperties( + Set<@SystemDeviceStateProperties Integer> systemProperties) { + mSystemProperties = systemProperties; + return this; + } + + /** Sets the system properties for this {@link DeviceState.Configuration.Builder} */ + public Builder setPhysicalProperties( + Set<@PhysicalDeviceStateProperties Integer> physicalProperties) { + mPhysicalProperties = physicalProperties; + return this; + } + + /** + * Returns a new {@link DeviceState.Configuration} whose values match the values set on + * the builder. + */ + public DeviceState.Configuration build() { + return new DeviceState.Configuration(mIdentifier, mName, mSystemProperties, + mPhysicalProperties); + } + } + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/FoldableTestUtils.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/FoldableTestUtils.kt index e499a3c6c2eb..e4a1c2680658 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/unfold/util/FoldableTestUtils.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/util/FoldableTestUtils.kt @@ -30,16 +30,22 @@ object FoldableTestUtils { assumeTrue("Test should be launched on a foldable device", foldedDeviceStates.isNotEmpty()) - val folded = - DeviceState(foldedDeviceStates.maxOrNull()!! /* identifier */, - "" /* name */, - emptySet() /* properties */) - val unfolded = - DeviceState(folded.identifier + 1 /* identifier */, - "" /* name */, - emptySet() /* properties */) + val folded = getDeviceState( + identifier = foldedDeviceStates.maxOrNull()!! + ) + val unfolded = getDeviceState( + identifier = folded.identifier + 1 + ) return FoldableDeviceStates(folded = folded, unfolded = unfolded) } + + private fun getDeviceState(identifier: Int): DeviceState { + return DeviceState( + DeviceState.Configuration.Builder( + identifier, "" /* name */ + ).build() + ) + } } data class FoldableDeviceStates(val folded: DeviceState, val unfolded: DeviceState)
\ No newline at end of file diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java index 38051c13049c..af6bdea86ba1 100644 --- a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java +++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java @@ -19,7 +19,8 @@ package com.android.server.devicestate; import static android.Manifest.permission.CONTROL_DEVICE_STATE; import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; import static android.content.pm.PackageManager.PERMISSION_GRANTED; -import static android.hardware.devicestate.DeviceState.FLAG_CANCEL_OVERRIDE_REQUESTS; +import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS; +import static android.hardware.devicestate.DeviceState.PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP; import static android.hardware.devicestate.DeviceStateManager.INVALID_DEVICE_STATE; import static android.hardware.devicestate.DeviceStateManager.MAXIMUM_DEVICE_STATE_IDENTIFIER; import static android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE_IDENTIFIER; @@ -408,7 +409,7 @@ public final class DeviceStateManagerService extends SystemService { mDeviceStates.clear(); for (int i = 0; i < supportedDeviceStates.length; i++) { DeviceState state = supportedDeviceStates[i]; - if (state.hasFlag(FLAG_CANCEL_OVERRIDE_REQUESTS)) { + if (state.hasProperty(PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS)) { hasTerminalDeviceState = true; } mDeviceStates.put(state.getIdentifier(), state); @@ -453,7 +454,7 @@ public final class DeviceStateManagerService extends SystemService { * Returns the {@link DeviceState} with the supplied {@code identifier}, or {@code null} if * there is no device state with the identifier. */ - @Nullable + @NonNull private Optional<DeviceState> getStateLocked(int identifier) { return Optional.ofNullable(mDeviceStates.get(identifier)); } @@ -468,7 +469,7 @@ public final class DeviceStateManagerService extends SystemService { private void setBaseState(int identifier) { synchronized (mLock) { final Optional<DeviceState> baseStateOptional = getStateLocked(identifier); - if (!baseStateOptional.isPresent()) { + if (baseStateOptional.isEmpty()) { throw new IllegalArgumentException("Base state is not supported"); } @@ -484,7 +485,7 @@ public final class DeviceStateManagerService extends SystemService { } mBaseState = Optional.of(baseState); - if (baseState.hasFlag(FLAG_CANCEL_OVERRIDE_REQUESTS)) { + if (baseState.hasProperty(PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS)) { mOverrideRequestController.cancelOverrideRequest(); } mOverrideRequestController.handleBaseStateChanged(identifier); @@ -1023,7 +1024,7 @@ public final class DeviceStateManagerService extends SystemService { } private Set<Integer> readFoldedStates() { - Set<Integer> foldedStates = new HashSet(); + Set<Integer> foldedStates = new HashSet<>(); int[] mFoldedStatesArray = getContext().getResources().getIntArray( com.android.internal.R.array.config_foldedDeviceStates); for (int i = 0; i < mFoldedStatesArray.length; i++) { @@ -1338,7 +1339,7 @@ public final class DeviceStateManagerService extends SystemService { } int identifier = mActiveOverride.get().getRequestedStateIdentifier(); DeviceState deviceState = mDeviceStates.get(identifier); - return deviceState.hasFlag(DeviceState.FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP); + return deviceState.hasProperty(PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP); } private class OverrideRequestScreenObserver implements diff --git a/services/core/java/com/android/server/devicestate/DeviceStateProvider.java b/services/core/java/com/android/server/devicestate/DeviceStateProvider.java index b865c1d90a49..8d07609cef30 100644 --- a/services/core/java/com/android/server/devicestate/DeviceStateProvider.java +++ b/services/core/java/com/android/server/devicestate/DeviceStateProvider.java @@ -28,8 +28,8 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; /** - * Responsible for providing the set of supported {@link DeviceState device states} as well as the - * current device state. + * Responsible for providing the set of supported {@link DeviceState.Configuration device states} as + * well as the current device state. * * @see DeviceStatePolicy */ diff --git a/services/core/java/com/android/server/devicestate/OverrideRequest.java b/services/core/java/com/android/server/devicestate/OverrideRequest.java index d92629f77a95..df7301eee93e 100644 --- a/services/core/java/com/android/server/devicestate/OverrideRequest.java +++ b/services/core/java/com/android/server/devicestate/OverrideRequest.java @@ -72,8 +72,9 @@ final class OverrideRequest { @Retention(RetentionPolicy.SOURCE) public @interface OverrideRequestType {} - OverrideRequest(IBinder token, int pid, int uid, @NonNull DeviceState requestedState, - @DeviceStateRequest.RequestFlags int flags, @OverrideRequestType int requestType) { + OverrideRequest(IBinder token, int pid, int uid, + @NonNull DeviceState requestedState, @DeviceStateRequest.RequestFlags int flags, + @OverrideRequestType int requestType) { mToken = token; mPid = pid; mUid = uid; diff --git a/services/core/java/com/android/server/devicestate/OverrideRequestController.java b/services/core/java/com/android/server/devicestate/OverrideRequestController.java index 6c3fd83d17a0..041ab3ad9d2d 100644 --- a/services/core/java/com/android/server/devicestate/OverrideRequestController.java +++ b/services/core/java/com/android/server/devicestate/OverrideRequestController.java @@ -205,8 +205,8 @@ final class OverrideRequestController { } if (mRequest != null && mRequest.getPid() == pid) { - if (mRequest.getRequestedDeviceState().hasFlag( - DeviceState.FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP)) { + if (mRequest.getRequestedDeviceState().hasProperty( + DeviceState.PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP)) { cancelCurrentRequestLocked(); return; } diff --git a/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java b/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java index 1b220a0b1485..8670a96b2448 100644 --- a/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java +++ b/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java @@ -45,9 +45,9 @@ import com.android.server.devicestate.DeviceStateProvider; import com.android.server.input.InputManagerInternal; import com.android.server.policy.devicestate.config.Conditions; import com.android.server.policy.devicestate.config.DeviceStateConfig; -import com.android.server.policy.devicestate.config.Flags; import com.android.server.policy.devicestate.config.LidSwitchCondition; import com.android.server.policy.devicestate.config.NumericRange; +import com.android.server.policy.devicestate.config.Properties; import com.android.server.policy.devicestate.config.SensorCondition; import com.android.server.policy.devicestate.config.XmlParser; @@ -63,8 +63,10 @@ import java.math.BigDecimal; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import java.util.function.BooleanSupplier; import javax.xml.datatype.DatatypeConfigurationException; @@ -94,21 +96,49 @@ 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_IDENTIFIER, - "DEFAULT", 0 /* flags */); + static final DeviceState DEFAULT_DEVICE_STATE = + new DeviceState(new DeviceState.Configuration.Builder(MINIMUM_DEVICE_STATE_IDENTIFIER, + "DEFAULT").build()); private static final String VENDOR_CONFIG_FILE_PATH = "etc/devicestate/"; private static final String DATA_CONFIG_FILE_PATH = "system/devicestate/"; private static final String CONFIG_FILE_NAME = "device_state_configuration.xml"; - private static final String FLAG_CANCEL_OVERRIDE_REQUESTS = "FLAG_CANCEL_OVERRIDE_REQUESTS"; - private static final String FLAG_APP_INACCESSIBLE = "FLAG_APP_INACCESSIBLE"; - private static final String FLAG_EMULATED_ONLY = "FLAG_EMULATED_ONLY"; - private static final String FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP = - "FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP"; - private static final String FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL = - "FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL"; - private static final String FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE = - "FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE"; + private static final String PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED = + "com.android.server.policy.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED"; + private static final String PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN = + "com.android.server.policy.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN"; + private static final String PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN = + "com.android.server.policy.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN"; + private static final String PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS = + "com.android.server.policy.PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS"; + private static final String PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP = + "com.android.server.policy.PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP"; + private static final String PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL = + "com.android.server.policy.PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL"; + private static final String PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE = + "com.android.server.policy.PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE"; + private static final String PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST = + "com.android.server.policy.PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST"; + private static final String PROPERTY_APP_INACCESSIBLE = + "com.android.server.policy.PROPERTY_APP_INACCESSIBLE"; + private static final String PROPERTY_EMULATED_ONLY = + "com.android.server.policy.PROPERTY_EMULATED_ONLY"; + private static final String PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY = + "com.android.server.policy.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY"; + private static final String PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY = + "com.android.server.policy.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY"; + private static final String PROPERTY_POWER_CONFIGURATION_TRIGGER_SLEEP = + "com.android.server.policy.PROPERTY_POWER_CONFIGURATION_TRIGGER_SLEEP"; + private static final String PROPERTY_POWER_CONFIGURATION_TRIGGER_WAKE = + "com.android.server.policy.PROPERTY_POWER_CONFIGURATION_TRIGGER_WAKE"; + private static final String PROPERTY_EXTENDED_DEVICE_STATE_EXTERNAL_DISPLAY = + "com.android.server.policy.PROPERTY_EXTENDED_DEVICE_STATE_EXTERNAL_DISPLAY"; + private static final String PROPERTY_FEATURE_REAR_DISPLAY = + "com.android.server.policy.PROPERTY_FEATURE_REAR_DISPLAY"; + private static final String PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT = + "com.android.server.policy.PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT"; + + /** Interface that allows reading the device state configuration. */ interface ReadableConfig { @@ -149,40 +179,25 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider, final int state = stateConfig.getIdentifier().intValue(); final String name = stateConfig.getName() == null ? "" : stateConfig.getName(); - int flags = 0; - final Flags configFlags = stateConfig.getFlags(); + Set<@DeviceState.DeviceStateProperties Integer> systemProperties = + new HashSet<>(); + Set<@DeviceState.DeviceStateProperties Integer> physicalProperties = + new HashSet<>(); + final Properties configFlags = stateConfig.getProperties(); if (configFlags != null) { - List<String> configFlagStrings = configFlags.getFlag(); - for (int i = 0; i < configFlagStrings.size(); i++) { - final String configFlagString = configFlagStrings.get(i); - switch (configFlagString) { - case FLAG_CANCEL_OVERRIDE_REQUESTS: - flags |= DeviceState.FLAG_CANCEL_OVERRIDE_REQUESTS; - break; - case FLAG_APP_INACCESSIBLE: - flags |= DeviceState.FLAG_APP_INACCESSIBLE; - break; - case FLAG_EMULATED_ONLY: - flags |= DeviceState.FLAG_EMULATED_ONLY; - break; - case FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP: - flags |= DeviceState.FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP; - break; - case FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL: - flags |= DeviceState - .FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL; - break; - case FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE: - flags |= DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE; - default: - Slog.w(TAG, "Parsed unknown flag with name: " - + configFlagString); - break; - } + List<String> configPropertyStrings = configFlags.getProperty(); + for (int i = 0; i < configPropertyStrings.size(); i++) { + final String configPropertyString = configPropertyStrings.get(i); + addPropertyByString(configPropertyString, systemProperties, + physicalProperties); } } - - deviceStateList.add(new DeviceState(state, name, flags)); + DeviceState.Configuration deviceStateConfiguration = + new DeviceState.Configuration.Builder(state, name) + .setSystemProperties(systemProperties) + .setPhysicalProperties(physicalProperties) + .build(); + deviceStateList.add(new DeviceState(deviceStateConfiguration)); final Conditions condition = stateConfig.getConditions(); conditionsList.add(condition); @@ -190,13 +205,88 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider, } } - if (deviceStateList.size() == 0) { + if (deviceStateList.isEmpty()) { deviceStateList.add(DEFAULT_DEVICE_STATE); conditionsList.add(null); } return new DeviceStateProviderImpl(context, deviceStateList, conditionsList); } + private static void addPropertyByString(String propertyString, + Set<@DeviceState.SystemDeviceStateProperties Integer> systemProperties, + Set<@DeviceState.PhysicalDeviceStateProperties Integer> physicalProperties) { + switch (propertyString) { + // Look for the physical hardware properties first + case PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED: + physicalProperties.add( + DeviceState.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED); + break; + case PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN: + physicalProperties.add( + DeviceState.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN); + break; + case PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN: + physicalProperties.add( + DeviceState.PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN); + break; + case PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS: + systemProperties.add( + DeviceState.PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS); + break; + case PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP: + systemProperties.add( + DeviceState.PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP); + break; + case PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL: + systemProperties.add( + DeviceState.PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL); + break; + case PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE: + systemProperties.add( + DeviceState.PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE); + break; + case PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST: + systemProperties.add( + DeviceState.PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST); + break; + case PROPERTY_APP_INACCESSIBLE: + systemProperties.add(DeviceState.PROPERTY_APP_INACCESSIBLE); + break; + case PROPERTY_EMULATED_ONLY: + systemProperties.add(DeviceState.PROPERTY_EMULATED_ONLY); + break; + case PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY: + systemProperties.add( + DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY); + break; + case PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY: + systemProperties.add( + DeviceState.PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY); + break; + case PROPERTY_POWER_CONFIGURATION_TRIGGER_SLEEP: + systemProperties.add( + DeviceState.PROPERTY_POWER_CONFIGURATION_TRIGGER_SLEEP); + break; + case PROPERTY_POWER_CONFIGURATION_TRIGGER_WAKE: + systemProperties.add( + DeviceState.PROPERTY_POWER_CONFIGURATION_TRIGGER_WAKE); + break; + case PROPERTY_EXTENDED_DEVICE_STATE_EXTERNAL_DISPLAY: + systemProperties.add( + DeviceState.PROPERTY_EXTENDED_DEVICE_STATE_EXTERNAL_DISPLAY); + break; + case PROPERTY_FEATURE_REAR_DISPLAY: + systemProperties.add(DeviceState.PROPERTY_FEATURE_REAR_DISPLAY); + break; + case PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT: + systemProperties.add(DeviceState.PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT); + break; + default: + Slog.w(TAG, "Parsed unknown flag with name: " + propertyString); + break; + } + } + // Lock for internal state. private final Object mLock = new Object(); private final Context mContext; @@ -285,7 +375,7 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider, if (conditions == null) { // If this state has the FLAG_EMULATED_ONLY flag on it, it should never be triggered // by a physical hardware change, and should always return false for it's conditions - if (deviceStates.get(i).hasFlag(DeviceState.FLAG_EMULATED_ONLY)) { + if (deviceStates.get(i).hasProperty(DeviceState.PROPERTY_EMULATED_ONLY)) { mStateConditions.put(state, FALSE_BOOLEAN_SUPPLIER); } else { mStateConditions.put(state, TRUE_BOOLEAN_SUPPLIER); @@ -410,13 +500,13 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider, } listener = mListener; for (DeviceState deviceState : mOrderedStates) { - if (isThermalStatusCriticalOrAbove(mThermalStatus) - && deviceState.hasFlag( - DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL)) { + if (isThermalStatusCriticalOrAbove(mThermalStatus) && deviceState.hasProperty( + DeviceState.PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL + )) { continue; } - if (mPowerSaveModeEnabled && deviceState.hasFlag( - DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE)) { + if (mPowerSaveModeEnabled && deviceState.hasProperty( + DeviceState.PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE)) { continue; } supportedStates.add(deviceState); @@ -424,7 +514,8 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider, } listener.onSupportedDeviceStatesChanged( - supportedStates.toArray(new DeviceState[supportedStates.size()]), reason); + supportedStates.toArray(new DeviceState[supportedStates.size()]), + reason); } /** Computes the current device state and notifies the listener of a change, if needed. */ @@ -774,8 +865,9 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider, } private static boolean hasThermalSensitiveState(List<DeviceState> deviceStates) { - for (DeviceState state : deviceStates) { - if (state.hasFlag(DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL)) { + for (int i = 0; i < deviceStates.size(); i++) { + if (deviceStates.get(i).hasProperty( + DeviceState.PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL)) { return true; } } @@ -784,7 +876,8 @@ public final class DeviceStateProviderImpl implements DeviceStateProvider, private static boolean hasPowerSaveSensitiveState(List<DeviceState> deviceStates) { for (int i = 0; i < deviceStates.size(); i++) { - if (deviceStates.get(i).hasFlag(DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE)) { + if (deviceStates.get(i).hasProperty( + DeviceState.PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE)) { return true; } } diff --git a/services/core/xsd/device-state-config/device-state-config.xsd b/services/core/xsd/device-state-config/device-state-config.xsd index 86f41769008d..4a947327070a 100644 --- a/services/core/xsd/device-state-config/device-state-config.xsd +++ b/services/core/xsd/device-state-config/device-state-config.xsd @@ -40,14 +40,14 @@ <xs:element name="name" type="xs:string" minOccurs="0"> <xs:annotation name="nullable" /> </xs:element> - <xs:element name="flags" type="flags" /> + <xs:element name="properties" type="properties" /> <xs:element name="conditions" type="conditions" /> </xs:sequence> </xs:complexType> - <xs:complexType name="flags"> + <xs:complexType name="properties"> <xs:sequence> - <xs:element name="flag" type="xs:string" minOccurs="0" maxOccurs="unbounded"> + <xs:element name="property" type="xs:string" minOccurs="0" maxOccurs="unbounded"> <xs:annotation name="nullable" /> </xs:element> </xs:sequence> diff --git a/services/core/xsd/device-state-config/schema/current.txt b/services/core/xsd/device-state-config/schema/current.txt index a98d4e569cd6..5bb216e69e4d 100644 --- a/services/core/xsd/device-state-config/schema/current.txt +++ b/services/core/xsd/device-state-config/schema/current.txt @@ -11,13 +11,13 @@ package com.android.server.policy.devicestate.config { public class DeviceState { ctor public DeviceState(); method public com.android.server.policy.devicestate.config.Conditions getConditions(); - method public com.android.server.policy.devicestate.config.Flags getFlags(); method public java.math.BigInteger getIdentifier(); method @Nullable public String getName(); + method public com.android.server.policy.devicestate.config.Properties getProperties(); method public void setConditions(com.android.server.policy.devicestate.config.Conditions); - method public void setFlags(com.android.server.policy.devicestate.config.Flags); method public void setIdentifier(java.math.BigInteger); method public void setName(@Nullable String); + method public void setProperties(com.android.server.policy.devicestate.config.Properties); } public class DeviceStateConfig { @@ -25,11 +25,6 @@ package com.android.server.policy.devicestate.config { method public java.util.List<com.android.server.policy.devicestate.config.DeviceState> getDeviceState(); } - public class Flags { - ctor public Flags(); - method @Nullable public java.util.List<java.lang.String> getFlag(); - } - public class LidSwitchCondition { ctor public LidSwitchCondition(); method public boolean getOpen(); @@ -48,6 +43,11 @@ package com.android.server.policy.devicestate.config { method public void setMin_optional(@Nullable java.math.BigDecimal); } + public class Properties { + ctor public Properties(); + method @Nullable public java.util.List<java.lang.String> getProperty(); + } + public class SensorCondition { ctor public SensorCondition(); method public String getName(); diff --git a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java index b7050771d2e4..9130adca34b4 100644 --- a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java +++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateManagerServiceTest.java @@ -57,6 +57,8 @@ import org.junit.runner.RunWith; import java.io.PrintWriter; import java.util.Arrays; import java.util.HashMap; +import java.util.HashSet; +import java.util.List; import java.util.Optional; import javax.annotation.Nullable; @@ -69,17 +71,21 @@ import javax.annotation.Nullable; @Presubmit @RunWith(AndroidJUnit4.class) public final class DeviceStateManagerServiceTest { - private static final DeviceState DEFAULT_DEVICE_STATE = - new DeviceState(0, "DEFAULT", 0 /* flags */); - private static final DeviceState OTHER_DEVICE_STATE = - new DeviceState(1, "OTHER", 0 /* flags */); - private static final DeviceState - DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP = - new DeviceState(2, "DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP", - DeviceState.FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP /* flags */); + private static final DeviceState DEFAULT_DEVICE_STATE = new DeviceState( + new DeviceState.Configuration.Builder(0, "DEFAULT").build()); + private static final DeviceState OTHER_DEVICE_STATE = new DeviceState( + new DeviceState.Configuration.Builder(1, "DEFAULT").build()); + private static final DeviceState DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP = + new DeviceState(new DeviceState.Configuration.Builder(2, + "DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP") + .setSystemProperties(new HashSet<>(List.of( + DeviceState.PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP))) + .build()); + // A device state that is not reported as being supported for the default test provider. - private static final DeviceState UNSUPPORTED_DEVICE_STATE = - new DeviceState(255, "UNSUPPORTED", 0 /* flags */); + private static final DeviceState UNSUPPORTED_DEVICE_STATE = new DeviceState( + new DeviceState.Configuration.Builder(255, "UNSUPPORTED") + .build()); private static final int[] SUPPORTED_DEVICE_STATE_IDENTIFIERS = new int[]{DEFAULT_DEVICE_STATE.getIdentifier(), OTHER_DEVICE_STATE.getIdentifier(), @@ -201,9 +207,8 @@ public final class DeviceStateManagerServiceTest { @Test public void baseStateChanged_invalidState() { - assertThrows(IllegalArgumentException.class, () -> { - mProvider.setState(INVALID_DEVICE_STATE); - }); + assertThrows(IllegalArgumentException.class, + () -> mProvider.setState(INVALID_DEVICE_STATE)); assertEquals(mService.getCommittedState(), Optional.of(DEFAULT_DEVICE_STATE)); assertEquals(mService.getPendingState(), Optional.empty()); @@ -636,7 +641,8 @@ public final class DeviceStateManagerServiceTest { assertEquals(mPolicy.getMostRecentRequestedStateToConfigure(), OTHER_DEVICE_STATE.getIdentifier()); - mProvider.notifySupportedDeviceStates(new DeviceState[]{ DEFAULT_DEVICE_STATE }); + mProvider.notifySupportedDeviceStates( + new DeviceState[]{DEFAULT_DEVICE_STATE}); flushHandler(); // Request is canceled because the state is no longer supported. @@ -739,11 +745,12 @@ public final class DeviceStateManagerServiceTest { @Test public void requestBaseStateOverride_cancelledByBaseStateUpdate() throws RemoteException { - final DeviceState testDeviceState = new DeviceState(2, "TEST", 0); + final DeviceState testDeviceState = new DeviceState(new DeviceState.Configuration.Builder(2, + "TEST").build()); TestDeviceStateManagerCallback callback = new TestDeviceStateManagerCallback(); mService.getBinderService().registerCallback(callback); - mProvider.notifySupportedDeviceStates( - new DeviceState[]{DEFAULT_DEVICE_STATE, OTHER_DEVICE_STATE, testDeviceState }); + mProvider.notifySupportedDeviceStates(new DeviceState[]{DEFAULT_DEVICE_STATE, + OTHER_DEVICE_STATE, testDeviceState}); flushHandler(); final IBinder token = new Binder(); @@ -892,7 +899,8 @@ public final class DeviceStateManagerServiceTest { * @param isOverrideState whether a state override is active. */ private void assertDeviceStateConditions( - DeviceState state, DeviceState baseState, boolean isOverrideState) { + DeviceState state, DeviceState baseState, + boolean isOverrideState) { assertEquals(mService.getCommittedState(), Optional.of(state)); assertEquals(mService.getBaseState(), Optional.of(baseState)); assertEquals(mSysPropSetter.getValue(), @@ -970,10 +978,11 @@ public final class DeviceStateManagerServiceTest { } private static final class TestDeviceStateProvider implements DeviceStateProvider { - private DeviceState[] mSupportedDeviceStates = new DeviceState[]{ - DEFAULT_DEVICE_STATE, - OTHER_DEVICE_STATE, - DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP}; + private DeviceState[] mSupportedDeviceStates = + new DeviceState[]{ + DEFAULT_DEVICE_STATE, + OTHER_DEVICE_STATE, + DEVICE_STATE_CANCEL_WHEN_REQUESTER_NOT_ON_TOP}; @Nullable private final DeviceState mInitialState; private Listener mListener; diff --git a/services/tests/servicestests/src/com/android/server/devicestate/OverrideRequestControllerTest.java b/services/tests/servicestests/src/com/android/server/devicestate/OverrideRequestControllerTest.java index cfdb5869e020..637bf03c8bcc 100644 --- a/services/tests/servicestests/src/com/android/server/devicestate/OverrideRequestControllerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicestate/OverrideRequestControllerTest.java @@ -49,10 +49,10 @@ import java.util.Map; @RunWith(AndroidJUnit4.class) public final class OverrideRequestControllerTest { - private static final DeviceState - TEST_DEVICE_STATE_ZERO = new DeviceState(0, "TEST_STATE", 0); - private static final DeviceState - TEST_DEVICE_STATE_ONE = new DeviceState(1, "TEST_STATE", 0); + private static final DeviceState TEST_DEVICE_STATE_ZERO = new DeviceState( + new DeviceState.Configuration.Builder(0, "TEST_STATE").build()); + private static final DeviceState TEST_DEVICE_STATE_ONE = new DeviceState( + new DeviceState.Configuration.Builder(1, "TEST_STATE").build()); private TestStatusChangeListener mStatusListener; private OverrideRequestController mController; diff --git a/services/tests/servicestests/src/com/android/server/policy/DeviceStateProviderImplTest.java b/services/tests/servicestests/src/com/android/server/policy/DeviceStateProviderImplTest.java index 16909ab4511e..fad10f7a7553 100644 --- a/services/tests/servicestests/src/com/android/server/policy/DeviceStateProviderImplTest.java +++ b/services/tests/servicestests/src/com/android/server/policy/DeviceStateProviderImplTest.java @@ -60,7 +60,10 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Constructor; +import java.util.Arrays; +import java.util.HashSet; import java.util.List; +import java.util.Set; /** * Unit tests for {@link DeviceStateProviderImpl}. @@ -68,10 +71,15 @@ import java.util.List; * Run with <code>atest DeviceStateProviderImplTest</code>. */ public final class DeviceStateProviderImplTest { - private final ArgumentCaptor<DeviceState[]> mDeviceStateArrayCaptor = ArgumentCaptor.forClass( - DeviceState[].class); + private final ArgumentCaptor<DeviceState[]> mDeviceStateArrayCaptor = + ArgumentCaptor.forClass(DeviceState[].class); private final ArgumentCaptor<Integer> mIntegerCaptor = ArgumentCaptor.forClass(Integer.class); private static final int MAX_HINGE_ANGLE_EXCLUSIVE = 360; + private static final Set<Integer> EMPTY_PROPERTY_SET = new HashSet<>(); + private static final Set<Integer> THERMAL_TEST_PROPERTY_SET = new HashSet<>( + Arrays.asList(DeviceState.PROPERTY_EMULATED_ONLY, + DeviceState.PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL, + DeviceState.PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE)); private Context mContext; private SensorManager mSensorManager; @@ -160,8 +168,8 @@ public final class DeviceStateProviderImplTest { verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture(), eq(SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED)); final DeviceState[] expectedStates = new DeviceState[]{ - new DeviceState(1, "", 0 /* flags */), - new DeviceState(2, "", 0 /* flags */) }; + createDeviceState(1, "", EMPTY_PROPERTY_SET), + createDeviceState(2, "", EMPTY_PROPERTY_SET)}; assertArrayEquals(expectedStates, mDeviceStateArrayCaptor.getValue()); verify(listener).onStateChanged(mIntegerCaptor.capture()); @@ -169,13 +177,13 @@ public final class DeviceStateProviderImplTest { } @Test - public void create_stateWithCancelOverrideRequestFlag() { + public void create_stateWithCancelOverrideRequestProperty() { String configString = "<device-state-config>\n" + " <device-state>\n" + " <identifier>1</identifier>\n" - + " <flags>\n" - + " <flag>FLAG_CANCEL_OVERRIDE_REQUESTS</flag>\n" - + " </flags>\n" + + " <properties>\n" + + " <property>PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS</property>\n" + + " </properties>\n" + " <conditions/>\n" + " </device-state>\n" + " <device-state>\n" @@ -192,20 +200,22 @@ public final class DeviceStateProviderImplTest { verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture(), eq(SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED)); + final DeviceState[] expectedStates = new DeviceState[]{ - new DeviceState(1, "", DeviceState.FLAG_CANCEL_OVERRIDE_REQUESTS), - new DeviceState(2, "", 0 /* flags */) }; + createDeviceState(1, "", new HashSet<>( + List.of(DeviceState.PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS))), + createDeviceState(2, "", EMPTY_PROPERTY_SET)}; assertArrayEquals(expectedStates, mDeviceStateArrayCaptor.getValue()); } @Test - public void create_stateWithInvalidFlag() { + public void create_stateWithInvalidProperty() { String configString = "<device-state-config>\n" + " <device-state>\n" + " <identifier>1</identifier>\n" - + " <flags>\n" - + " <flag>INVALID_FLAG</flag>\n" - + " </flags>\n" + + " <properties>\n" + + " <property>INVALID_PROPERTY</property>\n" + + " </properties>\n" + " <conditions/>\n" + " </device-state>\n" + " <device-state>\n" @@ -223,8 +233,8 @@ public final class DeviceStateProviderImplTest { verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture(), eq(SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED)); final DeviceState[] expectedStates = new DeviceState[]{ - new DeviceState(1, "", 0 /* flags */), - new DeviceState(2, "", 0 /* flags */) }; + createDeviceState(1, "", EMPTY_PROPERTY_SET), + createDeviceState(2, "", EMPTY_PROPERTY_SET)}; assertArrayEquals(expectedStates, mDeviceStateArrayCaptor.getValue()); } @@ -259,8 +269,8 @@ public final class DeviceStateProviderImplTest { verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture(), eq(SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED)); final DeviceState[] expectedStates = new DeviceState[]{ - new DeviceState(1, "", 0 /* flags */), - new DeviceState(2, "CLOSED", 0 /* flags */) }; + createDeviceState(1, "", EMPTY_PROPERTY_SET), + createDeviceState(2, "CLOSED", EMPTY_PROPERTY_SET)}; assertArrayEquals(expectedStates, mDeviceStateArrayCaptor.getValue()); // onStateChanged() should not be called because the provider has not yet been notified of @@ -327,11 +337,13 @@ public final class DeviceStateProviderImplTest { + " <device-state>\n" + " <identifier>4</identifier>\n" + " <name>THERMAL_TEST</name>\n" - + " <flags>\n" - + " <flag>FLAG_EMULATED_ONLY</flag>\n" - + " <flag>FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL</flag>\n" - + " <flag>FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE</flag>\n" - + " </flags>\n" + + " <properties>\n" + + " <property>PROPERTY_EMULATED_ONLY</property>\n" + + " <property>PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL" + + "</property>\n" + + " <property>PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE" + + "</property>\n" + + " </properties>\n" + " </device-state>\n" + "</device-state-config>\n"; DeviceStateProviderImpl.ReadableConfig config = new TestReadableConfig(configString); @@ -352,13 +364,11 @@ public final class DeviceStateProviderImplTest { eq(SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED)); assertArrayEquals( new DeviceState[]{ - new DeviceState(1, "CLOSED", 0 /* flags */), - new DeviceState(2, "HALF_OPENED", 0 /* flags */), - new DeviceState(3, "OPENED", 0 /* flags */), - new DeviceState(4, "THERMAL_TEST", - DeviceState.FLAG_EMULATED_ONLY - | DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL - | DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE) }, + createDeviceState(1, "CLOSED", EMPTY_PROPERTY_SET), + createDeviceState(2, "HALF_OPENED", EMPTY_PROPERTY_SET), + createDeviceState(3, "OPENED", EMPTY_PROPERTY_SET), + createDeviceState(4, "THERMAL_TEST", + THERMAL_TEST_PROPERTY_SET)}, mDeviceStateArrayCaptor.getValue()); // onStateChanged() should not be called because the provider has not yet been notified of // the initial sensor state. @@ -405,7 +415,7 @@ public final class DeviceStateProviderImplTest { } @Test - public void test_flagDisableWhenThermalStatusCritical() throws Exception { + public void test_propertyDisableWhenThermalStatusCritical() throws Exception { Sensor sensor = newSensor("sensor", Sensor.STRING_TYPE_HINGE_ANGLE); when(mSensorManager.getSensorList(anyInt())).thenReturn(List.of(sensor)); DeviceStateProviderImpl provider = create_sensorBasedProvider(sensor); @@ -418,13 +428,11 @@ public final class DeviceStateProviderImplTest { eq(SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED)); assertArrayEquals( new DeviceState[]{ - new DeviceState(1, "CLOSED", 0 /* flags */), - new DeviceState(2, "HALF_OPENED", 0 /* flags */), - new DeviceState(3, "OPENED", 0 /* flags */), - new DeviceState(4, "THERMAL_TEST", - DeviceState.FLAG_EMULATED_ONLY - | DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL - | DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE) }, + createDeviceState(1, "CLOSED", EMPTY_PROPERTY_SET), + createDeviceState(2, "HALF_OPENED", EMPTY_PROPERTY_SET), + createDeviceState(3, "OPENED", EMPTY_PROPERTY_SET), + createDeviceState(4, "THERMAL_TEST", + THERMAL_TEST_PROPERTY_SET)}, mDeviceStateArrayCaptor.getValue()); Mockito.clearInvocations(listener); @@ -439,9 +447,9 @@ public final class DeviceStateProviderImplTest { eq(SUPPORTED_DEVICE_STATES_CHANGED_THERMAL_CRITICAL)); assertArrayEquals( new DeviceState[]{ - new DeviceState(1, "CLOSED", 0 /* flags */), - new DeviceState(2, "HALF_OPENED", 0 /* flags */), - new DeviceState(3, "OPENED", 0 /* flags */) }, + createDeviceState(1, "CLOSED", EMPTY_PROPERTY_SET), + createDeviceState(2, "HALF_OPENED", EMPTY_PROPERTY_SET), + createDeviceState(3, "OPENED", EMPTY_PROPERTY_SET)}, mDeviceStateArrayCaptor.getValue()); Mockito.clearInvocations(listener); @@ -451,18 +459,16 @@ public final class DeviceStateProviderImplTest { eq(SUPPORTED_DEVICE_STATES_CHANGED_THERMAL_NORMAL)); assertArrayEquals( new DeviceState[]{ - new DeviceState(1, "CLOSED", 0 /* flags */), - new DeviceState(2, "HALF_OPENED", 0 /* flags */), - new DeviceState(3, "OPENED", 0 /* flags */), - new DeviceState(4, "THERMAL_TEST", - DeviceState.FLAG_EMULATED_ONLY - | DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL - | DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE) }, + createDeviceState(1, "CLOSED", EMPTY_PROPERTY_SET), + createDeviceState(2, "HALF_OPENED", EMPTY_PROPERTY_SET), + createDeviceState(3, "OPENED", EMPTY_PROPERTY_SET), + createDeviceState(4, "THERMAL_TEST", + THERMAL_TEST_PROPERTY_SET)}, mDeviceStateArrayCaptor.getValue()); } @Test - public void test_flagDisableWhenPowerSaveEnabled() throws Exception { + public void test_propertyDisableWhenPowerSaveEnabled() throws Exception { Sensor sensor = newSensor("sensor", Sensor.STRING_TYPE_HINGE_ANGLE); when(mSensorManager.getSensorList(anyInt())).thenReturn(List.of(sensor)); DeviceStateProviderImpl provider = create_sensorBasedProvider(sensor); @@ -475,13 +481,11 @@ public final class DeviceStateProviderImplTest { eq(SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED)); assertArrayEquals( new DeviceState[]{ - new DeviceState(1, "CLOSED", 0 /* flags */), - new DeviceState(2, "HALF_OPENED", 0 /* flags */), - new DeviceState(3, "OPENED", 0 /* flags */), - new DeviceState(4, "THERMAL_TEST", - DeviceState.FLAG_EMULATED_ONLY - | DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL - | DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE) }, + createDeviceState(1, "CLOSED", EMPTY_PROPERTY_SET), + createDeviceState(2, "HALF_OPENED", EMPTY_PROPERTY_SET), + createDeviceState(3, "OPENED", EMPTY_PROPERTY_SET), + createDeviceState(4, "THERMAL_TEST", + THERMAL_TEST_PROPERTY_SET)}, mDeviceStateArrayCaptor.getValue()); Mockito.clearInvocations(listener); @@ -496,9 +500,9 @@ public final class DeviceStateProviderImplTest { eq(SUPPORTED_DEVICE_STATES_CHANGED_POWER_SAVE_ENABLED)); assertArrayEquals( new DeviceState[]{ - new DeviceState(1, "CLOSED", 0 /* flags */), - new DeviceState(2, "HALF_OPENED", 0 /* flags */), - new DeviceState(3, "OPENED", 0 /* flags */) }, + createDeviceState(1, "CLOSED", EMPTY_PROPERTY_SET), + createDeviceState(2, "HALF_OPENED", EMPTY_PROPERTY_SET), + createDeviceState(3, "OPENED", EMPTY_PROPERTY_SET)}, mDeviceStateArrayCaptor.getValue()); Mockito.clearInvocations(listener); @@ -508,13 +512,11 @@ public final class DeviceStateProviderImplTest { eq(SUPPORTED_DEVICE_STATES_CHANGED_POWER_SAVE_DISABLED)); assertArrayEquals( new DeviceState[]{ - new DeviceState(1, "CLOSED", 0 /* flags */), - new DeviceState(2, "HALF_OPENED", 0 /* flags */), - new DeviceState(3, "OPENED", 0 /* flags */), - new DeviceState(4, "THERMAL_TEST", - DeviceState.FLAG_EMULATED_ONLY - | DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL - | DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE) }, + createDeviceState(1, "CLOSED", EMPTY_PROPERTY_SET), + createDeviceState(2, "HALF_OPENED", EMPTY_PROPERTY_SET), + createDeviceState(3, "OPENED", EMPTY_PROPERTY_SET), + createDeviceState(4, "THERMAL_TEST", + THERMAL_TEST_PROPERTY_SET)}, mDeviceStateArrayCaptor.getValue()); } @@ -598,13 +600,22 @@ public final class DeviceStateProviderImplTest { eq(SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED)); assertArrayEquals( new DeviceState[]{ - new DeviceState(1, "CLOSED", 0 /* flags */), - new DeviceState(2, "HALF_OPENED", 0 /* flags */) + createDeviceState(1, "CLOSED", EMPTY_PROPERTY_SET), + createDeviceState(2, "HALF_OPENED", EMPTY_PROPERTY_SET) }, mDeviceStateArrayCaptor.getValue()); // onStateChanged() should not be called because the provider could not find the sensor. verify(listener, never()).onStateChanged(mIntegerCaptor.capture()); } + private DeviceState createDeviceState(int identifier, @NonNull String name, + @NonNull Set<@DeviceState.DeviceStateProperties Integer> systemProperties) { + DeviceState.Configuration configuration = new DeviceState.Configuration.Builder(identifier, + name) + .setSystemProperties(systemProperties) + .build(); + return new DeviceState(configuration); + } + private static Sensor newSensor(String name, String type) throws Exception { Constructor<Sensor> constructor = Sensor.class.getDeclaredConstructor(); constructor.setAccessible(true); |