1 /*
2  * Copyright (C) 2006 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.view;
18 
19 import static android.Manifest.permission.CONFIGURE_DISPLAY_COLOR_MODE;
20 
21 import android.annotation.IntDef;
22 import android.annotation.NonNull;
23 import android.annotation.Nullable;
24 import android.annotation.RequiresPermission;
25 import android.annotation.SuppressLint;
26 import android.annotation.TestApi;
27 import android.app.KeyguardManager;
28 import android.compat.annotation.UnsupportedAppUsage;
29 import android.content.res.CompatibilityInfo;
30 import android.content.res.Configuration;
31 import android.content.res.Resources;
32 import android.graphics.ColorSpace;
33 import android.graphics.PixelFormat;
34 import android.graphics.Point;
35 import android.graphics.Rect;
36 import android.hardware.display.DisplayManager;
37 import android.hardware.display.DisplayManagerGlobal;
38 import android.os.Build;
39 import android.os.Parcel;
40 import android.os.Parcelable;
41 import android.os.Process;
42 import android.os.SystemClock;
43 import android.util.DisplayMetrics;
44 import android.util.Log;
45 
46 import java.lang.annotation.Retention;
47 import java.lang.annotation.RetentionPolicy;
48 import java.util.ArrayList;
49 import java.util.Arrays;
50 import java.util.List;
51 
52 /**
53  * Provides information about the size and density of a logical display.
54  * <p>
55  * The display area is described in two different ways.
56  * <ul>
57  * <li>The application display area specifies the part of the display that may contain
58  * an application window, excluding the system decorations.  The application display area may
59  * be smaller than the real display area because the system subtracts the space needed
60  * for decor elements such as the status bar.  Use {@link WindowMetrics#getBounds()} to query the
61  * application window bounds.</li>
62  * <li>The real display area specifies the part of the display that contains content
63  * including the system decorations.  Even so, the real display area may be smaller than the
64  * physical size of the display if the window manager is emulating a smaller display
65  * using (adb shell wm size).  Use the following methods to query the
66  * real display area: {@link #getRealSize}, {@link #getRealMetrics}.</li>
67  * </ul>
68  * </p><p>
69  * A logical display does not necessarily represent a particular physical display device
70  * such as the internal display or an external display.  The contents of a logical
71  * display may be presented on one or more physical displays according to the devices
72  * that are currently attached and whether mirroring has been enabled.
73  * </p>
74  */
75 public final class Display {
76     private static final String TAG = "Display";
77     private static final boolean DEBUG = false;
78 
79     private final DisplayManagerGlobal mGlobal;
80     private final int mDisplayId;
81     private final int mLayerStack;
82     private final int mFlags;
83     private final int mType;
84     private final DisplayAddress mAddress;
85     private final int mOwnerUid;
86     private final String mOwnerPackageName;
87     private final Resources mResources;
88     private DisplayAdjustments mDisplayAdjustments;
89 
90     @UnsupportedAppUsage
91     private DisplayInfo mDisplayInfo; // never null
92     private boolean mIsValid;
93 
94     // Temporary display metrics structure used for compatibility mode.
95     private final DisplayMetrics mTempMetrics = new DisplayMetrics();
96 
97     // We cache the app width and height properties briefly between calls
98     // to getHeight() and getWidth() to ensure that applications perceive
99     // consistent results when the size changes (most of the time).
100     // Applications should now be using WindowMetrics instead.
101     private static final int CACHED_APP_SIZE_DURATION_MILLIS = 20;
102     private long mLastCachedAppSizeUpdate;
103     private int mCachedAppWidthCompat;
104     private int mCachedAppHeightCompat;
105 
106     /**
107      * Indicates that the application is started in a different rotation than the real display, so
108      * the display information may be adjusted. That ensures the methods {@link #getRotation},
109      * {@link #getRealSize}, {@link #getRealMetrics}, and {@link #getCutout} are consistent with how
110      * the application window is laid out.
111      */
112     private boolean mMayAdjustByFixedRotation;
113 
114     /**
115      * The default Display id, which is the id of the primary display assuming there is one.
116      */
117     public static final int DEFAULT_DISPLAY = 0;
118 
119     /**
120      * Invalid display id.
121      */
122     public static final int INVALID_DISPLAY = -1;
123 
124     /**
125      * Display flag: Indicates that the display supports compositing content
126      * that is stored in protected graphics buffers.
127      * <p>
128      * If this flag is set then the display device supports compositing protected buffers.
129      * </p><p>
130      * If this flag is not set then the display device may not support compositing
131      * protected buffers; the user may see a blank region on the screen instead of
132      * the protected content.
133      * </p><p>
134      * Secure (DRM) video decoders may allocate protected graphics buffers to request that
135      * a hardware-protected path be provided between the video decoder and the external
136      * display sink.  If a hardware-protected path is not available, then content stored
137      * in protected graphics buffers may not be composited.
138      * </p><p>
139      * An application can use the absence of this flag as a hint that it should not use protected
140      * buffers for this display because the content may not be visible.  For example,
141      * if the flag is not set then the application may choose not to show content on this
142      * display, show an informative error message, select an alternate content stream
143      * or adopt a different strategy for decoding content that does not rely on
144      * protected buffers.
145      * </p>
146      *
147      * @see #getFlags
148      */
149     public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1 << 0;
150 
151     /**
152      * Display flag: Indicates that the display has a secure video output and
153      * supports compositing secure surfaces.
154      * <p>
155      * If this flag is set then the display device has a secure video output
156      * and is capable of showing secure surfaces.  It may also be capable of
157      * showing {@link #FLAG_SUPPORTS_PROTECTED_BUFFERS protected buffers}.
158      * </p><p>
159      * If this flag is not set then the display device may not have a secure video
160      * output; the user may see a blank region on the screen instead of
161      * the contents of secure surfaces or protected buffers.
162      * </p><p>
163      * Secure surfaces are used to prevent content rendered into those surfaces
164      * by applications from appearing in screenshots or from being viewed
165      * on non-secure displays.  Protected buffers are used by secure video decoders
166      * for a similar purpose.
167      * </p><p>
168      * An application creates a window with a secure surface by specifying the
169      * {@link WindowManager.LayoutParams#FLAG_SECURE} window flag.
170      * Likewise, an application creates a {@link SurfaceView} with a secure surface
171      * by calling {@link SurfaceView#setSecure} before attaching the secure view to
172      * its containing window.
173      * </p><p>
174      * An application can use the absence of this flag as a hint that it should not create
175      * secure surfaces or protected buffers on this display because the content may
176      * not be visible.  For example, if the flag is not set then the application may
177      * choose not to show content on this display, show an informative error message,
178      * select an alternate content stream or adopt a different strategy for decoding
179      * content that does not rely on secure surfaces or protected buffers.
180      * </p>
181      *
182      * @see #getFlags
183      */
184     public static final int FLAG_SECURE = 1 << 1;
185 
186     /**
187      * Display flag: Indicates that the display is private.  Only the application that
188      * owns the display and apps that are already on the display can create windows on it.
189      *
190      * @see #getFlags
191      */
192     public static final int FLAG_PRIVATE = 1 << 2;
193 
194     /**
195      * Display flag: Indicates that the display is a presentation display.
196      * <p>
197      * This flag identifies secondary displays that are suitable for
198      * use as presentation displays such as external or wireless displays.  Applications
199      * may automatically project their content to presentation displays to provide
200      * richer second screen experiences.
201      * </p>
202      *
203      * @see #getFlags
204      */
205     public static final int FLAG_PRESENTATION = 1 << 3;
206 
207     /**
208      * Display flag: Indicates that the display has a round shape.
209      * <p>
210      * This flag identifies displays that are circular, elliptical or otherwise
211      * do not permit the user to see all the way to the logical corners of the display.
212      * </p>
213      *
214      * @see #getFlags
215      */
216     public static final int FLAG_ROUND = 1 << 4;
217 
218     /**
219      * Display flag: Indicates that the display can show its content when non-secure keyguard is
220      * shown.
221      * <p>
222      * This flag identifies secondary displays that will continue showing content if keyguard can be
223      * dismissed without entering credentials.
224      * </p><p>
225      * An example of usage is a virtual display which content is displayed on external hardware
226      * display that is not visible to the system directly.
227      * </p>
228      *
229      * @see DisplayManager#VIRTUAL_DISPLAY_FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD
230      * @see KeyguardManager#isDeviceSecure()
231      * @see KeyguardManager#isDeviceLocked()
232      * @see #getFlags
233      * @hide
234      */
235     // TODO (b/114338689): Remove the flag and use IWindowManager#shouldShowWithInsecureKeyguard
236     public static final int FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD = 1 << 5;
237 
238     /**
239      * Display flag: Indicates that the display should show system decorations.
240      * <p>
241      * This flag identifies secondary displays that should show system decorations, such as status
242      * bar, navigation bar, home activity or IME.
243      * </p>
244      * <p>Note that this flag doesn't work without {@link #FLAG_TRUSTED}</p>
245      *
246      * @see #getFlags()
247      * @hide
248      */
249     // TODO (b/114338689): Remove the flag and use IWindowManager#setShouldShowSystemDecors
250     public static final int FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 1 << 6;
251 
252     /**
253      * Flag: The display is trusted to show system decorations and receive inputs without users'
254      * touch.
255      * @see #FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
256      *
257      * @see #getFlags()
258      * @hide
259      */
260     @TestApi
261     public static final int FLAG_TRUSTED = 1 << 7;
262 
263     /**
264      * Display flag: Indicates that the contents of the display should not be scaled
265      * to fit the physical screen dimensions.  Used for development only to emulate
266      * devices with smaller physicals screens while preserving density.
267      *
268      * @hide
269      */
270     public static final int FLAG_SCALING_DISABLED = 1 << 30;
271 
272     /**
273      * Display type: Unknown display type.
274      * @hide
275      */
276     @UnsupportedAppUsage
277     @TestApi
278     public static final int TYPE_UNKNOWN = 0;
279 
280     /**
281      * Display type: Physical display connected through an internal port.
282      * @hide
283      */
284     @TestApi
285     public static final int TYPE_INTERNAL = 1;
286 
287     /**
288      * Display type: Physical display connected through an external port.
289      * @hide
290      */
291     @UnsupportedAppUsage
292     @TestApi
293     public static final int TYPE_EXTERNAL = 2;
294 
295     /**
296      * Display type: WiFi display.
297      * @hide
298      */
299     @UnsupportedAppUsage
300     @TestApi
301     public static final int TYPE_WIFI = 3;
302 
303     /**
304      * Display type: Overlay display.
305      * @hide
306      */
307     @TestApi
308     public static final int TYPE_OVERLAY = 4;
309 
310     /**
311      * Display type: Virtual display.
312      * @hide
313      */
314     @UnsupportedAppUsage
315     @TestApi
316     public static final int TYPE_VIRTUAL = 5;
317 
318     /**
319      * Display state: The display state is unknown.
320      *
321      * @see #getState
322      */
323     public static final int STATE_UNKNOWN = ViewProtoEnums.DISPLAY_STATE_UNKNOWN; // 0
324 
325     /**
326      * Display state: The display is off.
327      *
328      * @see #getState
329      */
330     public static final int STATE_OFF = ViewProtoEnums.DISPLAY_STATE_OFF; // 1
331 
332     /**
333      * Display state: The display is on.
334      *
335      * @see #getState
336      */
337     public static final int STATE_ON = ViewProtoEnums.DISPLAY_STATE_ON; // 2
338 
339     /**
340      * Display state: The display is dozing in a low power state; it is still
341      * on but is optimized for showing system-provided content while the
342      * device is non-interactive.
343      *
344      * @see #getState
345      * @see android.os.PowerManager#isInteractive
346      */
347     public static final int STATE_DOZE = ViewProtoEnums.DISPLAY_STATE_DOZE; // 3
348 
349     /**
350      * Display state: The display is dozing in a suspended low power state; it is still
351      * on but the CPU is not updating it. This may be used in one of two ways: to show
352      * static system-provided content while the device is non-interactive, or to allow
353      * a "Sidekick" compute resource to update the display. For this reason, the
354      * CPU must not control the display in this mode.
355      *
356      * @see #getState
357      * @see android.os.PowerManager#isInteractive
358      */
359     public static final int STATE_DOZE_SUSPEND = ViewProtoEnums.DISPLAY_STATE_DOZE_SUSPEND; // 4
360 
361     /**
362      * Display state: The display is on and optimized for VR mode.
363      *
364      * @see #getState
365      * @see android.os.PowerManager#isInteractive
366      */
367     public static final int STATE_VR = ViewProtoEnums.DISPLAY_STATE_VR; // 5
368 
369     /**
370      * Display state: The display is in a suspended full power state; it is still
371      * on but the CPU is not updating it. This may be used in one of two ways: to show
372      * static system-provided content while the device is non-interactive, or to allow
373      * a "Sidekick" compute resource to update the display. For this reason, the
374      * CPU must not control the display in this mode.
375      *
376      * @see #getState
377      * @see android.os.PowerManager#isInteractive
378      */
379     public static final int STATE_ON_SUSPEND = ViewProtoEnums.DISPLAY_STATE_ON_SUSPEND; // 6
380 
381     /* The color mode constants defined below must be kept in sync with the ones in
382      * system/core/include/system/graphics-base.h */
383 
384     /**
385      * Display color mode: The current color mode is unknown or invalid.
386      * @hide
387      */
388     public static final int COLOR_MODE_INVALID = -1;
389 
390     /**
391      * Display color mode: The default or native gamut of the display.
392      * @hide
393      */
394     public static final int COLOR_MODE_DEFAULT = 0;
395 
396     /** @hide */
397     public static final int COLOR_MODE_BT601_625 = 1;
398     /** @hide */
399     public static final int COLOR_MODE_BT601_625_UNADJUSTED = 2;
400     /** @hide */
401     public static final int COLOR_MODE_BT601_525 = 3;
402     /** @hide */
403     public static final int COLOR_MODE_BT601_525_UNADJUSTED = 4;
404     /** @hide */
405     public static final int COLOR_MODE_BT709 = 5;
406     /** @hide */
407     public static final int COLOR_MODE_DCI_P3 = 6;
408     /** @hide */
409     public static final int COLOR_MODE_SRGB = 7;
410     /** @hide */
411     public static final int COLOR_MODE_ADOBE_RGB = 8;
412     /** @hide */
413     public static final int COLOR_MODE_DISPLAY_P3 = 9;
414 
415     /** @hide **/
416     @IntDef(prefix = {"COLOR_MODE_"}, value = {
417             COLOR_MODE_INVALID,
418             COLOR_MODE_DEFAULT,
419             COLOR_MODE_BT601_625,
420             COLOR_MODE_BT601_625_UNADJUSTED,
421             COLOR_MODE_BT601_525,
422             COLOR_MODE_BT601_525_UNADJUSTED,
423             COLOR_MODE_BT709,
424             COLOR_MODE_DCI_P3,
425             COLOR_MODE_SRGB,
426             COLOR_MODE_ADOBE_RGB,
427             COLOR_MODE_DISPLAY_P3
428     })
429     @Retention(RetentionPolicy.SOURCE)
430     public @interface ColorMode {}
431 
432     /**
433      * Indicates that when display is removed, all its activities will be moved to the primary
434      * display and the topmost activity should become focused.
435      *
436      * @hide
437      */
438     // TODO (b/114338689): Remove the flag and use WindowManager#REMOVE_CONTENT_MODE_MOVE_TO_PRIMARY
439     public static final int REMOVE_MODE_MOVE_CONTENT_TO_PRIMARY = 0;
440     /**
441      * Indicates that when display is removed, all its stacks and tasks will be removed, all
442      * activities will be destroyed according to the usual lifecycle.
443      *
444      * @hide
445      */
446     // TODO (b/114338689): Remove the flag and use WindowManager#REMOVE_CONTENT_MODE_DESTROY
447     public static final int REMOVE_MODE_DESTROY_CONTENT = 1;
448 
449     /**
450      * Internal method to create a display.
451      * The display created with this method will have a static {@link DisplayAdjustments} applied.
452      * Applications should use {@link android.content.Context#getDisplay} with
453      * {@link android.app.Activity} or a context associated with a {@link Display} via
454      * {@link android.content.Context#createDisplayContext(Display)}
455      * to get a display object associated with a {@link android.app.Context}, or
456      * {@link android.hardware.display.DisplayManager#getDisplay} to get a display object by id.
457      *
458      * @see android.content.Context#getDisplay()
459      * @see android.content.Context#createDisplayContext(Display)
460      * @hide
461      */
Display(DisplayManagerGlobal global, int displayId, DisplayInfo displayInfo, DisplayAdjustments daj)462     public Display(DisplayManagerGlobal global, int displayId, /*@NotNull*/ DisplayInfo displayInfo,
463             DisplayAdjustments daj) {
464         this(global, displayId, displayInfo, daj, null /*res*/);
465     }
466 
467     /**
468      * Internal method to create a display.
469      * The display created with this method will be adjusted based on the adjustments in the
470      * supplied {@link Resources}.
471      *
472      * @hide
473      */
Display(DisplayManagerGlobal global, int displayId, DisplayInfo displayInfo, Resources res)474     public Display(DisplayManagerGlobal global, int displayId, /*@NotNull*/ DisplayInfo displayInfo,
475             Resources res) {
476         this(global, displayId, displayInfo, null /*daj*/, res);
477     }
478 
Display(DisplayManagerGlobal global, int displayId, DisplayInfo displayInfo, DisplayAdjustments daj, Resources res)479     private Display(DisplayManagerGlobal global, int displayId,
480             /*@NotNull*/ DisplayInfo displayInfo, DisplayAdjustments daj, Resources res) {
481         mGlobal = global;
482         mDisplayId = displayId;
483         mDisplayInfo = displayInfo;
484         mResources = res;
485         mDisplayAdjustments = mResources != null
486             ? new DisplayAdjustments(mResources.getConfiguration())
487             : daj != null ? new DisplayAdjustments(daj) : new DisplayAdjustments();
488         mIsValid = true;
489 
490         // Cache properties that cannot change as long as the display is valid.
491         mLayerStack = displayInfo.layerStack;
492         mFlags = displayInfo.flags;
493         mType = displayInfo.type;
494         mAddress = displayInfo.address;
495         mOwnerUid = displayInfo.ownerUid;
496         mOwnerPackageName = displayInfo.ownerPackageName;
497     }
498 
499     /**
500      * Gets the display id.
501      * <p>
502      * Each logical display has a unique id.
503      * The default display has id {@link #DEFAULT_DISPLAY}.
504      * </p>
505      */
getDisplayId()506     public int getDisplayId() {
507         return mDisplayId;
508     }
509 
510     /**
511      * Gets the display unique id.
512      * <p>
513      * Unique id is different from display id because physical displays have stable unique id across
514      * reboots.
515      *
516      * @see com.android.service.display.DisplayDevice#hasStableUniqueId().
517      * @hide
518      */
getUniqueId()519     public String getUniqueId() {
520         return mDisplayInfo.uniqueId;
521     }
522 
523     /**
524      * Returns true if this display is still valid, false if the display has been removed.
525      *
526      * If the display is invalid, then the methods of this class will
527      * continue to report the most recently observed display information.
528      * However, it is unwise (and rather fruitless) to continue using a
529      * {@link Display} object after the display's demise.
530      *
531      * It's possible for a display that was previously invalid to become
532      * valid again if a display with the same id is reconnected.
533      *
534      * @return True if the display is still valid.
535      */
isValid()536     public boolean isValid() {
537         synchronized (this) {
538             updateDisplayInfoLocked();
539             return mIsValid;
540         }
541     }
542 
543     /**
544      * Gets a full copy of the display information.
545      *
546      * @param outDisplayInfo The object to receive the copy of the display information.
547      * @return True if the display is still valid.
548      * @hide
549      */
550     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
getDisplayInfo(DisplayInfo outDisplayInfo)551     public boolean getDisplayInfo(DisplayInfo outDisplayInfo) {
552         synchronized (this) {
553             updateDisplayInfoLocked();
554             outDisplayInfo.copyFrom(mDisplayInfo);
555             return mIsValid;
556         }
557     }
558 
559     /**
560      * Gets the display's layer stack.
561      *
562      * Each display has its own independent layer stack upon which surfaces
563      * are placed to be managed by surface flinger.
564      *
565      * @return The display's layer stack number.
566      * @hide
567      */
getLayerStack()568     public int getLayerStack() {
569         return mLayerStack;
570     }
571 
572     /**
573      * Returns a combination of flags that describe the capabilities of the display.
574      *
575      * @return The display flags.
576      *
577      * @see #FLAG_SUPPORTS_PROTECTED_BUFFERS
578      * @see #FLAG_SECURE
579      * @see #FLAG_PRIVATE
580      * @see #FLAG_ROUND
581      */
getFlags()582     public int getFlags() {
583         return mFlags;
584     }
585 
586     /**
587      * Gets the display type.
588      *
589      * @return The display type.
590      *
591      * @see #TYPE_UNKNOWN
592      * @see #TYPE_INTERNAL
593      * @see #TYPE_EXTERNAL
594      * @see #TYPE_WIFI
595      * @see #TYPE_OVERLAY
596      * @see #TYPE_VIRTUAL
597      * @hide
598      */
599     @UnsupportedAppUsage
600     @TestApi
getType()601     public int getType() {
602         return mType;
603     }
604 
605     /**
606      * Gets the display address, or null if none.
607      * Interpretation varies by display type.
608      *
609      * @return The display address.
610      * @hide
611      */
getAddress()612     public DisplayAddress getAddress() {
613         return mAddress;
614     }
615 
616     /**
617      * Gets the UID of the application that owns this display, or zero if it is
618      * owned by the system.
619      * <p>
620      * If the display is private, then only the owner can use it.
621      * </p>
622      *
623      * @hide
624      */
getOwnerUid()625     public int getOwnerUid() {
626         return mOwnerUid;
627     }
628 
629     /**
630      * Gets the package name of the application that owns this display, or null if it is
631      * owned by the system.
632      * <p>
633      * If the display is private, then only the owner can use it.
634      * </p>
635      *
636      * @hide
637      */
638     @UnsupportedAppUsage
getOwnerPackageName()639     public String getOwnerPackageName() {
640         return mOwnerPackageName;
641     }
642 
643     /**
644      * Gets the compatibility info used by this display instance.
645      *
646      * @return The display adjustments holder, or null if none is required.
647      * @hide
648      */
649     @UnsupportedAppUsage
getDisplayAdjustments()650     public DisplayAdjustments getDisplayAdjustments() {
651         if (mResources != null) {
652             final DisplayAdjustments currentAdjustements = mResources.getDisplayAdjustments();
653             if (!mDisplayAdjustments.equals(currentAdjustements)) {
654                 mDisplayAdjustments = new DisplayAdjustments(currentAdjustements);
655             }
656         }
657 
658         return mDisplayAdjustments;
659     }
660 
661     /**
662      * Gets the name of the display.
663      * <p>
664      * Note that some displays may be renamed by the user.
665      * </p>
666      *
667      * @return The display's name.
668      */
getName()669     public String getName() {
670         synchronized (this) {
671             updateDisplayInfoLocked();
672             return mDisplayInfo.name;
673         }
674     }
675 
676     /**
677      * Gets the size of the display, in pixels.
678      * Value returned by this method does not necessarily represent the actual raw size
679      * (native resolution) of the display.
680      * <p>
681      * 1. The returned size may be adjusted to exclude certain system decor elements
682      * that are always visible.
683      * </p><p>
684      * 2. It may be scaled to provide compatibility with older applications that
685      * were originally designed for smaller displays.
686      * </p><p>
687      * 3. It can be different depending on the WindowManager to which the display belongs.
688      * </p><p>
689      * - If requested from non-Activity context (e.g. Application context via
690      * {@code (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE)})
691      * it will report the size of the entire display based on current rotation and with subtracted
692      * system decoration areas.
693      * </p><p>
694      * - If requested from activity (either using {@code getWindowManager()} or
695      * {@code (WindowManager) getSystemService(Context.WINDOW_SERVICE)}) resulting size will
696      * correspond to current app window size. In this case it can be smaller than physical size in
697      * multi-window mode.
698      * </p><p>
699      * Typically for the purposes of layout apps should make a request from activity context
700      * to obtain size available for the app content.
701      * </p>
702      *
703      * @param outSize A {@link Point} object to receive the size information.
704      * @deprecated Use {@link WindowManager#getCurrentWindowMetrics()} to obtain an instance of
705      * {@link WindowMetrics} and use {@link WindowMetrics#getBounds()} instead.
706      */
707     @Deprecated
getSize(Point outSize)708     public void getSize(Point outSize) {
709         synchronized (this) {
710             updateDisplayInfoLocked();
711             mDisplayInfo.getAppMetrics(mTempMetrics, getDisplayAdjustments());
712             outSize.x = mTempMetrics.widthPixels;
713             outSize.y = mTempMetrics.heightPixels;
714         }
715     }
716 
717     /**
718      * Gets the size of the display as a rectangle, in pixels.
719      *
720      * @param outSize A {@link Rect} object to receive the size information.
721      * @deprecated Use {@link WindowMetrics#getBounds()} to get the dimensions of the application
722      * window area.
723      */
724     @Deprecated
getRectSize(Rect outSize)725     public void getRectSize(Rect outSize) {
726         synchronized (this) {
727             updateDisplayInfoLocked();
728             mDisplayInfo.getAppMetrics(mTempMetrics, getDisplayAdjustments());
729             outSize.set(0, 0, mTempMetrics.widthPixels, mTempMetrics.heightPixels);
730         }
731     }
732 
733     /**
734      * Return the range of display sizes an application can expect to encounter
735      * under normal operation, as long as there is no physical change in screen
736      * size.  This is basically the sizes you will see as the orientation
737      * changes, taking into account whatever screen decoration there is in
738      * each rotation.  For example, the status bar is always at the top of the
739      * screen, so it will reduce the height both in landscape and portrait, and
740      * the smallest height returned here will be the smaller of the two.
741      *
742      * This is intended for applications to get an idea of the range of sizes
743      * they will encounter while going through device rotations, to provide a
744      * stable UI through rotation.  The sizes here take into account all standard
745      * system decorations that reduce the size actually available to the
746      * application: the status bar, navigation bar, system bar, etc.  It does
747      * <em>not</em> take into account more transient elements like an IME
748      * soft keyboard.
749      *
750      * @param outSmallestSize Filled in with the smallest width and height
751      * that the application will encounter, in pixels (not dp units).  The x
752      * (width) dimension here directly corresponds to
753      * {@link android.content.res.Configuration#smallestScreenWidthDp
754      * Configuration.smallestScreenWidthDp}, except the value here is in raw
755      * screen pixels rather than dp units.  Your application may of course
756      * still get smaller space yet if, for example, a soft keyboard is
757      * being displayed.
758      * @param outLargestSize Filled in with the largest width and height
759      * that the application will encounter, in pixels (not dp units).  Your
760      * application may of course still get larger space than this if,
761      * for example, screen decorations like the status bar are being hidden.
762      */
getCurrentSizeRange(Point outSmallestSize, Point outLargestSize)763     public void getCurrentSizeRange(Point outSmallestSize, Point outLargestSize) {
764         synchronized (this) {
765             updateDisplayInfoLocked();
766             outSmallestSize.x = mDisplayInfo.smallestNominalAppWidth;
767             outSmallestSize.y = mDisplayInfo.smallestNominalAppHeight;
768             outLargestSize.x = mDisplayInfo.largestNominalAppWidth;
769             outLargestSize.y = mDisplayInfo.largestNominalAppHeight;
770         }
771     }
772 
773     /**
774      * Return the maximum screen size dimension that will happen.  This is
775      * mostly for wallpapers.
776      * @hide
777      */
778     @UnsupportedAppUsage
getMaximumSizeDimension()779     public int getMaximumSizeDimension() {
780         synchronized (this) {
781             updateDisplayInfoLocked();
782             return Math.max(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
783         }
784     }
785 
786     /**
787      * @deprecated Use {@link WindowMetrics#getBounds#width()} instead.
788      */
789     @Deprecated
getWidth()790     public int getWidth() {
791         synchronized (this) {
792             updateCachedAppSizeIfNeededLocked();
793             return mCachedAppWidthCompat;
794         }
795     }
796 
797     /**
798      * @deprecated Use {@link WindowMetrics#getBounds()#height()} instead.
799      */
800     @Deprecated
getHeight()801     public int getHeight() {
802         synchronized (this) {
803             updateCachedAppSizeIfNeededLocked();
804             return mCachedAppHeightCompat;
805         }
806     }
807 
808     /**
809      * Returns the rotation of the screen from its "natural" orientation.
810      * The returned value may be {@link Surface#ROTATION_0 Surface.ROTATION_0}
811      * (no rotation), {@link Surface#ROTATION_90 Surface.ROTATION_90},
812      * {@link Surface#ROTATION_180 Surface.ROTATION_180}, or
813      * {@link Surface#ROTATION_270 Surface.ROTATION_270}.  For
814      * example, if a device has a naturally tall screen, and the user has
815      * turned it on its side to go into a landscape orientation, the value
816      * returned here may be either {@link Surface#ROTATION_90 Surface.ROTATION_90}
817      * or {@link Surface#ROTATION_270 Surface.ROTATION_270} depending on
818      * the direction it was turned.  The angle is the rotation of the drawn
819      * graphics on the screen, which is the opposite direction of the physical
820      * rotation of the device.  For example, if the device is rotated 90
821      * degrees counter-clockwise, to compensate rendering will be rotated by
822      * 90 degrees clockwise and thus the returned value here will be
823      * {@link Surface#ROTATION_90 Surface.ROTATION_90}.
824      */
825     @Surface.Rotation
getRotation()826     public int getRotation() {
827         synchronized (this) {
828             updateDisplayInfoLocked();
829             return mMayAdjustByFixedRotation
830                     ? getDisplayAdjustments().getRotation(mDisplayInfo.rotation)
831                     : mDisplayInfo.rotation;
832         }
833     }
834 
835     /**
836      * @deprecated use {@link #getRotation}
837      * @return orientation of this display.
838      */
839     @Deprecated
840     @Surface.Rotation
getOrientation()841     public int getOrientation() {
842         return getRotation();
843     }
844 
845 
846     /**
847      * Returns the {@link DisplayCutout}, or {@code null} if there is none.
848      *
849      * @see DisplayCutout
850      */
851     @Nullable
getCutout()852     public DisplayCutout getCutout() {
853         synchronized (this) {
854             updateDisplayInfoLocked();
855             return mMayAdjustByFixedRotation
856                     ? getDisplayAdjustments().getDisplayCutout(mDisplayInfo.displayCutout)
857                     : mDisplayInfo.displayCutout;
858         }
859     }
860 
861     /**
862      * Gets the pixel format of the display.
863      * @return One of the constants defined in {@link android.graphics.PixelFormat}.
864      *
865      * @deprecated This method is no longer supported.
866      * The result is always {@link PixelFormat#RGBA_8888}.
867      */
868     @Deprecated
getPixelFormat()869     public int getPixelFormat() {
870         return PixelFormat.RGBA_8888;
871     }
872 
873     /**
874      * Gets the refresh rate of this display in frames per second.
875      */
getRefreshRate()876     public float getRefreshRate() {
877         synchronized (this) {
878             updateDisplayInfoLocked();
879             return mDisplayInfo.getMode().getRefreshRate();
880         }
881     }
882 
883     /**
884      * Get the supported refresh rates of this display in frames per second.
885      * <p>
886      * This method only returns refresh rates for the display's default modes. For more options, use
887      * {@link #getSupportedModes()}.
888      *
889      * @deprecated use {@link #getSupportedModes()} instead
890      */
891     @Deprecated
getSupportedRefreshRates()892     public float[] getSupportedRefreshRates() {
893         synchronized (this) {
894             updateDisplayInfoLocked();
895             return mDisplayInfo.getDefaultRefreshRates();
896         }
897     }
898 
899     /**
900      * Returns the active mode of the display.
901      */
getMode()902     public Mode getMode() {
903         synchronized (this) {
904             updateDisplayInfoLocked();
905             return mDisplayInfo.getMode();
906         }
907     }
908 
909     /**
910      * Gets the supported modes of this display.
911      */
getSupportedModes()912     public Mode[] getSupportedModes() {
913         synchronized (this) {
914             updateDisplayInfoLocked();
915             final Display.Mode[] modes = mDisplayInfo.supportedModes;
916             return Arrays.copyOf(modes, modes.length);
917         }
918     }
919 
920     /**
921      * <p> Returns true if the connected display can be switched into a mode with minimal
922      * post processing. </p>
923      *
924      * <p> If the Display sink is connected via HDMI, this method will return true if the
925      * display supports either Auto Low Latency Mode or Game Content Type.
926      *
927      * <p> If the Display sink has an internal connection or uses some other protocol than
928      * HDMI, this method will return true if the sink can be switched into an
929      * implementation-defined low latency image processing mode. </p>
930      *
931      * <p> The ability to switch to a mode with minimal post processing may be disabled
932      * by a user setting in the system settings menu. In that case, this method returns
933      * false. </p>
934      *
935      * @see android.view.Window#setPreferMinimalPostProcessing
936      */
937     @SuppressLint("VisiblySynchronized")
isMinimalPostProcessingSupported()938     public boolean isMinimalPostProcessingSupported() {
939         synchronized (this) {
940             updateDisplayInfoLocked();
941             return mDisplayInfo.minimalPostProcessingSupported;
942         }
943     }
944 
945     /**
946      * Request the display applies a color mode.
947      * @hide
948      */
949     @RequiresPermission(CONFIGURE_DISPLAY_COLOR_MODE)
requestColorMode(int colorMode)950     public void requestColorMode(int colorMode) {
951         mGlobal.requestColorMode(mDisplayId, colorMode);
952     }
953 
954     /**
955      * Returns the active color mode of this display
956      * @hide
957      */
getColorMode()958     public int getColorMode() {
959         synchronized (this) {
960             updateDisplayInfoLocked();
961             return mDisplayInfo.colorMode;
962         }
963     }
964 
965     /**
966      * @hide
967      * Get current remove mode of the display - what actions should be performed with the display's
968      * content when it is removed. Default behavior for public displays in this case is to move all
969      * activities to the primary display and make it focused. For private display - destroy all
970      * activities.
971      *
972      * @see #REMOVE_MODE_MOVE_CONTENT_TO_PRIMARY
973      * @see #REMOVE_MODE_DESTROY_CONTENT
974      */
975     // TODO (b/114338689): Remove the method and use IWindowManager#getRemoveContentMode
getRemoveMode()976     public int getRemoveMode() {
977         return mDisplayInfo.removeMode;
978     }
979 
980     /**
981      * Returns the display's HDR capabilities.
982      *
983      * @see #isHdr()
984      */
getHdrCapabilities()985     public HdrCapabilities getHdrCapabilities() {
986         synchronized (this) {
987             updateDisplayInfoLocked();
988             return mDisplayInfo.hdrCapabilities;
989         }
990     }
991 
992     /**
993      * Returns whether this display supports any HDR type.
994      *
995      * @see #getHdrCapabilities()
996      * @see HdrCapabilities#getSupportedHdrTypes()
997      */
isHdr()998     public boolean isHdr() {
999         synchronized (this) {
1000             updateDisplayInfoLocked();
1001             return mDisplayInfo.isHdr();
1002         }
1003     }
1004 
1005     /**
1006      * Returns whether this display can be used to display wide color gamut content.
1007      * This does not necessarily mean the device itself can render wide color gamut
1008      * content. To ensure wide color gamut content can be produced, refer to
1009      * {@link Configuration#isScreenWideColorGamut()}.
1010      */
isWideColorGamut()1011     public boolean isWideColorGamut() {
1012         synchronized (this) {
1013             updateDisplayInfoLocked();
1014             return mDisplayInfo.isWideColorGamut();
1015         }
1016     }
1017 
1018     /**
1019      * Returns the preferred wide color space of the Display.
1020      * The returned wide gamut color space is based on hardware capability and
1021      * is preferred by the composition pipeline.
1022      * Returns null if the display doesn't support wide color gamut.
1023      * {@link Display#isWideColorGamut()}.
1024      */
1025     @Nullable
getPreferredWideGamutColorSpace()1026     public ColorSpace getPreferredWideGamutColorSpace() {
1027         synchronized (this) {
1028             updateDisplayInfoLocked();
1029             if (mDisplayInfo.isWideColorGamut()) {
1030                 return mGlobal.getPreferredWideGamutColorSpace();
1031             }
1032             return null;
1033         }
1034     }
1035 
1036     /**
1037      * Gets the supported color modes of this device.
1038      * @hide
1039      */
getSupportedColorModes()1040     public int[] getSupportedColorModes() {
1041         synchronized (this) {
1042             updateDisplayInfoLocked();
1043             int[] colorModes = mDisplayInfo.supportedColorModes;
1044             return Arrays.copyOf(colorModes, colorModes.length);
1045         }
1046     }
1047 
1048     /**
1049      * Gets the supported wide color gamuts of this device.
1050      *
1051      * @return Supported WCG color spaces.
1052      * @hide
1053      */
1054     @SuppressLint("VisiblySynchronized")
1055     @NonNull
1056     @TestApi
getSupportedWideColorGamut()1057     public @ColorMode ColorSpace[] getSupportedWideColorGamut() {
1058         synchronized (this) {
1059             final ColorSpace[] defaultColorSpaces = new ColorSpace[0];
1060             updateDisplayInfoLocked();
1061             if (!isWideColorGamut()) {
1062                 return defaultColorSpaces;
1063             }
1064 
1065             final int[] colorModes = getSupportedColorModes();
1066             final List<ColorSpace> colorSpaces = new ArrayList<>();
1067             for (int colorMode : colorModes) {
1068                 // Refer to DisplayInfo#isWideColorGamut.
1069                 switch (colorMode) {
1070                     case COLOR_MODE_DCI_P3:
1071                         colorSpaces.add(ColorSpace.get(ColorSpace.Named.DCI_P3));
1072                         break;
1073                     case COLOR_MODE_DISPLAY_P3:
1074                         colorSpaces.add(ColorSpace.get(ColorSpace.Named.DISPLAY_P3));
1075                         break;
1076                 }
1077             }
1078             return colorSpaces.toArray(defaultColorSpaces);
1079         }
1080     }
1081 
1082     /**
1083      * Gets the app VSYNC offset, in nanoseconds.  This is a positive value indicating
1084      * the phase offset of the VSYNC events provided by Choreographer relative to the
1085      * display refresh.  For example, if Choreographer reports that the refresh occurred
1086      * at time N, it actually occurred at (N - appVsyncOffset).
1087      * <p>
1088      * Apps generally do not need to be aware of this.  It's only useful for fine-grained
1089      * A/V synchronization.
1090      */
getAppVsyncOffsetNanos()1091     public long getAppVsyncOffsetNanos() {
1092         synchronized (this) {
1093             updateDisplayInfoLocked();
1094             return mDisplayInfo.appVsyncOffsetNanos;
1095         }
1096     }
1097 
1098     /**
1099      * This is how far in advance a buffer must be queued for presentation at
1100      * a given time.  If you want a buffer to appear on the screen at
1101      * time N, you must submit the buffer before (N - presentationDeadline).
1102      * <p>
1103      * The desired presentation time for GLES rendering may be set with
1104      * {@link android.opengl.EGLExt#eglPresentationTimeANDROID}.  For video decoding, use
1105      * {@link android.media.MediaCodec#releaseOutputBuffer(int, long)}.  Times are
1106      * expressed in nanoseconds, using the system monotonic clock
1107      * ({@link System#nanoTime}).
1108      */
getPresentationDeadlineNanos()1109     public long getPresentationDeadlineNanos() {
1110         synchronized (this) {
1111             updateDisplayInfoLocked();
1112             return mDisplayInfo.presentationDeadlineNanos;
1113         }
1114     }
1115 
1116     /**
1117      * Gets display metrics that describe the size and density of this display.
1118      * The size returned by this method does not necessarily represent the
1119      * actual raw size (native resolution) of the display.
1120      * <p>
1121      * 1. The returned size may be adjusted to exclude certain system decor elements
1122      * that are always visible.
1123      * </p><p>
1124      * 2. It may be scaled to provide compatibility with older applications that
1125      * were originally designed for smaller displays.
1126      * </p><p>
1127      * 3. It can be different depending on the WindowManager to which the display belongs.
1128      * </p><p>
1129      * - If requested from non-Activity context (e.g. Application context via
1130      * {@code (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE)})
1131      * metrics will report the size of the entire display based on current rotation and with
1132      * subtracted system decoration areas.
1133      * </p><p>
1134      * - If requested from activity (either using {@code getWindowManager()} or
1135      * {@code (WindowManager) getSystemService(Context.WINDOW_SERVICE)}) resulting metrics will
1136      * correspond to current app window metrics. In this case the size can be smaller than physical
1137      * size in multi-window mode.
1138      * </p>
1139      *
1140      * @param outMetrics A {@link DisplayMetrics} object to receive the metrics.
1141      * @deprecated Use {@link WindowMetrics#getBounds()} to get the dimensions of the application
1142      * window area, and {@link Configuration#densityDpi} to get the current density.
1143      */
1144     @Deprecated
getMetrics(DisplayMetrics outMetrics)1145     public void getMetrics(DisplayMetrics outMetrics) {
1146         synchronized (this) {
1147             updateDisplayInfoLocked();
1148             mDisplayInfo.getAppMetrics(outMetrics, getDisplayAdjustments());
1149         }
1150     }
1151 
1152     /**
1153      * Gets the real size of the display without subtracting any window decor or
1154      * applying any compatibility scale factors.
1155      * <p>
1156      * The size is adjusted based on the current rotation of the display.
1157      * </p><p>
1158      * The real size may be smaller than the physical size of the screen when the
1159      * window manager is emulating a smaller display (using adb shell wm size).
1160      * </p>
1161      *
1162      * @param outSize Set to the real size of the display.
1163      */
getRealSize(Point outSize)1164     public void getRealSize(Point outSize) {
1165         synchronized (this) {
1166             updateDisplayInfoLocked();
1167             outSize.x = mDisplayInfo.logicalWidth;
1168             outSize.y = mDisplayInfo.logicalHeight;
1169             if (mMayAdjustByFixedRotation) {
1170                 getDisplayAdjustments().adjustSize(outSize, mDisplayInfo.rotation);
1171             }
1172         }
1173     }
1174 
1175     /**
1176      * Gets display metrics based on the real size of this display.
1177      * <p>
1178      * The size is adjusted based on the current rotation of the display.
1179      * </p><p>
1180      * The real size may be smaller than the physical size of the screen when the
1181      * window manager is emulating a smaller display (using adb shell wm size).
1182      * </p>
1183      *
1184      * @param outMetrics A {@link DisplayMetrics} object to receive the metrics.
1185      */
getRealMetrics(DisplayMetrics outMetrics)1186     public void getRealMetrics(DisplayMetrics outMetrics) {
1187         synchronized (this) {
1188             updateDisplayInfoLocked();
1189             mDisplayInfo.getLogicalMetrics(outMetrics,
1190                     CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
1191             if (mMayAdjustByFixedRotation) {
1192                 getDisplayAdjustments().adjustMetrics(outMetrics, mDisplayInfo.rotation);
1193             }
1194         }
1195     }
1196 
1197     /**
1198      * Gets the state of the display, such as whether it is on or off.
1199      *
1200      * @return The state of the display: one of {@link #STATE_OFF}, {@link #STATE_ON},
1201      * {@link #STATE_DOZE}, {@link #STATE_DOZE_SUSPEND}, {@link #STATE_ON_SUSPEND}, or
1202      * {@link #STATE_UNKNOWN}.
1203      */
getState()1204     public int getState() {
1205         synchronized (this) {
1206             updateDisplayInfoLocked();
1207             return mIsValid ? mDisplayInfo.state : STATE_UNKNOWN;
1208         }
1209     }
1210 
1211     /**
1212      * Returns true if the specified UID has access to this display.
1213      * @hide
1214      */
1215     @TestApi
hasAccess(int uid)1216     public boolean hasAccess(int uid) {
1217         return hasAccess(uid, mFlags, mOwnerUid, mDisplayId);
1218     }
1219 
1220     /** @hide */
hasAccess(int uid, int flags, int ownerUid, int displayId)1221     public static boolean hasAccess(int uid, int flags, int ownerUid, int displayId) {
1222         return (flags & Display.FLAG_PRIVATE) == 0
1223                 || uid == ownerUid
1224                 || uid == Process.SYSTEM_UID
1225                 || uid == 0
1226                 // Check if the UID is present on given display.
1227                 || DisplayManagerGlobal.getInstance().isUidPresentOnDisplay(uid, displayId);
1228     }
1229 
1230     /**
1231      * Returns true if the display is a public presentation display.
1232      * @hide
1233      */
isPublicPresentation()1234     public boolean isPublicPresentation() {
1235         return (mFlags & (Display.FLAG_PRIVATE | Display.FLAG_PRESENTATION)) ==
1236                 Display.FLAG_PRESENTATION;
1237     }
1238 
1239     /**
1240      * @return {@code true} if the display is a trusted display.
1241      *
1242      * @see #FLAG_TRUSTED
1243      * @hide
1244      */
isTrusted()1245     public boolean isTrusted() {
1246         return (mFlags & FLAG_TRUSTED) == FLAG_TRUSTED;
1247     }
1248 
updateDisplayInfoLocked()1249     private void updateDisplayInfoLocked() {
1250         // Note: The display manager caches display info objects on our behalf.
1251         DisplayInfo newInfo = mGlobal.getDisplayInfo(mDisplayId);
1252         if (newInfo == null) {
1253             // Preserve the old mDisplayInfo after the display is removed.
1254             if (mIsValid) {
1255                 mIsValid = false;
1256                 if (DEBUG) {
1257                     Log.d(TAG, "Logical display " + mDisplayId + " was removed.");
1258                 }
1259             }
1260         } else {
1261             // Use the new display info.  (It might be the same object if nothing changed.)
1262             mDisplayInfo = newInfo;
1263             if (!mIsValid) {
1264                 mIsValid = true;
1265                 if (DEBUG) {
1266                     Log.d(TAG, "Logical display " + mDisplayId + " was recreated.");
1267                 }
1268             }
1269         }
1270 
1271         mMayAdjustByFixedRotation = mResources != null
1272                 && mResources.hasOverrideDisplayAdjustments();
1273     }
1274 
updateCachedAppSizeIfNeededLocked()1275     private void updateCachedAppSizeIfNeededLocked() {
1276         long now = SystemClock.uptimeMillis();
1277         if (now > mLastCachedAppSizeUpdate + CACHED_APP_SIZE_DURATION_MILLIS) {
1278             updateDisplayInfoLocked();
1279             mDisplayInfo.getAppMetrics(mTempMetrics, getDisplayAdjustments());
1280             mCachedAppWidthCompat = mTempMetrics.widthPixels;
1281             mCachedAppHeightCompat = mTempMetrics.heightPixels;
1282             mLastCachedAppSizeUpdate = now;
1283         }
1284     }
1285 
1286     // For debugging purposes
1287     @Override
toString()1288     public String toString() {
1289         synchronized (this) {
1290             updateDisplayInfoLocked();
1291             final DisplayAdjustments adjustments = getDisplayAdjustments();
1292             mDisplayInfo.getAppMetrics(mTempMetrics, adjustments);
1293             return "Display id " + mDisplayId + ": " + mDisplayInfo
1294                     + (mMayAdjustByFixedRotation
1295                             ? (", " + adjustments.getFixedRotationAdjustments() + ", ") : ", ")
1296                     + mTempMetrics + ", isValid=" + mIsValid;
1297         }
1298     }
1299 
1300     /**
1301      * @hide
1302      */
typeToString(int type)1303     public static String typeToString(int type) {
1304         switch (type) {
1305             case TYPE_UNKNOWN:
1306                 return "UNKNOWN";
1307             case TYPE_INTERNAL:
1308                 return "INTERNAL";
1309             case TYPE_EXTERNAL:
1310                 return "EXTERNAL";
1311             case TYPE_WIFI:
1312                 return "WIFI";
1313             case TYPE_OVERLAY:
1314                 return "OVERLAY";
1315             case TYPE_VIRTUAL:
1316                 return "VIRTUAL";
1317             default:
1318                 return Integer.toString(type);
1319         }
1320     }
1321 
1322     /**
1323      * @hide
1324      */
stateToString(int state)1325     public static String stateToString(int state) {
1326         switch (state) {
1327             case STATE_UNKNOWN:
1328                 return "UNKNOWN";
1329             case STATE_OFF:
1330                 return "OFF";
1331             case STATE_ON:
1332                 return "ON";
1333             case STATE_DOZE:
1334                 return "DOZE";
1335             case STATE_DOZE_SUSPEND:
1336                 return "DOZE_SUSPEND";
1337             case STATE_VR:
1338                 return "VR";
1339             case STATE_ON_SUSPEND:
1340                 return "ON_SUSPEND";
1341             default:
1342                 return Integer.toString(state);
1343         }
1344     }
1345 
1346     /**
1347      * Returns true if display updates may be suspended while in the specified
1348      * display power state. In SUSPEND states, updates are absolutely forbidden.
1349      * @hide
1350      */
isSuspendedState(int state)1351     public static boolean isSuspendedState(int state) {
1352         return state == STATE_OFF || state == STATE_DOZE_SUSPEND || state == STATE_ON_SUSPEND;
1353     }
1354 
1355     /**
1356      * Returns true if the display may be in a reduced operating mode while in the
1357      * specified display power state.
1358      * @hide
1359      */
isDozeState(int state)1360     public static boolean isDozeState(int state) {
1361         return state == STATE_DOZE || state == STATE_DOZE_SUSPEND;
1362     }
1363 
1364     /**
1365      * Returns true if the display is in active state such as {@link #STATE_ON}
1366      * or {@link #STATE_VR}.
1367      * @hide
1368      */
isActiveState(int state)1369     public static boolean isActiveState(int state) {
1370         return state == STATE_ON || state == STATE_VR;
1371     }
1372 
1373     /**
1374      * A mode supported by a given display.
1375      *
1376      * @see Display#getSupportedModes()
1377      */
1378     public static final class Mode implements Parcelable {
1379         /**
1380          * @hide
1381          */
1382         public static final Mode[] EMPTY_ARRAY = new Mode[0];
1383 
1384         private final int mModeId;
1385         private final int mWidth;
1386         private final int mHeight;
1387         private final float mRefreshRate;
1388 
1389         /**
1390          * @hide
1391          */
1392         @UnsupportedAppUsage
Mode(int modeId, int width, int height, float refreshRate)1393         public Mode(int modeId, int width, int height, float refreshRate) {
1394             mModeId = modeId;
1395             mWidth = width;
1396             mHeight = height;
1397             mRefreshRate = refreshRate;
1398         }
1399 
1400         /**
1401          * Returns this mode's id.
1402          */
getModeId()1403         public int getModeId() {
1404             return mModeId;
1405         }
1406 
1407         /**
1408          * Returns the physical width of the display in pixels when configured in this mode's
1409          * resolution.
1410          * <p>
1411          * Note that due to application UI scaling, the number of pixels made available to
1412          * applications when the mode is active (as reported by {@link Display#getWidth()} may
1413          * differ from the mode's actual resolution (as reported by this function).
1414          * <p>
1415          * For example, applications running on a 4K display may have their UI laid out and rendered
1416          * in 1080p and then scaled up. Applications can take advantage of the extra resolution by
1417          * rendering content through a {@link android.view.SurfaceView} using full size buffers.
1418          */
getPhysicalWidth()1419         public int getPhysicalWidth() {
1420             return mWidth;
1421         }
1422 
1423         /**
1424          * Returns the physical height of the display in pixels when configured in this mode's
1425          * resolution.
1426          * <p>
1427          * Note that due to application UI scaling, the number of pixels made available to
1428          * applications when the mode is active (as reported by {@link Display#getHeight()} may
1429          * differ from the mode's actual resolution (as reported by this function).
1430          * <p>
1431          * For example, applications running on a 4K display may have their UI laid out and rendered
1432          * in 1080p and then scaled up. Applications can take advantage of the extra resolution by
1433          * rendering content through a {@link android.view.SurfaceView} using full size buffers.
1434          */
getPhysicalHeight()1435         public int getPhysicalHeight() {
1436             return mHeight;
1437         }
1438 
1439         /**
1440          * Returns the refresh rate in frames per second.
1441          */
getRefreshRate()1442         public float getRefreshRate() {
1443             return mRefreshRate;
1444         }
1445 
1446         /**
1447          * Returns {@code true} if this mode matches the given parameters.
1448          *
1449          * @hide
1450          */
matches(int width, int height, float refreshRate)1451         public boolean matches(int width, int height, float refreshRate) {
1452             return mWidth == width &&
1453                     mHeight == height &&
1454                     Float.floatToIntBits(mRefreshRate) == Float.floatToIntBits(refreshRate);
1455         }
1456 
1457         @Override
equals(Object other)1458         public boolean equals(Object other) {
1459             if (this == other) {
1460                 return true;
1461             }
1462             if (!(other instanceof Mode)) {
1463                 return false;
1464             }
1465             Mode that = (Mode) other;
1466             return mModeId == that.mModeId && matches(that.mWidth, that.mHeight, that.mRefreshRate);
1467         }
1468 
1469         @Override
hashCode()1470         public int hashCode() {
1471             int hash = 1;
1472             hash = hash * 17 + mModeId;
1473             hash = hash * 17 + mWidth;
1474             hash = hash * 17 + mHeight;
1475             hash = hash * 17 + Float.floatToIntBits(mRefreshRate);
1476             return hash;
1477         }
1478 
1479         @Override
toString()1480         public String toString() {
1481             return new StringBuilder("{")
1482                     .append("id=").append(mModeId)
1483                     .append(", width=").append(mWidth)
1484                     .append(", height=").append(mHeight)
1485                     .append(", fps=").append(mRefreshRate)
1486                     .append("}")
1487                     .toString();
1488         }
1489 
1490         @Override
describeContents()1491         public int describeContents() {
1492             return 0;
1493         }
1494 
Mode(Parcel in)1495         private Mode(Parcel in) {
1496             this(in.readInt(), in.readInt(), in.readInt(), in.readFloat());
1497         }
1498 
1499         @Override
writeToParcel(Parcel out, int parcelableFlags)1500         public void writeToParcel(Parcel out, int parcelableFlags) {
1501             out.writeInt(mModeId);
1502             out.writeInt(mWidth);
1503             out.writeInt(mHeight);
1504             out.writeFloat(mRefreshRate);
1505         }
1506 
1507         @SuppressWarnings("hiding")
1508         public static final @android.annotation.NonNull Parcelable.Creator<Mode> CREATOR
1509                 = new Parcelable.Creator<Mode>() {
1510             @Override
1511             public Mode createFromParcel(Parcel in) {
1512                 return new Mode(in);
1513             }
1514 
1515             @Override
1516             public Mode[] newArray(int size) {
1517                 return new Mode[size];
1518             }
1519         };
1520     }
1521 
1522     /**
1523      * Encapsulates the HDR capabilities of a given display.
1524      * For example, what HDR types it supports and details about the desired luminance data.
1525      * <p>You can get an instance for a given {@link Display} object with
1526      * {@link Display#getHdrCapabilities getHdrCapabilities()}.
1527      */
1528     public static final class HdrCapabilities implements Parcelable {
1529         /**
1530          * Invalid luminance value.
1531          */
1532         public static final float INVALID_LUMINANCE = -1;
1533         /**
1534          * Dolby Vision high dynamic range (HDR) display.
1535          */
1536         public static final int HDR_TYPE_DOLBY_VISION = 1;
1537         /**
1538          * HDR10 display.
1539          */
1540         public static final int HDR_TYPE_HDR10 = 2;
1541         /**
1542          * Hybrid Log-Gamma HDR display.
1543          */
1544         public static final int HDR_TYPE_HLG = 3;
1545 
1546         /**
1547          * HDR10+ display.
1548          */
1549         public static final int HDR_TYPE_HDR10_PLUS = 4;
1550 
1551         /** @hide */
1552         @IntDef(prefix = { "HDR_TYPE_" }, value = {
1553                 HDR_TYPE_DOLBY_VISION,
1554                 HDR_TYPE_HDR10,
1555                 HDR_TYPE_HLG,
1556                 HDR_TYPE_HDR10_PLUS,
1557         })
1558         @Retention(RetentionPolicy.SOURCE)
1559         public @interface HdrType {}
1560 
1561         private @HdrType int[] mSupportedHdrTypes = new int[0];
1562         private float mMaxLuminance = INVALID_LUMINANCE;
1563         private float mMaxAverageLuminance = INVALID_LUMINANCE;
1564         private float mMinLuminance = INVALID_LUMINANCE;
1565 
1566         /**
1567          * @hide
1568          */
HdrCapabilities()1569         public HdrCapabilities() {
1570         }
1571 
1572         /**
1573          * @hide
1574          */
1575         @UnsupportedAppUsage
HdrCapabilities(int[] supportedHdrTypes, float maxLuminance, float maxAverageLuminance, float minLuminance)1576         public HdrCapabilities(int[] supportedHdrTypes, float maxLuminance,
1577                 float maxAverageLuminance, float minLuminance) {
1578             mSupportedHdrTypes = supportedHdrTypes;
1579             Arrays.sort(mSupportedHdrTypes);
1580             mMaxLuminance = maxLuminance;
1581             mMaxAverageLuminance = maxAverageLuminance;
1582             mMinLuminance = minLuminance;
1583         }
1584 
1585         /**
1586          * Gets the supported HDR types of this display.
1587          * Returns empty array if HDR is not supported by the display.
1588          */
getSupportedHdrTypes()1589         public @HdrType int[] getSupportedHdrTypes() {
1590             return mSupportedHdrTypes;
1591         }
1592         /**
1593          * Returns the desired content max luminance data in cd/m2 for this display.
1594          */
getDesiredMaxLuminance()1595         public float getDesiredMaxLuminance() {
1596             return mMaxLuminance;
1597         }
1598         /**
1599          * Returns the desired content max frame-average luminance data in cd/m2 for this display.
1600          */
getDesiredMaxAverageLuminance()1601         public float getDesiredMaxAverageLuminance() {
1602             return mMaxAverageLuminance;
1603         }
1604         /**
1605          * Returns the desired content min luminance data in cd/m2 for this display.
1606          */
getDesiredMinLuminance()1607         public float getDesiredMinLuminance() {
1608             return mMinLuminance;
1609         }
1610 
1611         @Override
equals(Object other)1612         public boolean equals(Object other) {
1613             if (this == other) {
1614                 return true;
1615             }
1616 
1617             if (!(other instanceof HdrCapabilities)) {
1618                 return false;
1619             }
1620             HdrCapabilities that = (HdrCapabilities) other;
1621 
1622             return Arrays.equals(mSupportedHdrTypes, that.mSupportedHdrTypes)
1623                 && mMaxLuminance == that.mMaxLuminance
1624                 && mMaxAverageLuminance == that.mMaxAverageLuminance
1625                 && mMinLuminance == that.mMinLuminance;
1626         }
1627 
1628         @Override
hashCode()1629         public int hashCode() {
1630             int hash = 23;
1631             hash = hash * 17 + Arrays.hashCode(mSupportedHdrTypes);
1632             hash = hash * 17 + Float.floatToIntBits(mMaxLuminance);
1633             hash = hash * 17 + Float.floatToIntBits(mMaxAverageLuminance);
1634             hash = hash * 17 + Float.floatToIntBits(mMinLuminance);
1635             return hash;
1636         }
1637 
1638         public static final @android.annotation.NonNull Creator<HdrCapabilities> CREATOR = new Creator<HdrCapabilities>() {
1639             @Override
1640             public HdrCapabilities createFromParcel(Parcel source) {
1641                 return new HdrCapabilities(source);
1642             }
1643 
1644             @Override
1645             public HdrCapabilities[] newArray(int size) {
1646                 return new HdrCapabilities[size];
1647             }
1648         };
1649 
HdrCapabilities(Parcel source)1650         private HdrCapabilities(Parcel source) {
1651             readFromParcel(source);
1652         }
1653 
1654         /**
1655          * @hide
1656          */
readFromParcel(Parcel source)1657         public void readFromParcel(Parcel source) {
1658             int types = source.readInt();
1659             mSupportedHdrTypes = new int[types];
1660             for (int i = 0; i < types; ++i) {
1661                 mSupportedHdrTypes[i] = source.readInt();
1662             }
1663             mMaxLuminance = source.readFloat();
1664             mMaxAverageLuminance = source.readFloat();
1665             mMinLuminance = source.readFloat();
1666         }
1667 
1668         @Override
writeToParcel(Parcel dest, int flags)1669         public void writeToParcel(Parcel dest, int flags) {
1670             dest.writeInt(mSupportedHdrTypes.length);
1671             for (int i = 0; i < mSupportedHdrTypes.length; ++i) {
1672                 dest.writeInt(mSupportedHdrTypes[i]);
1673             }
1674             dest.writeFloat(mMaxLuminance);
1675             dest.writeFloat(mMaxAverageLuminance);
1676             dest.writeFloat(mMinLuminance);
1677         }
1678 
1679         @Override
describeContents()1680         public int describeContents() {
1681             return 0;
1682         }
1683 
1684         @Override
toString()1685         public String toString() {
1686             return "HdrCapabilities{"
1687                     + "mSupportedHdrTypes=" + Arrays.toString(mSupportedHdrTypes)
1688                     + ", mMaxLuminance=" + mMaxLuminance
1689                     + ", mMaxAverageLuminance=" + mMaxAverageLuminance
1690                     + ", mMinLuminance=" + mMinLuminance + '}';
1691         }
1692     }
1693 }
1694