1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.hardware.devicestate; 18 19 import static android.hardware.devicestate.DeviceStateManager.MAXIMUM_DEVICE_STATE_IDENTIFIER; 20 import static android.hardware.devicestate.DeviceStateManager.MINIMUM_DEVICE_STATE_IDENTIFIER; 21 22 import android.annotation.FlaggedApi; 23 import android.annotation.IntDef; 24 import android.annotation.IntRange; 25 import android.annotation.NonNull; 26 import android.annotation.SystemApi; 27 import android.annotation.TestApi; 28 import android.os.Parcel; 29 import android.os.Parcelable; 30 import android.util.ArraySet; 31 32 import java.lang.annotation.ElementType; 33 import java.lang.annotation.Retention; 34 import java.lang.annotation.RetentionPolicy; 35 import java.lang.annotation.Target; 36 import java.util.Collections; 37 import java.util.Objects; 38 import java.util.Set; 39 40 /** 41 * A state of the device managed by {@link DeviceStateManager}. 42 * <p> 43 * Device state is an abstract concept that allows mapping the current state of the device to the 44 * state of the system. This is useful for variable-state devices, like foldable or rollable 45 * devices, that can be configured by users into differing hardware states, which each may have a 46 * different expected use case. 47 * 48 * @hide 49 * @see DeviceStateManager 50 */ 51 @SystemApi 52 @FlaggedApi(android.hardware.devicestate.feature.flags.Flags.FLAG_DEVICE_STATE_PROPERTY_API) 53 public final class DeviceState { 54 /** 55 * Property that indicates that a fold-in style foldable device is currently in a fully closed 56 * configuration. 57 */ 58 public static final int PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED = 1; 59 60 /** 61 * Property that indicates that a fold-in style foldable device is currently in a half-opened 62 * configuration. This signifies that the device's hinge is positioned somewhere around 90 63 * degrees. Checking for display configuration properties as well can provide information 64 * on which display is currently active. 65 */ 66 public static final int PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN = 2; 67 68 /** 69 * Property that indicates that a fold-in style foldable device is currently in a fully open 70 * configuration. 71 */ 72 public static final int PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN = 3; 73 74 /** 75 * Property that indicates override requests should be cancelled when the device is physically 76 * put into this state. 77 * @hide 78 */ 79 public static final int PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS = 4; 80 81 /** 82 * This property indicates that the corresponding state should be automatically canceled when 83 * the requesting app is no longer on top. The app is considered not on top when (1) the top 84 * activity in the system is from a different app, (2) the device is in sleep mode, or 85 * (3) the keyguard shows up. 86 * @hide 87 */ 88 public static final int PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP = 5; 89 90 /** 91 * This property indicates that the corresponding state should be disabled when the device is 92 * overheating and reaching the critical status. 93 * @hide 94 */ 95 public static final int PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL = 6; 96 97 /** 98 * This property indicates that the corresponding state should be disabled when power save mode 99 * is enabled. 100 * @hide 101 */ 102 public static final int PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE = 7; 103 104 /** 105 * This property denotes that this state is available for applications to request and the system 106 * server should deny any request that comes from a process that does not hold the 107 * CONTROL_DEVICE_STATE permission if it is requesting a state that does not have this property 108 * on it. 109 * @hide 110 */ 111 @TestApi 112 public static final int PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST = 8; 113 114 /** 115 * Property that indicates this device state is inaccessible for applications to be made 116 * visible to the user. This could be a device-state where the {@link Display#DEFAULT_DISPLAY} 117 * is not enabled. 118 * @hide 119 */ 120 public static final int PROPERTY_APP_INACCESSIBLE = 9; 121 122 /** 123 * This property indidcates that this state can only be entered through emulation and has no 124 * physical configuration to match. 125 */ 126 public static final int PROPERTY_EMULATED_ONLY = 10; 127 128 /** 129 * Property that indicates that the outer display area of a foldable device is currently the 130 * primary display area. 131 * 132 * Note: This does not necessarily mean that the outer display area is the 133 * {@link Display#DEFAULT_DISPLAY}. 134 */ 135 public static final int PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY = 11; 136 137 /** 138 * Property that indicates that the inner display area of a foldable device is currently the 139 * primary display area. 140 * 141 * Note: This does not necessarily mean that the inner display area is the 142 * {@link Display#DEFAULT_DISPLAY}. 143 */ 144 public static final int PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY = 12; 145 146 /** 147 * Property that indicates that this device state will attempt to trigger the device to go to 148 * sleep. 149 */ 150 public static final int PROPERTY_POWER_CONFIGURATION_TRIGGER_SLEEP = 13; 151 152 /** 153 * Property that indicates that this device state will attempt to trigger the device to wake up. 154 */ 155 public static final int PROPERTY_POWER_CONFIGURATION_TRIGGER_WAKE = 14; 156 157 /** 158 * Property that indicates that an external display has been connected to the device. Specifics 159 * around display mode or properties around the display should be gathered through 160 * {@link android.hardware.display.DisplayManager} 161 */ 162 public static final int PROPERTY_EXTENDED_DEVICE_STATE_EXTERNAL_DISPLAY = 15; 163 /** 164 * Property that indicates that this state corresponds to the device state for rear display 165 * mode. This means that the active display is facing the same direction as the rear camera. 166 */ 167 public static final int PROPERTY_FEATURE_REAR_DISPLAY = 16; 168 169 /** 170 * Property that indicates that this state corresponds to the device state where both displays 171 * on a foldable are active, with the internal display being the default display. 172 */ 173 public static final int PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT = 17; 174 175 /** @hide */ 176 @IntDef(prefix = {"PROPERTY_"}, flag = false, value = { 177 PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED, 178 PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN, 179 PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN, 180 PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS, 181 PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP, 182 PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL, 183 PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE, 184 PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST, 185 PROPERTY_APP_INACCESSIBLE, 186 PROPERTY_EMULATED_ONLY, 187 PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY, 188 PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY, 189 PROPERTY_POWER_CONFIGURATION_TRIGGER_SLEEP, 190 PROPERTY_POWER_CONFIGURATION_TRIGGER_WAKE, 191 PROPERTY_EXTENDED_DEVICE_STATE_EXTERNAL_DISPLAY, 192 PROPERTY_FEATURE_REAR_DISPLAY, 193 PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT 194 }) 195 @Retention(RetentionPolicy.SOURCE) 196 @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) 197 public @interface DeviceStateProperties {} 198 199 /** @hide */ 200 @IntDef(prefix = {"PROPERTY_"}, flag = false, value = { 201 PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_CLOSED, 202 PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_HALF_OPEN, 203 PROPERTY_FOLDABLE_HARDWARE_CONFIGURATION_FOLD_IN_OPEN 204 }) 205 @Retention(RetentionPolicy.SOURCE) 206 @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) 207 public @interface PhysicalDeviceStateProperties {} 208 209 /** @hide */ 210 @IntDef(prefix = {"PROPERTY_"}, flag = false, value = { 211 PROPERTY_POLICY_CANCEL_OVERRIDE_REQUESTS, 212 PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP, 213 PROPERTY_POLICY_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL, 214 PROPERTY_POLICY_UNSUPPORTED_WHEN_POWER_SAVE_MODE, 215 PROPERTY_POLICY_AVAILABLE_FOR_APP_REQUEST, 216 PROPERTY_APP_INACCESSIBLE, 217 PROPERTY_EMULATED_ONLY, 218 PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_OUTER_PRIMARY, 219 PROPERTY_FOLDABLE_DISPLAY_CONFIGURATION_INNER_PRIMARY, 220 PROPERTY_POWER_CONFIGURATION_TRIGGER_SLEEP, 221 PROPERTY_POWER_CONFIGURATION_TRIGGER_WAKE, 222 PROPERTY_EXTENDED_DEVICE_STATE_EXTERNAL_DISPLAY, 223 PROPERTY_FEATURE_REAR_DISPLAY, 224 PROPERTY_FEATURE_DUAL_DISPLAY_INTERNAL_DEFAULT 225 }) 226 @Retention(RetentionPolicy.SOURCE) 227 @Target({ElementType.TYPE_PARAMETER, ElementType.TYPE_USE}) 228 public @interface SystemDeviceStateProperties {} 229 230 @NonNull 231 private final DeviceState.Configuration mDeviceStateConfiguration; 232 233 /** @hide */ 234 @TestApi DeviceState(@onNull DeviceState.Configuration deviceStateConfiguration)235 public DeviceState(@NonNull DeviceState.Configuration deviceStateConfiguration) { 236 Objects.requireNonNull(deviceStateConfiguration, "Device StateConfiguration is null"); 237 mDeviceStateConfiguration = deviceStateConfiguration; 238 } 239 240 /** Returns the unique identifier for the device state. */ 241 @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER) getIdentifier()242 public int getIdentifier() { 243 return mDeviceStateConfiguration.getIdentifier(); 244 } 245 246 /** Returns a string description of the device state. */ 247 @NonNull getName()248 public String getName() { 249 return mDeviceStateConfiguration.getName(); 250 } 251 252 @Override toString()253 public String toString() { 254 return "DeviceState{" + "identifier=" + mDeviceStateConfiguration.getIdentifier() 255 + ", name='" + mDeviceStateConfiguration.getName() + '\'' 256 + ", app_accessible=" + !mDeviceStateConfiguration.getSystemProperties().contains( 257 PROPERTY_APP_INACCESSIBLE) 258 + ", cancel_when_requester_not_on_top=" 259 + mDeviceStateConfiguration.getSystemProperties().contains( 260 PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP) 261 + "}"; 262 } 263 264 @Override equals(Object o)265 public boolean equals(Object o) { 266 if (this == o) return true; 267 if (o == null || getClass() != o.getClass()) return false; 268 DeviceState that = (DeviceState) o; 269 return Objects.equals(mDeviceStateConfiguration, that.mDeviceStateConfiguration); 270 } 271 272 @Override hashCode()273 public int hashCode() { 274 return Objects.hash(mDeviceStateConfiguration); 275 } 276 277 /** 278 * Checks if a specific property is set on this state 279 */ hasProperty(@eviceStateProperties int propertyToCheckFor)280 public boolean hasProperty(@DeviceStateProperties int propertyToCheckFor) { 281 return mDeviceStateConfiguration.mSystemProperties.contains(propertyToCheckFor) 282 || mDeviceStateConfiguration.mPhysicalProperties.contains(propertyToCheckFor); 283 } 284 285 /** 286 * Checks if a list of properties are all set on this state 287 */ hasProperties(@onNull @eviceStateProperties int... properties)288 public boolean hasProperties(@NonNull @DeviceStateProperties int... properties) { 289 for (int i = 0; i < properties.length; i++) { 290 if (!hasProperty(properties[i])) { 291 return false; 292 } 293 } 294 return true; 295 } 296 297 /** 298 * Returns the underlying {@link DeviceState.Configuration} object used to model the 299 * device state. 300 * @hide 301 */ getConfiguration()302 public Configuration getConfiguration() { 303 return mDeviceStateConfiguration; 304 } 305 306 /** 307 * Detailed description of a {@link DeviceState} that includes separated sets of 308 * {@link DeviceStateProperties} for properties that correspond to the state of the system when 309 * the device is in this state, as well as physical properties that describe this state. 310 * 311 * Instantiation of this class should only be done by the system server, and clients of 312 * {@link DeviceStateManager} will receive {@link DeviceState} objects. 313 * 314 * @see DeviceStateManager 315 * @hide 316 */ 317 @TestApi 318 public static final class Configuration implements Parcelable { 319 /** Unique identifier for the device state. */ 320 @IntRange(from = MINIMUM_DEVICE_STATE_IDENTIFIER, to = MAXIMUM_DEVICE_STATE_IDENTIFIER) 321 private final int mIdentifier; 322 323 /** String description of the device state. */ 324 @NonNull 325 private final String mName; 326 327 /** {@link ArraySet} of system properties that apply to this state. */ 328 @NonNull 329 private final ArraySet<@SystemDeviceStateProperties Integer> mSystemProperties; 330 331 /** {@link ArraySet} of physical device properties that apply to this state. */ 332 @NonNull 333 private final ArraySet<@PhysicalDeviceStateProperties Integer> mPhysicalProperties; 334 Configuration(int identifier, @NonNull String name, @NonNull ArraySet<@SystemDeviceStateProperties Integer> systemProperties, @NonNull ArraySet<@PhysicalDeviceStateProperties Integer> physicalProperties)335 private Configuration(int identifier, @NonNull String name, 336 @NonNull ArraySet<@SystemDeviceStateProperties Integer> systemProperties, 337 @NonNull ArraySet<@PhysicalDeviceStateProperties Integer> physicalProperties) { 338 mIdentifier = identifier; 339 mName = name; 340 mSystemProperties = systemProperties; 341 mPhysicalProperties = physicalProperties; 342 } 343 344 /** Returns the unique identifier for the device state. */ getIdentifier()345 public int getIdentifier() { 346 return mIdentifier; 347 } 348 349 /** Returns a string description of the device state. */ 350 @NonNull getName()351 public String getName() { 352 return mName; 353 } 354 355 /** Returns the {@link Set} of system properties that apply to this state. */ 356 @NonNull getSystemProperties()357 public Set<@SystemDeviceStateProperties Integer> getSystemProperties() { 358 return mSystemProperties; 359 } 360 361 /** Returns the {@link Set} of physical device properties that apply to this state. */ 362 @NonNull getPhysicalProperties()363 public Set<@DeviceStateProperties Integer> getPhysicalProperties() { 364 return mPhysicalProperties; 365 } 366 367 @Override toString()368 public String toString() { 369 return "DeviceState{" + "identifier=" + mIdentifier 370 + ", name='" + mName + '\'' 371 + ", app_accessible=" + mSystemProperties.contains(PROPERTY_APP_INACCESSIBLE) 372 + ", cancel_when_requester_not_on_top=" 373 + mSystemProperties.contains(PROPERTY_POLICY_CANCEL_WHEN_REQUESTER_NOT_ON_TOP) 374 + "}"; 375 } 376 377 @Override equals(Object o)378 public boolean equals(Object o) { 379 if (this == o) return true; 380 if (o == null || getClass() != o.getClass()) return false; 381 DeviceState.Configuration that = (DeviceState.Configuration) o; 382 return mIdentifier == that.mIdentifier 383 && Objects.equals(mName, that.mName) 384 && Objects.equals(mSystemProperties, that.mSystemProperties) 385 && Objects.equals(mPhysicalProperties, that.mPhysicalProperties); 386 } 387 388 @Override hashCode()389 public int hashCode() { 390 return Objects.hash(mIdentifier, mName, mSystemProperties, mPhysicalProperties); 391 } 392 393 @Override describeContents()394 public int describeContents() { 395 return 0; 396 } 397 398 @Override writeToParcel(@onNull Parcel dest, int flags)399 public void writeToParcel(@NonNull Parcel dest, int flags) { 400 dest.writeInt(mIdentifier); 401 dest.writeString8(mName); 402 dest.writeArraySet(mSystemProperties); 403 dest.writeArraySet(mPhysicalProperties); 404 } 405 406 @NonNull 407 public static final Creator<DeviceState.Configuration> CREATOR = new Creator<>() { 408 @Override 409 public DeviceState.Configuration createFromParcel(Parcel source) { 410 int identifier = source.readInt(); 411 String name = source.readString8(); 412 ArraySet<@SystemDeviceStateProperties Integer> systemProperties = 413 (ArraySet<Integer>) source.readArraySet(null /* classLoader */); 414 ArraySet<@PhysicalDeviceStateProperties Integer> physicalProperties = 415 (ArraySet<Integer>) source.readArraySet(null /* classLoader */); 416 417 return new DeviceState.Configuration(identifier, name, systemProperties, 418 physicalProperties); 419 } 420 421 @Override 422 public DeviceState.Configuration[] newArray(int size) { 423 return new DeviceState.Configuration[size]; 424 } 425 }; 426 427 /** @hide */ 428 @TestApi 429 public static final class Builder { 430 private final int mIdentifier; 431 @NonNull 432 private final String mName; 433 @NonNull 434 private Set<@SystemDeviceStateProperties Integer> mSystemProperties = 435 Collections.emptySet(); 436 @NonNull 437 private Set<@PhysicalDeviceStateProperties Integer> mPhysicalProperties = 438 Collections.emptySet(); 439 Builder(int identifier, @NonNull String name)440 public Builder(int identifier, @NonNull String name) { 441 mIdentifier = identifier; 442 mName = name; 443 } 444 445 /** Sets the system properties for this {@link DeviceState.Configuration.Builder} */ 446 @NonNull setSystemProperties( @onNull Set<@SystemDeviceStateProperties Integer> systemProperties)447 public Builder setSystemProperties( 448 @NonNull Set<@SystemDeviceStateProperties Integer> systemProperties) { 449 mSystemProperties = systemProperties; 450 return this; 451 } 452 453 /** Sets the system properties for this {@link DeviceState.Configuration.Builder} */ 454 @NonNull setPhysicalProperties( @onNull Set<@PhysicalDeviceStateProperties Integer> physicalProperties)455 public Builder setPhysicalProperties( 456 @NonNull Set<@PhysicalDeviceStateProperties Integer> physicalProperties) { 457 mPhysicalProperties = physicalProperties; 458 return this; 459 } 460 461 /** 462 * Returns a new {@link DeviceState.Configuration} whose values match the values set on 463 * the builder. 464 */ 465 @NonNull build()466 public DeviceState.Configuration build() { 467 return new DeviceState.Configuration(mIdentifier, mName, 468 new ArraySet<>(mSystemProperties), new ArraySet<>(mPhysicalProperties)); 469 } 470 } 471 } 472 } 473