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