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