• 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 android.annotation.IntDef;
20 import android.annotation.RequiresPermission;
21 import android.content.Context;
22 import android.content.res.CompatibilityInfo;
23 import android.content.res.Resources;
24 import android.graphics.PixelFormat;
25 import android.graphics.Point;
26 import android.graphics.Rect;
27 import android.hardware.display.DisplayManagerGlobal;
28 import android.os.Parcel;
29 import android.os.Parcelable;
30 import android.os.Process;
31 import android.os.SystemClock;
32 import android.util.DisplayMetrics;
33 import android.util.Log;
34 
35 import java.lang.annotation.Retention;
36 import java.lang.annotation.RetentionPolicy;
37 import java.util.Arrays;
38 
39 import static android.Manifest.permission.CONFIGURE_DISPLAY_COLOR_MODE;
40 
41 /**
42  * Provides information about the size and density of a logical display.
43  * <p>
44  * The display area is described in two different ways.
45  * <ul>
46  * <li>The application display area specifies the part of the display that may contain
47  * an application window, excluding the system decorations.  The application display area may
48  * be smaller than the real display area because the system subtracts the space needed
49  * for decor elements such as the status bar.  Use the following methods to query the
50  * application display area: {@link #getSize}, {@link #getRectSize} and {@link #getMetrics}.</li>
51  * <li>The real display area specifies the part of the display that contains content
52  * including the system decorations.  Even so, the real display area may be smaller than the
53  * physical size of the display if the window manager is emulating a smaller display
54  * using (adb shell am display-size).  Use the following methods to query the
55  * real display area: {@link #getRealSize}, {@link #getRealMetrics}.</li>
56  * </ul>
57  * </p><p>
58  * A logical display does not necessarily represent a particular physical display device
59  * such as the built-in screen or an external monitor.  The contents of a logical
60  * display may be presented on one or more physical displays according to the devices
61  * that are currently attached and whether mirroring has been enabled.
62  * </p>
63  */
64 public final class Display {
65     private static final String TAG = "Display";
66     private static final boolean DEBUG = false;
67 
68     private final DisplayManagerGlobal mGlobal;
69     private final int mDisplayId;
70     private final int mLayerStack;
71     private final int mFlags;
72     private final int mType;
73     private final String mAddress;
74     private final int mOwnerUid;
75     private final String mOwnerPackageName;
76     private final DisplayAdjustments mDisplayAdjustments;
77 
78     private DisplayInfo mDisplayInfo; // never null
79     private boolean mIsValid;
80 
81     // Temporary display metrics structure used for compatibility mode.
82     private final DisplayMetrics mTempMetrics = new DisplayMetrics();
83 
84     // We cache the app width and height properties briefly between calls
85     // to getHeight() and getWidth() to ensure that applications perceive
86     // consistent results when the size changes (most of the time).
87     // Applications should now be using getSize() instead.
88     private static final int CACHED_APP_SIZE_DURATION_MILLIS = 20;
89     private long mLastCachedAppSizeUpdate;
90     private int mCachedAppWidthCompat;
91     private int mCachedAppHeightCompat;
92 
93     /**
94      * The default Display id, which is the id of the built-in primary display
95      * assuming there is one.
96      */
97     public static final int DEFAULT_DISPLAY = 0;
98 
99     /**
100      * Invalid display id.
101      */
102     public static final int INVALID_DISPLAY = -1;
103 
104     /**
105      * Display flag: Indicates that the display supports compositing content
106      * that is stored in protected graphics buffers.
107      * <p>
108      * If this flag is set then the display device supports compositing protected buffers.
109      * </p><p>
110      * If this flag is not set then the display device may not support compositing
111      * protected buffers; the user may see a blank region on the screen instead of
112      * the protected content.
113      * </p><p>
114      * Secure (DRM) video decoders may allocate protected graphics buffers to request that
115      * a hardware-protected path be provided between the video decoder and the external
116      * display sink.  If a hardware-protected path is not available, then content stored
117      * in protected graphics buffers may not be composited.
118      * </p><p>
119      * An application can use the absence of this flag as a hint that it should not use protected
120      * buffers for this display because the content may not be visible.  For example,
121      * if the flag is not set then the application may choose not to show content on this
122      * display, show an informative error message, select an alternate content stream
123      * or adopt a different strategy for decoding content that does not rely on
124      * protected buffers.
125      * </p>
126      *
127      * @see #getFlags
128      */
129     public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1 << 0;
130 
131     /**
132      * Display flag: Indicates that the display has a secure video output and
133      * supports compositing secure surfaces.
134      * <p>
135      * If this flag is set then the display device has a secure video output
136      * and is capable of showing secure surfaces.  It may also be capable of
137      * showing {@link #FLAG_SUPPORTS_PROTECTED_BUFFERS protected buffers}.
138      * </p><p>
139      * If this flag is not set then the display device may not have a secure video
140      * output; the user may see a blank region on the screen instead of
141      * the contents of secure surfaces or protected buffers.
142      * </p><p>
143      * Secure surfaces are used to prevent content rendered into those surfaces
144      * by applications from appearing in screenshots or from being viewed
145      * on non-secure displays.  Protected buffers are used by secure video decoders
146      * for a similar purpose.
147      * </p><p>
148      * An application creates a window with a secure surface by specifying the
149      * {@link WindowManager.LayoutParams#FLAG_SECURE} window flag.
150      * Likewise, an application creates a {@link SurfaceView} with a secure surface
151      * by calling {@link SurfaceView#setSecure} before attaching the secure view to
152      * its containing window.
153      * </p><p>
154      * An application can use the absence of this flag as a hint that it should not create
155      * secure surfaces or protected buffers on this display because the content may
156      * not be visible.  For example, if the flag is not set then the application may
157      * choose not to show content on this display, show an informative error message,
158      * select an alternate content stream or adopt a different strategy for decoding
159      * content that does not rely on secure surfaces or protected buffers.
160      * </p>
161      *
162      * @see #getFlags
163      */
164     public static final int FLAG_SECURE = 1 << 1;
165 
166     /**
167      * Display flag: Indicates that the display is private.  Only the application that
168      * owns the display can create windows on it.
169      *
170      * @see #getFlags
171      */
172     public static final int FLAG_PRIVATE = 1 << 2;
173 
174     /**
175      * Display flag: Indicates that the display is a presentation display.
176      * <p>
177      * This flag identifies secondary displays that are suitable for
178      * use as presentation displays such as HDMI or Wireless displays.  Applications
179      * may automatically project their content to presentation displays to provide
180      * richer second screen experiences.
181      * </p>
182      *
183      * @see #getFlags
184      */
185     public static final int FLAG_PRESENTATION = 1 << 3;
186 
187     /**
188      * Display flag: Indicates that the display has a round shape.
189      * <p>
190      * This flag identifies displays that are circular, elliptical or otherwise
191      * do not permit the user to see all the way to the logical corners of the display.
192      * </p>
193      *
194      * @see #getFlags
195      */
196     public static final int FLAG_ROUND = 1 << 4;
197 
198     /**
199      * Display flag: Indicates that the contents of the display should not be scaled
200      * to fit the physical screen dimensions.  Used for development only to emulate
201      * devices with smaller physicals screens while preserving density.
202      *
203      * @hide
204      */
205     public static final int FLAG_SCALING_DISABLED = 1 << 30;
206 
207     /**
208      * Display type: Unknown display type.
209      * @hide
210      */
211     public static final int TYPE_UNKNOWN = 0;
212 
213     /**
214      * Display type: Built-in display.
215      * @hide
216      */
217     public static final int TYPE_BUILT_IN = 1;
218 
219     /**
220      * Display type: HDMI display.
221      * @hide
222      */
223     public static final int TYPE_HDMI = 2;
224 
225     /**
226      * Display type: WiFi display.
227      * @hide
228      */
229     public static final int TYPE_WIFI = 3;
230 
231     /**
232      * Display type: Overlay display.
233      * @hide
234      */
235     public static final int TYPE_OVERLAY = 4;
236 
237     /**
238      * Display type: Virtual display.
239      * @hide
240      */
241     public static final int TYPE_VIRTUAL = 5;
242 
243     /**
244      * Display state: The display state is unknown.
245      *
246      * @see #getState
247      */
248     public static final int STATE_UNKNOWN = 0;
249 
250     /**
251      * Display state: The display is off.
252      *
253      * @see #getState
254      */
255     public static final int STATE_OFF = 1;
256 
257     /**
258      * Display state: The display is on.
259      *
260      * @see #getState
261      */
262     public static final int STATE_ON = 2;
263 
264     /**
265      * Display state: The display is dozing in a low power state; it is still
266      * on but is optimized for showing system-provided content while the
267      * device is non-interactive.
268      *
269      * @see #getState
270      * @see android.os.PowerManager#isInteractive
271      */
272     public static final int STATE_DOZE = 3;
273 
274     /**
275      * Display state: The display is dozing in a suspended low power state; it is still
276      * on but is optimized for showing static system-provided content while the device
277      * is non-interactive.  This mode may be used to conserve even more power by allowing
278      * the hardware to stop applying frame buffer updates from the graphics subsystem or
279      * to take over the display and manage it autonomously to implement low power always-on
280      * display functionality.
281      *
282      * @see #getState
283      * @see android.os.PowerManager#isInteractive
284      */
285     public static final int STATE_DOZE_SUSPEND = 4;
286 
287     /* The color mode constants defined below must be kept in sync with the ones in
288      * system/graphics.h */
289 
290     /**
291      * Display color mode: The current color mode is unknown or invalid.
292      * @hide
293      */
294     public static final int COLOR_MODE_INVALID = -1;
295 
296     /**
297      * Display color mode: The default or native gamut of the display.
298      * @hide
299      */
300     public static final int COLOR_MODE_DEFAULT = 0;
301 
302     /**
303      * Display color mode: SRGB
304      * @hide
305      */
306     public static final int COLOR_MODE_SRGB = 7;
307 
308     /**
309      * Internal method to create a display.
310      * Applications should use {@link android.view.WindowManager#getDefaultDisplay()}
311      * or {@link android.hardware.display.DisplayManager#getDisplay}
312      * to get a display object.
313      *
314      * @hide
315      */
Display(DisplayManagerGlobal global, int displayId, DisplayInfo displayInfo , DisplayAdjustments daj)316     public Display(DisplayManagerGlobal global,
317             int displayId, DisplayInfo displayInfo /*not null*/,
318             DisplayAdjustments daj) {
319         mGlobal = global;
320         mDisplayId = displayId;
321         mDisplayInfo = displayInfo;
322         mDisplayAdjustments = new DisplayAdjustments(daj);
323         mIsValid = true;
324 
325         // Cache properties that cannot change as long as the display is valid.
326         mLayerStack = displayInfo.layerStack;
327         mFlags = displayInfo.flags;
328         mType = displayInfo.type;
329         mAddress = displayInfo.address;
330         mOwnerUid = displayInfo.ownerUid;
331         mOwnerPackageName = displayInfo.ownerPackageName;
332     }
333 
334     /**
335      * Gets the display id.
336      * <p>
337      * Each logical display has a unique id.
338      * The default display has id {@link #DEFAULT_DISPLAY}.
339      * </p>
340      */
getDisplayId()341     public int getDisplayId() {
342         return mDisplayId;
343     }
344 
345     /**
346      * Returns true if this display is still valid, false if the display has been removed.
347      *
348      * If the display is invalid, then the methods of this class will
349      * continue to report the most recently observed display information.
350      * However, it is unwise (and rather fruitless) to continue using a
351      * {@link Display} object after the display's demise.
352      *
353      * It's possible for a display that was previously invalid to become
354      * valid again if a display with the same id is reconnected.
355      *
356      * @return True if the display is still valid.
357      */
isValid()358     public boolean isValid() {
359         synchronized (this) {
360             updateDisplayInfoLocked();
361             return mIsValid;
362         }
363     }
364 
365     /**
366      * Gets a full copy of the display information.
367      *
368      * @param outDisplayInfo The object to receive the copy of the display information.
369      * @return True if the display is still valid.
370      * @hide
371      */
getDisplayInfo(DisplayInfo outDisplayInfo)372     public boolean getDisplayInfo(DisplayInfo outDisplayInfo) {
373         synchronized (this) {
374             updateDisplayInfoLocked();
375             outDisplayInfo.copyFrom(mDisplayInfo);
376             return mIsValid;
377         }
378     }
379 
380     /**
381      * Gets the display's layer stack.
382      *
383      * Each display has its own independent layer stack upon which surfaces
384      * are placed to be managed by surface flinger.
385      *
386      * @return The display's layer stack number.
387      * @hide
388      */
getLayerStack()389     public int getLayerStack() {
390         return mLayerStack;
391     }
392 
393     /**
394      * Returns a combination of flags that describe the capabilities of the display.
395      *
396      * @return The display flags.
397      *
398      * @see #FLAG_SUPPORTS_PROTECTED_BUFFERS
399      * @see #FLAG_SECURE
400      * @see #FLAG_PRIVATE
401      */
getFlags()402     public int getFlags() {
403         return mFlags;
404     }
405 
406     /**
407      * Gets the display type.
408      *
409      * @return The display type.
410      *
411      * @see #TYPE_UNKNOWN
412      * @see #TYPE_BUILT_IN
413      * @see #TYPE_HDMI
414      * @see #TYPE_WIFI
415      * @see #TYPE_OVERLAY
416      * @see #TYPE_VIRTUAL
417      * @hide
418      */
getType()419     public int getType() {
420         return mType;
421     }
422 
423     /**
424      * Gets the display address, or null if none.
425      * Interpretation varies by display type.
426      *
427      * @return The display address.
428      * @hide
429      */
getAddress()430     public String getAddress() {
431         return mAddress;
432     }
433 
434     /**
435      * Gets the UID of the application that owns this display, or zero if it is
436      * owned by the system.
437      * <p>
438      * If the display is private, then only the owner can use it.
439      * </p>
440      *
441      * @hide
442      */
getOwnerUid()443     public int getOwnerUid() {
444         return mOwnerUid;
445     }
446 
447     /**
448      * Gets the package name of the application that owns this display, or null if it is
449      * owned by the system.
450      * <p>
451      * If the display is private, then only the owner can use it.
452      * </p>
453      *
454      * @hide
455      */
getOwnerPackageName()456     public String getOwnerPackageName() {
457         return mOwnerPackageName;
458     }
459 
460     /**
461      * Gets the compatibility info used by this display instance.
462      *
463      * @return The display adjustments holder, or null if none is required.
464      * @hide
465      */
getDisplayAdjustments()466     public DisplayAdjustments getDisplayAdjustments() {
467         return mDisplayAdjustments;
468     }
469 
470     /**
471      * Gets the name of the display.
472      * <p>
473      * Note that some displays may be renamed by the user.
474      * </p>
475      *
476      * @return The display's name.
477      */
getName()478     public String getName() {
479         synchronized (this) {
480             updateDisplayInfoLocked();
481             return mDisplayInfo.name;
482         }
483     }
484 
485     /**
486      * Gets the size of the display, in pixels.
487      * Value returned by this method does not necessarily represent the actual raw size
488      * (native resolution) of the display.
489      * <p>
490      * 1. The returned size may be adjusted to exclude certain system decor elements
491      * that are always visible.
492      * </p><p>
493      * 2. It may be scaled to provide compatibility with older applications that
494      * were originally designed for smaller displays.
495      * </p><p>
496      * 3. It can be different depending on the WindowManager to which the display belongs.
497      * </p><p>
498      * - If requested from non-Activity context (e.g. Application context via
499      * {@code (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE)})
500      * it will report the size of the entire display based on current rotation and with subtracted
501      * system decoration areas.
502      * </p><p>
503      * - If requested from activity (either using {@code getWindowManager()} or
504      * {@code (WindowManager) getSystemService(Context.WINDOW_SERVICE)}) resulting size will
505      * correspond to current app window size. In this case it can be smaller than physical size in
506      * multi-window mode.
507      * </p><p>
508      * Typically for the purposes of layout apps should make a request from activity context
509      * to obtain size available for the app content.
510      * </p>
511      *
512      * @param outSize A {@link Point} object to receive the size information.
513      */
getSize(Point outSize)514     public void getSize(Point outSize) {
515         synchronized (this) {
516             updateDisplayInfoLocked();
517             mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments);
518             outSize.x = mTempMetrics.widthPixels;
519             outSize.y = mTempMetrics.heightPixels;
520         }
521     }
522 
523     /**
524      * Gets the size of the display as a rectangle, in pixels.
525      *
526      * @param outSize A {@link Rect} object to receive the size information.
527      * @see #getSize(Point)
528      */
getRectSize(Rect outSize)529     public void getRectSize(Rect outSize) {
530         synchronized (this) {
531             updateDisplayInfoLocked();
532             mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments);
533             outSize.set(0, 0, mTempMetrics.widthPixels, mTempMetrics.heightPixels);
534         }
535     }
536 
537     /**
538      * Return the range of display sizes an application can expect to encounter
539      * under normal operation, as long as there is no physical change in screen
540      * size.  This is basically the sizes you will see as the orientation
541      * changes, taking into account whatever screen decoration there is in
542      * each rotation.  For example, the status bar is always at the top of the
543      * screen, so it will reduce the height both in landscape and portrait, and
544      * the smallest height returned here will be the smaller of the two.
545      *
546      * This is intended for applications to get an idea of the range of sizes
547      * they will encounter while going through device rotations, to provide a
548      * stable UI through rotation.  The sizes here take into account all standard
549      * system decorations that reduce the size actually available to the
550      * application: the status bar, navigation bar, system bar, etc.  It does
551      * <em>not</em> take into account more transient elements like an IME
552      * soft keyboard.
553      *
554      * @param outSmallestSize Filled in with the smallest width and height
555      * that the application will encounter, in pixels (not dp units).  The x
556      * (width) dimension here directly corresponds to
557      * {@link android.content.res.Configuration#smallestScreenWidthDp
558      * Configuration.smallestScreenWidthDp}, except the value here is in raw
559      * screen pixels rather than dp units.  Your application may of course
560      * still get smaller space yet if, for example, a soft keyboard is
561      * being displayed.
562      * @param outLargestSize Filled in with the largest width and height
563      * that the application will encounter, in pixels (not dp units).  Your
564      * application may of course still get larger space than this if,
565      * for example, screen decorations like the status bar are being hidden.
566      */
getCurrentSizeRange(Point outSmallestSize, Point outLargestSize)567     public void getCurrentSizeRange(Point outSmallestSize, Point outLargestSize) {
568         synchronized (this) {
569             updateDisplayInfoLocked();
570             outSmallestSize.x = mDisplayInfo.smallestNominalAppWidth;
571             outSmallestSize.y = mDisplayInfo.smallestNominalAppHeight;
572             outLargestSize.x = mDisplayInfo.largestNominalAppWidth;
573             outLargestSize.y = mDisplayInfo.largestNominalAppHeight;
574         }
575     }
576 
577     /**
578      * Return the maximum screen size dimension that will happen.  This is
579      * mostly for wallpapers.
580      * @hide
581      */
getMaximumSizeDimension()582     public int getMaximumSizeDimension() {
583         synchronized (this) {
584             updateDisplayInfoLocked();
585             return Math.max(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
586         }
587     }
588 
589     /**
590      * @deprecated Use {@link #getSize(Point)} instead.
591      */
592     @Deprecated
getWidth()593     public int getWidth() {
594         synchronized (this) {
595             updateCachedAppSizeIfNeededLocked();
596             return mCachedAppWidthCompat;
597         }
598     }
599 
600     /**
601      * @deprecated Use {@link #getSize(Point)} instead.
602      */
603     @Deprecated
getHeight()604     public int getHeight() {
605         synchronized (this) {
606             updateCachedAppSizeIfNeededLocked();
607             return mCachedAppHeightCompat;
608         }
609     }
610 
611     /**
612      * @hide
613      * Return a rectangle defining the insets of the overscan region of the display.
614      * Each field of the rectangle is the number of pixels the overscan area extends
615      * into the display on that side.
616      */
getOverscanInsets(Rect outRect)617     public void getOverscanInsets(Rect outRect) {
618         synchronized (this) {
619             updateDisplayInfoLocked();
620             outRect.set(mDisplayInfo.overscanLeft, mDisplayInfo.overscanTop,
621                     mDisplayInfo.overscanRight, mDisplayInfo.overscanBottom);
622         }
623     }
624 
625     /**
626      * Returns the rotation of the screen from its "natural" orientation.
627      * The returned value may be {@link Surface#ROTATION_0 Surface.ROTATION_0}
628      * (no rotation), {@link Surface#ROTATION_90 Surface.ROTATION_90},
629      * {@link Surface#ROTATION_180 Surface.ROTATION_180}, or
630      * {@link Surface#ROTATION_270 Surface.ROTATION_270}.  For
631      * example, if a device has a naturally tall screen, and the user has
632      * turned it on its side to go into a landscape orientation, the value
633      * returned here may be either {@link Surface#ROTATION_90 Surface.ROTATION_90}
634      * or {@link Surface#ROTATION_270 Surface.ROTATION_270} depending on
635      * the direction it was turned.  The angle is the rotation of the drawn
636      * graphics on the screen, which is the opposite direction of the physical
637      * rotation of the device.  For example, if the device is rotated 90
638      * degrees counter-clockwise, to compensate rendering will be rotated by
639      * 90 degrees clockwise and thus the returned value here will be
640      * {@link Surface#ROTATION_90 Surface.ROTATION_90}.
641      */
642     @Surface.Rotation
getRotation()643     public int getRotation() {
644         synchronized (this) {
645             updateDisplayInfoLocked();
646             return mDisplayInfo.rotation;
647         }
648     }
649 
650     /**
651      * @deprecated use {@link #getRotation}
652      * @return orientation of this display.
653      */
654     @Deprecated
655     @Surface.Rotation
getOrientation()656     public int getOrientation() {
657         return getRotation();
658     }
659 
660     /**
661      * Gets the pixel format of the display.
662      * @return One of the constants defined in {@link android.graphics.PixelFormat}.
663      *
664      * @deprecated This method is no longer supported.
665      * The result is always {@link PixelFormat#RGBA_8888}.
666      */
667     @Deprecated
getPixelFormat()668     public int getPixelFormat() {
669         return PixelFormat.RGBA_8888;
670     }
671 
672     /**
673      * Gets the refresh rate of this display in frames per second.
674      */
getRefreshRate()675     public float getRefreshRate() {
676         synchronized (this) {
677             updateDisplayInfoLocked();
678             return mDisplayInfo.getMode().getRefreshRate();
679         }
680     }
681 
682     /**
683      * Get the supported refresh rates of this display in frames per second.
684      * <p>
685      * This method only returns refresh rates for the display's default modes. For more options, use
686      * {@link #getSupportedModes()}.
687      *
688      * @deprecated use {@link #getSupportedModes()} instead
689      */
690     @Deprecated
getSupportedRefreshRates()691     public float[] getSupportedRefreshRates() {
692         synchronized (this) {
693             updateDisplayInfoLocked();
694             return mDisplayInfo.getDefaultRefreshRates();
695         }
696     }
697 
698     /**
699      * Returns the active mode of the display.
700      */
getMode()701     public Mode getMode() {
702         synchronized (this) {
703             updateDisplayInfoLocked();
704             return mDisplayInfo.getMode();
705         }
706     }
707 
708     /**
709      * Gets the supported modes of this display.
710      */
getSupportedModes()711     public Mode[] getSupportedModes() {
712         synchronized (this) {
713             updateDisplayInfoLocked();
714             final Display.Mode[] modes = mDisplayInfo.supportedModes;
715             return Arrays.copyOf(modes, modes.length);
716         }
717     }
718 
719     /**
720      * Request the display applies a color mode.
721      * @hide
722      */
723     @RequiresPermission(CONFIGURE_DISPLAY_COLOR_MODE)
requestColorMode(int colorMode)724     public void requestColorMode(int colorMode) {
725         mGlobal.requestColorMode(mDisplayId, colorMode);
726     }
727 
728     /**
729      * Returns the active color mode of this display
730      * @hide
731      */
getColorMode()732     public int getColorMode() {
733         synchronized (this) {
734             updateDisplayInfoLocked();
735             return mDisplayInfo.colorMode;
736         }
737     }
738 
739     /**
740      * Returns the display's HDR capabilities.
741      */
getHdrCapabilities()742     public HdrCapabilities getHdrCapabilities() {
743         synchronized (this) {
744             updateDisplayInfoLocked();
745             return mDisplayInfo.hdrCapabilities;
746         }
747     }
748 
749     /**
750      * Gets the supported color modes of this device.
751      * @hide
752      */
getSupportedColorModes()753     public int[] getSupportedColorModes() {
754         synchronized (this) {
755             updateDisplayInfoLocked();
756             int[] colorModes = mDisplayInfo.supportedColorModes;
757             return Arrays.copyOf(colorModes, colorModes.length);
758         }
759     }
760 
761     /**
762      * Gets the app VSYNC offset, in nanoseconds.  This is a positive value indicating
763      * the phase offset of the VSYNC events provided by Choreographer relative to the
764      * display refresh.  For example, if Choreographer reports that the refresh occurred
765      * at time N, it actually occurred at (N - appVsyncOffset).
766      * <p>
767      * Apps generally do not need to be aware of this.  It's only useful for fine-grained
768      * A/V synchronization.
769      */
getAppVsyncOffsetNanos()770     public long getAppVsyncOffsetNanos() {
771         synchronized (this) {
772             updateDisplayInfoLocked();
773             return mDisplayInfo.appVsyncOffsetNanos;
774         }
775     }
776 
777     /**
778      * This is how far in advance a buffer must be queued for presentation at
779      * a given time.  If you want a buffer to appear on the screen at
780      * time N, you must submit the buffer before (N - presentationDeadline).
781      * <p>
782      * The desired presentation time for GLES rendering may be set with
783      * {@link android.opengl.EGLExt#eglPresentationTimeANDROID}.  For video decoding, use
784      * {@link android.media.MediaCodec#releaseOutputBuffer(int, long)}.  Times are
785      * expressed in nanoseconds, using the system monotonic clock
786      * ({@link System#nanoTime}).
787      */
getPresentationDeadlineNanos()788     public long getPresentationDeadlineNanos() {
789         synchronized (this) {
790             updateDisplayInfoLocked();
791             return mDisplayInfo.presentationDeadlineNanos;
792         }
793     }
794 
795     /**
796      * Gets display metrics that describe the size and density of this display.
797      * The size returned by this method does not necessarily represent the
798      * actual raw size (native resolution) of the display.
799      * <p>
800      * 1. The returned size may be adjusted to exclude certain system decor elements
801      * that are always visible.
802      * </p><p>
803      * 2. It may be scaled to provide compatibility with older applications that
804      * were originally designed for smaller displays.
805      * </p><p>
806      * 3. It can be different depending on the WindowManager to which the display belongs.
807      * </p><p>
808      * - If requested from non-Activity context (e.g. Application context via
809      * {@code (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE)})
810      * metrics will report the size of the entire display based on current rotation and with
811      * subtracted system decoration areas.
812      * </p><p>
813      * - If requested from activity (either using {@code getWindowManager()} or
814      * {@code (WindowManager) getSystemService(Context.WINDOW_SERVICE)}) resulting metrics will
815      * correspond to current app window metrics. In this case the size can be smaller than physical
816      * size in multi-window mode.
817      * </p>
818      *
819      * @param outMetrics A {@link DisplayMetrics} object to receive the metrics.
820      */
getMetrics(DisplayMetrics outMetrics)821     public void getMetrics(DisplayMetrics outMetrics) {
822         synchronized (this) {
823             updateDisplayInfoLocked();
824             mDisplayInfo.getAppMetrics(outMetrics, mDisplayAdjustments);
825         }
826     }
827 
828     /**
829      * Gets the real size of the display without subtracting any window decor or
830      * applying any compatibility scale factors.
831      * <p>
832      * The size is adjusted based on the current rotation of the display.
833      * </p><p>
834      * The real size may be smaller than the physical size of the screen when the
835      * window manager is emulating a smaller display (using adb shell am display-size).
836      * </p>
837      *
838      * @param outSize Set to the real size of the display.
839      */
getRealSize(Point outSize)840     public void getRealSize(Point outSize) {
841         synchronized (this) {
842             updateDisplayInfoLocked();
843             outSize.x = mDisplayInfo.logicalWidth;
844             outSize.y = mDisplayInfo.logicalHeight;
845         }
846     }
847 
848     /**
849      * Gets display metrics based on the real size of this display.
850      * <p>
851      * The size is adjusted based on the current rotation of the display.
852      * </p><p>
853      * The real size may be smaller than the physical size of the screen when the
854      * window manager is emulating a smaller display (using adb shell wm size).
855      * </p>
856      *
857      * @param outMetrics A {@link DisplayMetrics} object to receive the metrics.
858      */
getRealMetrics(DisplayMetrics outMetrics)859     public void getRealMetrics(DisplayMetrics outMetrics) {
860         synchronized (this) {
861             updateDisplayInfoLocked();
862             mDisplayInfo.getLogicalMetrics(outMetrics,
863                     CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
864         }
865     }
866 
867     /**
868      * Gets the state of the display, such as whether it is on or off.
869      *
870      * @return The state of the display: one of {@link #STATE_OFF}, {@link #STATE_ON},
871      * {@link #STATE_DOZE}, {@link #STATE_DOZE_SUSPEND}, or {@link #STATE_UNKNOWN}.
872      */
getState()873     public int getState() {
874         synchronized (this) {
875             updateDisplayInfoLocked();
876             return mIsValid ? mDisplayInfo.state : STATE_UNKNOWN;
877         }
878     }
879 
880     /**
881      * Returns true if the specified UID has access to this display.
882      * @hide
883      */
hasAccess(int uid)884     public boolean hasAccess(int uid) {
885         return Display.hasAccess(uid, mFlags, mOwnerUid);
886     }
887 
888     /** @hide */
hasAccess(int uid, int flags, int ownerUid)889     public static boolean hasAccess(int uid, int flags, int ownerUid) {
890         return (flags & Display.FLAG_PRIVATE) == 0
891                 || uid == ownerUid
892                 || uid == Process.SYSTEM_UID
893                 || uid == 0;
894     }
895 
896     /**
897      * Returns true if the display is a public presentation display.
898      * @hide
899      */
isPublicPresentation()900     public boolean isPublicPresentation() {
901         return (mFlags & (Display.FLAG_PRIVATE | Display.FLAG_PRESENTATION)) ==
902                 Display.FLAG_PRESENTATION;
903     }
904 
updateDisplayInfoLocked()905     private void updateDisplayInfoLocked() {
906         // Note: The display manager caches display info objects on our behalf.
907         DisplayInfo newInfo = mGlobal.getDisplayInfo(mDisplayId);
908         if (newInfo == null) {
909             // Preserve the old mDisplayInfo after the display is removed.
910             if (mIsValid) {
911                 mIsValid = false;
912                 if (DEBUG) {
913                     Log.d(TAG, "Logical display " + mDisplayId + " was removed.");
914                 }
915             }
916         } else {
917             // Use the new display info.  (It might be the same object if nothing changed.)
918             mDisplayInfo = newInfo;
919             if (!mIsValid) {
920                 mIsValid = true;
921                 if (DEBUG) {
922                     Log.d(TAG, "Logical display " + mDisplayId + " was recreated.");
923                 }
924             }
925         }
926     }
927 
updateCachedAppSizeIfNeededLocked()928     private void updateCachedAppSizeIfNeededLocked() {
929         long now = SystemClock.uptimeMillis();
930         if (now > mLastCachedAppSizeUpdate + CACHED_APP_SIZE_DURATION_MILLIS) {
931             updateDisplayInfoLocked();
932             mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments);
933             mCachedAppWidthCompat = mTempMetrics.widthPixels;
934             mCachedAppHeightCompat = mTempMetrics.heightPixels;
935             mLastCachedAppSizeUpdate = now;
936         }
937     }
938 
939     // For debugging purposes
940     @Override
toString()941     public String toString() {
942         synchronized (this) {
943             updateDisplayInfoLocked();
944             mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments);
945             return "Display id " + mDisplayId + ": " + mDisplayInfo
946                     + ", " + mTempMetrics + ", isValid=" + mIsValid;
947         }
948     }
949 
950     /**
951      * @hide
952      */
typeToString(int type)953     public static String typeToString(int type) {
954         switch (type) {
955             case TYPE_UNKNOWN:
956                 return "UNKNOWN";
957             case TYPE_BUILT_IN:
958                 return "BUILT_IN";
959             case TYPE_HDMI:
960                 return "HDMI";
961             case TYPE_WIFI:
962                 return "WIFI";
963             case TYPE_OVERLAY:
964                 return "OVERLAY";
965             case TYPE_VIRTUAL:
966                 return "VIRTUAL";
967             default:
968                 return Integer.toString(type);
969         }
970     }
971 
972     /**
973      * @hide
974      */
stateToString(int state)975     public static String stateToString(int state) {
976         switch (state) {
977             case STATE_UNKNOWN:
978                 return "UNKNOWN";
979             case STATE_OFF:
980                 return "OFF";
981             case STATE_ON:
982                 return "ON";
983             case STATE_DOZE:
984                 return "DOZE";
985             case STATE_DOZE_SUSPEND:
986                 return "DOZE_SUSPEND";
987             default:
988                 return Integer.toString(state);
989         }
990     }
991 
992     /**
993      * Returns true if display updates may be suspended while in the specified
994      * display power state.
995      * @hide
996      */
isSuspendedState(int state)997     public static boolean isSuspendedState(int state) {
998         return state == STATE_OFF || state == STATE_DOZE_SUSPEND;
999     }
1000 
1001     /**
1002      * A mode supported by a given display.
1003      *
1004      * @see Display#getSupportedModes()
1005      */
1006     public static final class Mode implements Parcelable {
1007         /**
1008          * @hide
1009          */
1010         public static final Mode[] EMPTY_ARRAY = new Mode[0];
1011 
1012         private final int mModeId;
1013         private final int mWidth;
1014         private final int mHeight;
1015         private final float mRefreshRate;
1016 
1017         /**
1018          * @hide
1019          */
Mode(int modeId, int width, int height, float refreshRate)1020         public Mode(int modeId, int width, int height, float refreshRate) {
1021             mModeId = modeId;
1022             mWidth = width;
1023             mHeight = height;
1024             mRefreshRate = refreshRate;
1025         }
1026 
1027         /**
1028          * Returns this mode's id.
1029          */
getModeId()1030         public int getModeId() {
1031             return mModeId;
1032         }
1033 
1034         /**
1035          * Returns the physical width of the display in pixels when configured in this mode's
1036          * resolution.
1037          * <p>
1038          * Note that due to application UI scaling, the number of pixels made available to
1039          * applications when the mode is active (as reported by {@link Display#getWidth()} may
1040          * differ from the mode's actual resolution (as reported by this function).
1041          * <p>
1042          * For example, applications running on a 4K display may have their UI laid out and rendered
1043          * in 1080p and then scaled up. Applications can take advantage of the extra resolution by
1044          * rendering content through a {@link android.view.SurfaceView} using full size buffers.
1045          */
getPhysicalWidth()1046         public int getPhysicalWidth() {
1047             return mWidth;
1048         }
1049 
1050         /**
1051          * Returns the physical height of the display in pixels when configured in this mode's
1052          * resolution.
1053          * <p>
1054          * Note that due to application UI scaling, the number of pixels made available to
1055          * applications when the mode is active (as reported by {@link Display#getHeight()} may
1056          * differ from the mode's actual resolution (as reported by this function).
1057          * <p>
1058          * For example, applications running on a 4K display may have their UI laid out and rendered
1059          * in 1080p and then scaled up. Applications can take advantage of the extra resolution by
1060          * rendering content through a {@link android.view.SurfaceView} using full size buffers.
1061          */
getPhysicalHeight()1062         public int getPhysicalHeight() {
1063             return mHeight;
1064         }
1065 
1066         /**
1067          * Returns the refresh rate in frames per second.
1068          */
getRefreshRate()1069         public float getRefreshRate() {
1070             return mRefreshRate;
1071         }
1072 
1073         /**
1074          * Returns {@code true} if this mode matches the given parameters.
1075          *
1076          * @hide
1077          */
matches(int width, int height, float refreshRate)1078         public boolean matches(int width, int height, float refreshRate) {
1079             return mWidth == width &&
1080                     mHeight == height &&
1081                     Float.floatToIntBits(mRefreshRate) == Float.floatToIntBits(refreshRate);
1082         }
1083 
1084         @Override
equals(Object other)1085         public boolean equals(Object other) {
1086             if (this == other) {
1087                 return true;
1088             }
1089             if (!(other instanceof Mode)) {
1090                 return false;
1091             }
1092             Mode that = (Mode) other;
1093             return mModeId == that.mModeId && matches(that.mWidth, that.mHeight, that.mRefreshRate);
1094         }
1095 
1096         @Override
hashCode()1097         public int hashCode() {
1098             int hash = 1;
1099             hash = hash * 17 + mModeId;
1100             hash = hash * 17 + mWidth;
1101             hash = hash * 17 + mHeight;
1102             hash = hash * 17 + Float.floatToIntBits(mRefreshRate);
1103             return hash;
1104         }
1105 
1106         @Override
toString()1107         public String toString() {
1108             return new StringBuilder("{")
1109                     .append("id=").append(mModeId)
1110                     .append(", width=").append(mWidth)
1111                     .append(", height=").append(mHeight)
1112                     .append(", fps=").append(mRefreshRate)
1113                     .append("}")
1114                     .toString();
1115         }
1116 
1117         @Override
describeContents()1118         public int describeContents() {
1119             return 0;
1120         }
1121 
Mode(Parcel in)1122         private Mode(Parcel in) {
1123             this(in.readInt(), in.readInt(), in.readInt(), in.readFloat());
1124         }
1125 
1126         @Override
writeToParcel(Parcel out, int parcelableFlags)1127         public void writeToParcel(Parcel out, int parcelableFlags) {
1128             out.writeInt(mModeId);
1129             out.writeInt(mWidth);
1130             out.writeInt(mHeight);
1131             out.writeFloat(mRefreshRate);
1132         }
1133 
1134         @SuppressWarnings("hiding")
1135         public static final Parcelable.Creator<Mode> CREATOR
1136                 = new Parcelable.Creator<Mode>() {
1137             @Override
1138             public Mode createFromParcel(Parcel in) {
1139                 return new Mode(in);
1140             }
1141 
1142             @Override
1143             public Mode[] newArray(int size) {
1144                 return new Mode[size];
1145             }
1146         };
1147     }
1148 
1149     /**
1150      * Encapsulates the HDR capabilities of a given display.
1151      * For example, what HDR types it supports and details about the desired luminance data.
1152      * <p>You can get an instance for a given {@link Display} object with
1153      * {@link Display#getHdrCapabilities getHdrCapabilities()}.
1154      */
1155     public static final class HdrCapabilities implements Parcelable {
1156         /**
1157          * Invalid luminance value.
1158          */
1159         public static final float INVALID_LUMINANCE = -1;
1160         /**
1161          * Dolby Vision high dynamic range (HDR) display.
1162          */
1163         public static final int HDR_TYPE_DOLBY_VISION = 1;
1164         /**
1165          * HDR10 display.
1166          */
1167         public static final int HDR_TYPE_HDR10 = 2;
1168         /**
1169          * Hybrid Log-Gamma HDR display.
1170          */
1171         public static final int HDR_TYPE_HLG = 3;
1172 
1173         /** @hide */
1174         @IntDef({
1175             HDR_TYPE_DOLBY_VISION,
1176             HDR_TYPE_HDR10,
1177             HDR_TYPE_HLG,
1178         })
1179         @Retention(RetentionPolicy.SOURCE)
1180         public @interface HdrType {}
1181 
1182         private @HdrType int[] mSupportedHdrTypes = new int[0];
1183         private float mMaxLuminance = INVALID_LUMINANCE;
1184         private float mMaxAverageLuminance = INVALID_LUMINANCE;
1185         private float mMinLuminance = INVALID_LUMINANCE;
1186 
1187         /**
1188          * @hide
1189          */
HdrCapabilities()1190         public HdrCapabilities() {
1191         }
1192 
1193         /**
1194          * @hide
1195          */
HdrCapabilities(int[] supportedHdrTypes, float maxLuminance, float maxAverageLuminance, float minLuminance)1196         public HdrCapabilities(int[] supportedHdrTypes, float maxLuminance,
1197                 float maxAverageLuminance, float minLuminance) {
1198             mSupportedHdrTypes = supportedHdrTypes;
1199             mMaxLuminance = maxLuminance;
1200             mMaxAverageLuminance = maxAverageLuminance;
1201             mMinLuminance = minLuminance;
1202         }
1203 
1204         /**
1205          * Gets the supported HDR types of this display.
1206          * Returns empty array if HDR is not supported by the display.
1207          */
getSupportedHdrTypes()1208         public @HdrType int[] getSupportedHdrTypes() {
1209             return mSupportedHdrTypes;
1210         }
1211         /**
1212          * Returns the desired content max luminance data in cd/m2 for this display.
1213          */
getDesiredMaxLuminance()1214         public float getDesiredMaxLuminance() {
1215             return mMaxLuminance;
1216         }
1217         /**
1218          * Returns the desired content max frame-average luminance data in cd/m2 for this display.
1219          */
getDesiredMaxAverageLuminance()1220         public float getDesiredMaxAverageLuminance() {
1221             return mMaxAverageLuminance;
1222         }
1223         /**
1224          * Returns the desired content min luminance data in cd/m2 for this display.
1225          */
getDesiredMinLuminance()1226         public float getDesiredMinLuminance() {
1227             return mMinLuminance;
1228         }
1229 
1230         @Override
equals(Object other)1231         public boolean equals(Object other) {
1232             if (this == other) {
1233                 return true;
1234             }
1235 
1236             if (!(other instanceof HdrCapabilities)) {
1237                 return false;
1238             }
1239             HdrCapabilities that = (HdrCapabilities) other;
1240 
1241             return Arrays.equals(mSupportedHdrTypes, that.mSupportedHdrTypes)
1242                 && mMaxLuminance == that.mMaxLuminance
1243                 && mMaxAverageLuminance == that.mMaxAverageLuminance
1244                 && mMinLuminance == that.mMinLuminance;
1245         }
1246 
1247         @Override
hashCode()1248         public int hashCode() {
1249             int hash = 23;
1250             hash = hash * 17 + Arrays.hashCode(mSupportedHdrTypes);
1251             hash = hash * 17 + Float.floatToIntBits(mMaxLuminance);
1252             hash = hash * 17 + Float.floatToIntBits(mMaxAverageLuminance);
1253             hash = hash * 17 + Float.floatToIntBits(mMinLuminance);
1254             return hash;
1255         }
1256 
1257         public static final Creator<HdrCapabilities> CREATOR = new Creator<HdrCapabilities>() {
1258             @Override
1259             public HdrCapabilities createFromParcel(Parcel source) {
1260                 return new HdrCapabilities(source);
1261             }
1262 
1263             @Override
1264             public HdrCapabilities[] newArray(int size) {
1265                 return new HdrCapabilities[size];
1266             }
1267         };
1268 
HdrCapabilities(Parcel source)1269         private HdrCapabilities(Parcel source) {
1270             readFromParcel(source);
1271         }
1272 
1273         /**
1274          * @hide
1275          */
readFromParcel(Parcel source)1276         public void readFromParcel(Parcel source) {
1277             int types = source.readInt();
1278             mSupportedHdrTypes = new int[types];
1279             for (int i = 0; i < types; ++i) {
1280                 mSupportedHdrTypes[i] = source.readInt();
1281             }
1282             mMaxLuminance = source.readFloat();
1283             mMaxAverageLuminance = source.readFloat();
1284             mMinLuminance = source.readFloat();
1285         }
1286 
1287         @Override
writeToParcel(Parcel dest, int flags)1288         public void writeToParcel(Parcel dest, int flags) {
1289             dest.writeInt(mSupportedHdrTypes.length);
1290             for (int i = 0; i < mSupportedHdrTypes.length; ++i) {
1291                 dest.writeInt(mSupportedHdrTypes[i]);
1292             }
1293             dest.writeFloat(mMaxLuminance);
1294             dest.writeFloat(mMaxAverageLuminance);
1295             dest.writeFloat(mMinLuminance);
1296         }
1297 
1298         @Override
describeContents()1299         public int describeContents() {
1300             return 0;
1301         }
1302     }
1303 }
1304