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_TRANSFORM;
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     /**
288      * Internal method to create a display.
289      * Applications should use {@link android.view.WindowManager#getDefaultDisplay()}
290      * or {@link android.hardware.display.DisplayManager#getDisplay}
291      * to get a display object.
292      *
293      * @hide
294      */
Display(DisplayManagerGlobal global, int displayId, DisplayInfo displayInfo , DisplayAdjustments daj)295     public Display(DisplayManagerGlobal global,
296             int displayId, DisplayInfo displayInfo /*not null*/,
297             DisplayAdjustments daj) {
298         mGlobal = global;
299         mDisplayId = displayId;
300         mDisplayInfo = displayInfo;
301         mDisplayAdjustments = new DisplayAdjustments(daj);
302         mIsValid = true;
303 
304         // Cache properties that cannot change as long as the display is valid.
305         mLayerStack = displayInfo.layerStack;
306         mFlags = displayInfo.flags;
307         mType = displayInfo.type;
308         mAddress = displayInfo.address;
309         mOwnerUid = displayInfo.ownerUid;
310         mOwnerPackageName = displayInfo.ownerPackageName;
311     }
312 
313     /**
314      * Gets the display id.
315      * <p>
316      * Each logical display has a unique id.
317      * The default display has id {@link #DEFAULT_DISPLAY}.
318      * </p>
319      */
getDisplayId()320     public int getDisplayId() {
321         return mDisplayId;
322     }
323 
324     /**
325      * Returns true if this display is still valid, false if the display has been removed.
326      *
327      * If the display is invalid, then the methods of this class will
328      * continue to report the most recently observed display information.
329      * However, it is unwise (and rather fruitless) to continue using a
330      * {@link Display} object after the display's demise.
331      *
332      * It's possible for a display that was previously invalid to become
333      * valid again if a display with the same id is reconnected.
334      *
335      * @return True if the display is still valid.
336      */
isValid()337     public boolean isValid() {
338         synchronized (this) {
339             updateDisplayInfoLocked();
340             return mIsValid;
341         }
342     }
343 
344     /**
345      * Gets a full copy of the display information.
346      *
347      * @param outDisplayInfo The object to receive the copy of the display information.
348      * @return True if the display is still valid.
349      * @hide
350      */
getDisplayInfo(DisplayInfo outDisplayInfo)351     public boolean getDisplayInfo(DisplayInfo outDisplayInfo) {
352         synchronized (this) {
353             updateDisplayInfoLocked();
354             outDisplayInfo.copyFrom(mDisplayInfo);
355             return mIsValid;
356         }
357     }
358 
359     /**
360      * Gets the display's layer stack.
361      *
362      * Each display has its own independent layer stack upon which surfaces
363      * are placed to be managed by surface flinger.
364      *
365      * @return The display's layer stack number.
366      * @hide
367      */
getLayerStack()368     public int getLayerStack() {
369         return mLayerStack;
370     }
371 
372     /**
373      * Returns a combination of flags that describe the capabilities of the display.
374      *
375      * @return The display flags.
376      *
377      * @see #FLAG_SUPPORTS_PROTECTED_BUFFERS
378      * @see #FLAG_SECURE
379      * @see #FLAG_PRIVATE
380      */
getFlags()381     public int getFlags() {
382         return mFlags;
383     }
384 
385     /**
386      * Gets the display type.
387      *
388      * @return The display type.
389      *
390      * @see #TYPE_UNKNOWN
391      * @see #TYPE_BUILT_IN
392      * @see #TYPE_HDMI
393      * @see #TYPE_WIFI
394      * @see #TYPE_OVERLAY
395      * @see #TYPE_VIRTUAL
396      * @hide
397      */
getType()398     public int getType() {
399         return mType;
400     }
401 
402     /**
403      * Gets the display address, or null if none.
404      * Interpretation varies by display type.
405      *
406      * @return The display address.
407      * @hide
408      */
getAddress()409     public String getAddress() {
410         return mAddress;
411     }
412 
413     /**
414      * Gets the UID of the application that owns this display, or zero if it is
415      * owned by the system.
416      * <p>
417      * If the display is private, then only the owner can use it.
418      * </p>
419      *
420      * @hide
421      */
getOwnerUid()422     public int getOwnerUid() {
423         return mOwnerUid;
424     }
425 
426     /**
427      * Gets the package name of the application that owns this display, or null if it is
428      * owned by the system.
429      * <p>
430      * If the display is private, then only the owner can use it.
431      * </p>
432      *
433      * @hide
434      */
getOwnerPackageName()435     public String getOwnerPackageName() {
436         return mOwnerPackageName;
437     }
438 
439     /**
440      * Gets the compatibility info used by this display instance.
441      *
442      * @return The display adjustments holder, or null if none is required.
443      * @hide
444      */
getDisplayAdjustments()445     public DisplayAdjustments getDisplayAdjustments() {
446         return mDisplayAdjustments;
447     }
448 
449     /**
450      * Gets the name of the display.
451      * <p>
452      * Note that some displays may be renamed by the user.
453      * </p>
454      *
455      * @return The display's name.
456      */
getName()457     public String getName() {
458         synchronized (this) {
459             updateDisplayInfoLocked();
460             return mDisplayInfo.name;
461         }
462     }
463 
464     /**
465      * Gets the size of the display, in pixels.
466      * <p>
467      * Note that this value should <em>not</em> be used for computing layouts,
468      * since a device will typically have screen decoration (such as a status bar)
469      * along the edges of the display that reduce the amount of application
470      * space available from the size returned here.  Layouts should instead use
471      * the window size.
472      * </p><p>
473      * The size is adjusted based on the current rotation of the display.
474      * </p><p>
475      * The size returned by this method does not necessarily represent the
476      * actual raw size (native resolution) of the display.  The returned size may
477      * be adjusted to exclude certain system decoration elements that are always visible.
478      * It may also be scaled to provide compatibility with older applications that
479      * were originally designed for smaller displays.
480      * </p>
481      *
482      * @param outSize A {@link Point} object to receive the size information.
483      */
getSize(Point outSize)484     public void getSize(Point outSize) {
485         synchronized (this) {
486             updateDisplayInfoLocked();
487             mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments);
488             outSize.x = mTempMetrics.widthPixels;
489             outSize.y = mTempMetrics.heightPixels;
490         }
491     }
492 
493     /**
494      * Gets the size of the display as a rectangle, in pixels.
495      *
496      * @param outSize A {@link Rect} object to receive the size information.
497      * @see #getSize(Point)
498      */
getRectSize(Rect outSize)499     public void getRectSize(Rect outSize) {
500         synchronized (this) {
501             updateDisplayInfoLocked();
502             mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments);
503             outSize.set(0, 0, mTempMetrics.widthPixels, mTempMetrics.heightPixels);
504         }
505     }
506 
507     /**
508      * Return the range of display sizes an application can expect to encounter
509      * under normal operation, as long as there is no physical change in screen
510      * size.  This is basically the sizes you will see as the orientation
511      * changes, taking into account whatever screen decoration there is in
512      * each rotation.  For example, the status bar is always at the top of the
513      * screen, so it will reduce the height both in landscape and portrait, and
514      * the smallest height returned here will be the smaller of the two.
515      *
516      * This is intended for applications to get an idea of the range of sizes
517      * they will encounter while going through device rotations, to provide a
518      * stable UI through rotation.  The sizes here take into account all standard
519      * system decorations that reduce the size actually available to the
520      * application: the status bar, navigation bar, system bar, etc.  It does
521      * <em>not</em> take into account more transient elements like an IME
522      * soft keyboard.
523      *
524      * @param outSmallestSize Filled in with the smallest width and height
525      * that the application will encounter, in pixels (not dp units).  The x
526      * (width) dimension here directly corresponds to
527      * {@link android.content.res.Configuration#smallestScreenWidthDp
528      * Configuration.smallestScreenWidthDp}, except the value here is in raw
529      * screen pixels rather than dp units.  Your application may of course
530      * still get smaller space yet if, for example, a soft keyboard is
531      * being displayed.
532      * @param outLargestSize Filled in with the largest width and height
533      * that the application will encounter, in pixels (not dp units).  Your
534      * application may of course still get larger space than this if,
535      * for example, screen decorations like the status bar are being hidden.
536      */
getCurrentSizeRange(Point outSmallestSize, Point outLargestSize)537     public void getCurrentSizeRange(Point outSmallestSize, Point outLargestSize) {
538         synchronized (this) {
539             updateDisplayInfoLocked();
540             outSmallestSize.x = mDisplayInfo.smallestNominalAppWidth;
541             outSmallestSize.y = mDisplayInfo.smallestNominalAppHeight;
542             outLargestSize.x = mDisplayInfo.largestNominalAppWidth;
543             outLargestSize.y = mDisplayInfo.largestNominalAppHeight;
544         }
545     }
546 
547     /**
548      * Return the maximum screen size dimension that will happen.  This is
549      * mostly for wallpapers.
550      * @hide
551      */
getMaximumSizeDimension()552     public int getMaximumSizeDimension() {
553         synchronized (this) {
554             updateDisplayInfoLocked();
555             return Math.max(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
556         }
557     }
558 
559     /**
560      * @deprecated Use {@link #getSize(Point)} instead.
561      */
562     @Deprecated
getWidth()563     public int getWidth() {
564         synchronized (this) {
565             updateCachedAppSizeIfNeededLocked();
566             return mCachedAppWidthCompat;
567         }
568     }
569 
570     /**
571      * @deprecated Use {@link #getSize(Point)} instead.
572      */
573     @Deprecated
getHeight()574     public int getHeight() {
575         synchronized (this) {
576             updateCachedAppSizeIfNeededLocked();
577             return mCachedAppHeightCompat;
578         }
579     }
580 
581     /**
582      * @hide
583      * Return a rectangle defining the insets of the overscan region of the display.
584      * Each field of the rectangle is the number of pixels the overscan area extends
585      * into the display on that side.
586      */
getOverscanInsets(Rect outRect)587     public void getOverscanInsets(Rect outRect) {
588         synchronized (this) {
589             updateDisplayInfoLocked();
590             outRect.set(mDisplayInfo.overscanLeft, mDisplayInfo.overscanTop,
591                     mDisplayInfo.overscanRight, mDisplayInfo.overscanBottom);
592         }
593     }
594 
595     /**
596      * Returns the rotation of the screen from its "natural" orientation.
597      * The returned value may be {@link Surface#ROTATION_0 Surface.ROTATION_0}
598      * (no rotation), {@link Surface#ROTATION_90 Surface.ROTATION_90},
599      * {@link Surface#ROTATION_180 Surface.ROTATION_180}, or
600      * {@link Surface#ROTATION_270 Surface.ROTATION_270}.  For
601      * example, if a device has a naturally tall screen, and the user has
602      * turned it on its side to go into a landscape orientation, the value
603      * returned here may be either {@link Surface#ROTATION_90 Surface.ROTATION_90}
604      * or {@link Surface#ROTATION_270 Surface.ROTATION_270} depending on
605      * the direction it was turned.  The angle is the rotation of the drawn
606      * graphics on the screen, which is the opposite direction of the physical
607      * rotation of the device.  For example, if the device is rotated 90
608      * degrees counter-clockwise, to compensate rendering will be rotated by
609      * 90 degrees clockwise and thus the returned value here will be
610      * {@link Surface#ROTATION_90 Surface.ROTATION_90}.
611      */
612     @Surface.Rotation
getRotation()613     public int getRotation() {
614         synchronized (this) {
615             updateDisplayInfoLocked();
616             return mDisplayInfo.rotation;
617         }
618     }
619 
620     /**
621      * @deprecated use {@link #getRotation}
622      * @return orientation of this display.
623      */
624     @Deprecated
625     @Surface.Rotation
getOrientation()626     public int getOrientation() {
627         return getRotation();
628     }
629 
630     /**
631      * Gets the pixel format of the display.
632      * @return One of the constants defined in {@link android.graphics.PixelFormat}.
633      *
634      * @deprecated This method is no longer supported.
635      * The result is always {@link PixelFormat#RGBA_8888}.
636      */
637     @Deprecated
getPixelFormat()638     public int getPixelFormat() {
639         return PixelFormat.RGBA_8888;
640     }
641 
642     /**
643      * Gets the refresh rate of this display in frames per second.
644      */
getRefreshRate()645     public float getRefreshRate() {
646         synchronized (this) {
647             updateDisplayInfoLocked();
648             return mDisplayInfo.getMode().getRefreshRate();
649         }
650     }
651 
652     /**
653      * Get the supported refresh rates of this display in frames per second.
654      * <p>
655      * This method only returns refresh rates for the display's default modes. For more options, use
656      * {@link #getSupportedModes()}.
657      *
658      * @deprecated use {@link #getSupportedModes()} instead
659      */
660     @Deprecated
getSupportedRefreshRates()661     public float[] getSupportedRefreshRates() {
662         synchronized (this) {
663             updateDisplayInfoLocked();
664             return mDisplayInfo.getDefaultRefreshRates();
665         }
666     }
667 
668     /**
669      * Returns the active mode of the display.
670      */
getMode()671     public Mode getMode() {
672         synchronized (this) {
673             updateDisplayInfoLocked();
674             return mDisplayInfo.getMode();
675         }
676     }
677 
678     /**
679      * Gets the supported modes of this display.
680      */
getSupportedModes()681     public Mode[] getSupportedModes() {
682         synchronized (this) {
683             updateDisplayInfoLocked();
684             final Display.Mode[] modes = mDisplayInfo.supportedModes;
685             return Arrays.copyOf(modes, modes.length);
686         }
687     }
688 
689     /**
690      * Request the display applies a color transform.
691      * @hide
692      */
693     @RequiresPermission(CONFIGURE_DISPLAY_COLOR_TRANSFORM)
requestColorTransform(ColorTransform colorTransform)694     public void requestColorTransform(ColorTransform colorTransform) {
695         mGlobal.requestColorTransform(mDisplayId, colorTransform.getId());
696     }
697 
698     /**
699      * Returns the active color transform of this display
700      * @hide
701      */
getColorTransform()702     public ColorTransform getColorTransform() {
703         synchronized (this) {
704             updateDisplayInfoLocked();
705             return mDisplayInfo.getColorTransform();
706         }
707     }
708 
709     /**
710      * Returns the default color transform of this display
711      * @hide
712      */
getDefaultColorTransform()713     public ColorTransform getDefaultColorTransform() {
714         synchronized (this) {
715             updateDisplayInfoLocked();
716             return mDisplayInfo.getDefaultColorTransform();
717         }
718     }
719 
720     /**
721      * Returns the display's HDR capabilities.
722      */
getHdrCapabilities()723     public HdrCapabilities getHdrCapabilities() {
724         synchronized (this) {
725             updateDisplayInfoLocked();
726             return mDisplayInfo.hdrCapabilities;
727         }
728     }
729 
730     /**
731      * Gets the supported color transforms of this device.
732      * @hide
733      */
getSupportedColorTransforms()734     public ColorTransform[] getSupportedColorTransforms() {
735         synchronized (this) {
736             updateDisplayInfoLocked();
737             ColorTransform[] transforms = mDisplayInfo.supportedColorTransforms;
738             return Arrays.copyOf(transforms, transforms.length);
739         }
740     }
741 
742     /**
743      * Gets the app VSYNC offset, in nanoseconds.  This is a positive value indicating
744      * the phase offset of the VSYNC events provided by Choreographer relative to the
745      * display refresh.  For example, if Choreographer reports that the refresh occurred
746      * at time N, it actually occurred at (N - appVsyncOffset).
747      * <p>
748      * Apps generally do not need to be aware of this.  It's only useful for fine-grained
749      * A/V synchronization.
750      */
getAppVsyncOffsetNanos()751     public long getAppVsyncOffsetNanos() {
752         synchronized (this) {
753             updateDisplayInfoLocked();
754             return mDisplayInfo.appVsyncOffsetNanos;
755         }
756     }
757 
758     /**
759      * This is how far in advance a buffer must be queued for presentation at
760      * a given time.  If you want a buffer to appear on the screen at
761      * time N, you must submit the buffer before (N - presentationDeadline).
762      * <p>
763      * The desired presentation time for GLES rendering may be set with
764      * {@link android.opengl.EGLExt#eglPresentationTimeANDROID}.  For video decoding, use
765      * {@link android.media.MediaCodec#releaseOutputBuffer(int, long)}.  Times are
766      * expressed in nanoseconds, using the system monotonic clock
767      * ({@link System#nanoTime}).
768      */
getPresentationDeadlineNanos()769     public long getPresentationDeadlineNanos() {
770         synchronized (this) {
771             updateDisplayInfoLocked();
772             return mDisplayInfo.presentationDeadlineNanos;
773         }
774     }
775 
776     /**
777      * Gets display metrics that describe the size and density of this display.
778      * The size returned by this method does not necessarily represent the
779      * actual raw size (native resolution) of the display.
780      * <p>
781      * 1. The returned size may be adjusted to exclude certain system decor elements
782      * that are always visible.
783      * </p><p>
784      * 2. It may be scaled to provide compatibility with older applications that
785      * were originally designed for smaller displays.
786      * </p><p>
787      * 3. It can be different depending on the WindowManager to which the display belongs.
788      * <pre>
789      * - If requested from non-Activity context (e.g. Application context via
790      * {@code (WindowManager) getApplicationContext().getSystemService(Context.WINDOW_SERVICE)})
791      * metrics will report real size of the display based on current rotation.
792      * - If requested from activity resulting metrics will correspond to current window metrics.
793      * In this case the size can be smaller than physical size in multi-window mode.
794      * </pre>
795      * </p>
796      *
797      * @param outMetrics A {@link DisplayMetrics} object to receive the metrics.
798      */
getMetrics(DisplayMetrics outMetrics)799     public void getMetrics(DisplayMetrics outMetrics) {
800         synchronized (this) {
801             updateDisplayInfoLocked();
802             mDisplayInfo.getAppMetrics(outMetrics, mDisplayAdjustments);
803         }
804     }
805 
806     /**
807      * Gets the real size of the display without subtracting any window decor or
808      * applying any compatibility scale factors.
809      * <p>
810      * The size is adjusted based on the current rotation of the display.
811      * </p><p>
812      * The real size may be smaller than the physical size of the screen when the
813      * window manager is emulating a smaller display (using adb shell am display-size).
814      * </p>
815      *
816      * @param outSize Set to the real size of the display.
817      */
getRealSize(Point outSize)818     public void getRealSize(Point outSize) {
819         synchronized (this) {
820             updateDisplayInfoLocked();
821             outSize.x = mDisplayInfo.logicalWidth;
822             outSize.y = mDisplayInfo.logicalHeight;
823         }
824     }
825 
826     /**
827      * Gets display metrics based on the real size of this display.
828      * <p>
829      * The size is adjusted based on the current rotation of the display.
830      * </p><p>
831      * The real size may be smaller than the physical size of the screen when the
832      * window manager is emulating a smaller display (using adb shell wm size).
833      * </p>
834      *
835      * @param outMetrics A {@link DisplayMetrics} object to receive the metrics.
836      */
getRealMetrics(DisplayMetrics outMetrics)837     public void getRealMetrics(DisplayMetrics outMetrics) {
838         synchronized (this) {
839             updateDisplayInfoLocked();
840             mDisplayInfo.getLogicalMetrics(outMetrics,
841                     CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
842         }
843     }
844 
845     /**
846      * Gets the state of the display, such as whether it is on or off.
847      *
848      * @return The state of the display: one of {@link #STATE_OFF}, {@link #STATE_ON},
849      * {@link #STATE_DOZE}, {@link #STATE_DOZE_SUSPEND}, or {@link #STATE_UNKNOWN}.
850      */
getState()851     public int getState() {
852         synchronized (this) {
853             updateDisplayInfoLocked();
854             return mIsValid ? mDisplayInfo.state : STATE_UNKNOWN;
855         }
856     }
857 
858     /**
859      * Returns true if the specified UID has access to this display.
860      * @hide
861      */
hasAccess(int uid)862     public boolean hasAccess(int uid) {
863         return Display.hasAccess(uid, mFlags, mOwnerUid);
864     }
865 
866     /** @hide */
hasAccess(int uid, int flags, int ownerUid)867     public static boolean hasAccess(int uid, int flags, int ownerUid) {
868         return (flags & Display.FLAG_PRIVATE) == 0
869                 || uid == ownerUid
870                 || uid == Process.SYSTEM_UID
871                 || uid == 0;
872     }
873 
874     /**
875      * Returns true if the display is a public presentation display.
876      * @hide
877      */
isPublicPresentation()878     public boolean isPublicPresentation() {
879         return (mFlags & (Display.FLAG_PRIVATE | Display.FLAG_PRESENTATION)) ==
880                 Display.FLAG_PRESENTATION;
881     }
882 
updateDisplayInfoLocked()883     private void updateDisplayInfoLocked() {
884         // Note: The display manager caches display info objects on our behalf.
885         DisplayInfo newInfo = mGlobal.getDisplayInfo(mDisplayId);
886         if (newInfo == null) {
887             // Preserve the old mDisplayInfo after the display is removed.
888             if (mIsValid) {
889                 mIsValid = false;
890                 if (DEBUG) {
891                     Log.d(TAG, "Logical display " + mDisplayId + " was removed.");
892                 }
893             }
894         } else {
895             // Use the new display info.  (It might be the same object if nothing changed.)
896             mDisplayInfo = newInfo;
897             if (!mIsValid) {
898                 mIsValid = true;
899                 if (DEBUG) {
900                     Log.d(TAG, "Logical display " + mDisplayId + " was recreated.");
901                 }
902             }
903         }
904     }
905 
updateCachedAppSizeIfNeededLocked()906     private void updateCachedAppSizeIfNeededLocked() {
907         long now = SystemClock.uptimeMillis();
908         if (now > mLastCachedAppSizeUpdate + CACHED_APP_SIZE_DURATION_MILLIS) {
909             updateDisplayInfoLocked();
910             mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments);
911             mCachedAppWidthCompat = mTempMetrics.widthPixels;
912             mCachedAppHeightCompat = mTempMetrics.heightPixels;
913             mLastCachedAppSizeUpdate = now;
914         }
915     }
916 
917     // For debugging purposes
918     @Override
toString()919     public String toString() {
920         synchronized (this) {
921             updateDisplayInfoLocked();
922             mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments);
923             return "Display id " + mDisplayId + ": " + mDisplayInfo
924                     + ", " + mTempMetrics + ", isValid=" + mIsValid;
925         }
926     }
927 
928     /**
929      * @hide
930      */
typeToString(int type)931     public static String typeToString(int type) {
932         switch (type) {
933             case TYPE_UNKNOWN:
934                 return "UNKNOWN";
935             case TYPE_BUILT_IN:
936                 return "BUILT_IN";
937             case TYPE_HDMI:
938                 return "HDMI";
939             case TYPE_WIFI:
940                 return "WIFI";
941             case TYPE_OVERLAY:
942                 return "OVERLAY";
943             case TYPE_VIRTUAL:
944                 return "VIRTUAL";
945             default:
946                 return Integer.toString(type);
947         }
948     }
949 
950     /**
951      * @hide
952      */
stateToString(int state)953     public static String stateToString(int state) {
954         switch (state) {
955             case STATE_UNKNOWN:
956                 return "UNKNOWN";
957             case STATE_OFF:
958                 return "OFF";
959             case STATE_ON:
960                 return "ON";
961             case STATE_DOZE:
962                 return "DOZE";
963             case STATE_DOZE_SUSPEND:
964                 return "DOZE_SUSPEND";
965             default:
966                 return Integer.toString(state);
967         }
968     }
969 
970     /**
971      * Returns true if display updates may be suspended while in the specified
972      * display power state.
973      * @hide
974      */
isSuspendedState(int state)975     public static boolean isSuspendedState(int state) {
976         return state == STATE_OFF || state == STATE_DOZE_SUSPEND;
977     }
978 
979     /**
980      * A mode supported by a given display.
981      *
982      * @see Display#getSupportedModes()
983      */
984     public static final class Mode implements Parcelable {
985         /**
986          * @hide
987          */
988         public static final Mode[] EMPTY_ARRAY = new Mode[0];
989 
990         private final int mModeId;
991         private final int mWidth;
992         private final int mHeight;
993         private final float mRefreshRate;
994 
995         /**
996          * @hide
997          */
Mode(int modeId, int width, int height, float refreshRate)998         public Mode(int modeId, int width, int height, float refreshRate) {
999             mModeId = modeId;
1000             mWidth = width;
1001             mHeight = height;
1002             mRefreshRate = refreshRate;
1003         }
1004 
1005         /**
1006          * Returns this mode's id.
1007          */
getModeId()1008         public int getModeId() {
1009             return mModeId;
1010         }
1011 
1012         /**
1013          * Returns the physical width of the display in pixels when configured in this mode's
1014          * resolution.
1015          * <p>
1016          * Note that due to application UI scaling, the number of pixels made available to
1017          * applications when the mode is active (as reported by {@link Display#getWidth()} may
1018          * differ from the mode's actual resolution (as reported by this function).
1019          * <p>
1020          * For example, applications running on a 4K display may have their UI laid out and rendered
1021          * in 1080p and then scaled up. Applications can take advantage of the extra resolution by
1022          * rendering content through a {@link android.view.SurfaceView} using full size buffers.
1023          */
getPhysicalWidth()1024         public int getPhysicalWidth() {
1025             return mWidth;
1026         }
1027 
1028         /**
1029          * Returns the physical height of the display in pixels when configured in this mode's
1030          * resolution.
1031          * <p>
1032          * Note that due to application UI scaling, the number of pixels made available to
1033          * applications when the mode is active (as reported by {@link Display#getHeight()} may
1034          * differ from the mode's actual resolution (as reported by this function).
1035          * <p>
1036          * For example, applications running on a 4K display may have their UI laid out and rendered
1037          * in 1080p and then scaled up. Applications can take advantage of the extra resolution by
1038          * rendering content through a {@link android.view.SurfaceView} using full size buffers.
1039          */
getPhysicalHeight()1040         public int getPhysicalHeight() {
1041             return mHeight;
1042         }
1043 
1044         /**
1045          * Returns the refresh rate in frames per second.
1046          */
getRefreshRate()1047         public float getRefreshRate() {
1048             return mRefreshRate;
1049         }
1050 
1051         /**
1052          * Returns {@code true} if this mode matches the given parameters.
1053          *
1054          * @hide
1055          */
matches(int width, int height, float refreshRate)1056         public boolean matches(int width, int height, float refreshRate) {
1057             return mWidth == width &&
1058                     mHeight == height &&
1059                     Float.floatToIntBits(mRefreshRate) == Float.floatToIntBits(refreshRate);
1060         }
1061 
1062         @Override
equals(Object other)1063         public boolean equals(Object other) {
1064             if (this == other) {
1065                 return true;
1066             }
1067             if (!(other instanceof Mode)) {
1068                 return false;
1069             }
1070             Mode that = (Mode) other;
1071             return mModeId == that.mModeId && matches(that.mWidth, that.mHeight, that.mRefreshRate);
1072         }
1073 
1074         @Override
hashCode()1075         public int hashCode() {
1076             int hash = 1;
1077             hash = hash * 17 + mModeId;
1078             hash = hash * 17 + mWidth;
1079             hash = hash * 17 + mHeight;
1080             hash = hash * 17 + Float.floatToIntBits(mRefreshRate);
1081             return hash;
1082         }
1083 
1084         @Override
toString()1085         public String toString() {
1086             return new StringBuilder("{")
1087                     .append("id=").append(mModeId)
1088                     .append(", width=").append(mWidth)
1089                     .append(", height=").append(mHeight)
1090                     .append(", fps=").append(mRefreshRate)
1091                     .append("}")
1092                     .toString();
1093         }
1094 
1095         @Override
describeContents()1096         public int describeContents() {
1097             return 0;
1098         }
1099 
Mode(Parcel in)1100         private Mode(Parcel in) {
1101             this(in.readInt(), in.readInt(), in.readInt(), in.readFloat());
1102         }
1103 
1104         @Override
writeToParcel(Parcel out, int parcelableFlags)1105         public void writeToParcel(Parcel out, int parcelableFlags) {
1106             out.writeInt(mModeId);
1107             out.writeInt(mWidth);
1108             out.writeInt(mHeight);
1109             out.writeFloat(mRefreshRate);
1110         }
1111 
1112         @SuppressWarnings("hiding")
1113         public static final Parcelable.Creator<Mode> CREATOR
1114                 = new Parcelable.Creator<Mode>() {
1115             @Override
1116             public Mode createFromParcel(Parcel in) {
1117                 return new Mode(in);
1118             }
1119 
1120             @Override
1121             public Mode[] newArray(int size) {
1122                 return new Mode[size];
1123             }
1124         };
1125     }
1126 
1127     /**
1128      * Encapsulates the HDR capabilities of a given display.
1129      * For example, what HDR types it supports and details about the desired luminance data.
1130      * <p>You can get an instance for a given {@link Display} object with
1131      * {@link Display#getHdrCapabilities getHdrCapabilities()}.
1132      */
1133     public static final class HdrCapabilities implements Parcelable {
1134         /**
1135          * Invalid luminance value.
1136          */
1137         public static final float INVALID_LUMINANCE = -1;
1138         /**
1139          * Dolby Vision high dynamic range (HDR) display.
1140          */
1141         public static final int HDR_TYPE_DOLBY_VISION = 1;
1142         /**
1143          * HDR10 display.
1144          */
1145         public static final int HDR_TYPE_HDR10 = 2;
1146         /**
1147          * Hybrid Log-Gamma HDR display.
1148          */
1149         public static final int HDR_TYPE_HLG = 3;
1150 
1151         /** @hide */
1152         @IntDef({
1153             HDR_TYPE_DOLBY_VISION,
1154             HDR_TYPE_HDR10,
1155             HDR_TYPE_HLG,
1156         })
1157         @Retention(RetentionPolicy.SOURCE)
1158         public @interface HdrType {}
1159 
1160         private @HdrType int[] mSupportedHdrTypes = new int[0];
1161         private float mMaxLuminance = INVALID_LUMINANCE;
1162         private float mMaxAverageLuminance = INVALID_LUMINANCE;
1163         private float mMinLuminance = INVALID_LUMINANCE;
1164 
1165         /**
1166          * @hide
1167          */
HdrCapabilities()1168         public HdrCapabilities() {
1169         }
1170 
1171         /**
1172          * @hide
1173          */
HdrCapabilities(int[] supportedHdrTypes, float maxLuminance, float maxAverageLuminance, float minLuminance)1174         public HdrCapabilities(int[] supportedHdrTypes, float maxLuminance,
1175                 float maxAverageLuminance, float minLuminance) {
1176             mSupportedHdrTypes = supportedHdrTypes;
1177             mMaxLuminance = maxLuminance;
1178             mMaxAverageLuminance = maxAverageLuminance;
1179             mMinLuminance = minLuminance;
1180         }
1181 
1182         /**
1183          * Gets the supported HDR types of this display.
1184          * Returns empty array if HDR is not supported by the display.
1185          */
getSupportedHdrTypes()1186         public @HdrType int[] getSupportedHdrTypes() {
1187             return mSupportedHdrTypes;
1188         }
1189         /**
1190          * Returns the desired content max luminance data in cd/m2 for this display.
1191          */
getDesiredMaxLuminance()1192         public float getDesiredMaxLuminance() {
1193             return mMaxLuminance;
1194         }
1195         /**
1196          * Returns the desired content max frame-average luminance data in cd/m2 for this display.
1197          */
getDesiredMaxAverageLuminance()1198         public float getDesiredMaxAverageLuminance() {
1199             return mMaxAverageLuminance;
1200         }
1201         /**
1202          * Returns the desired content min luminance data in cd/m2 for this display.
1203          */
getDesiredMinLuminance()1204         public float getDesiredMinLuminance() {
1205             return mMinLuminance;
1206         }
1207 
1208         public static final Creator<HdrCapabilities> CREATOR = new Creator<HdrCapabilities>() {
1209             @Override
1210             public HdrCapabilities createFromParcel(Parcel source) {
1211                 return new HdrCapabilities(source);
1212             }
1213 
1214             @Override
1215             public HdrCapabilities[] newArray(int size) {
1216                 return new HdrCapabilities[size];
1217             }
1218         };
1219 
HdrCapabilities(Parcel source)1220         private HdrCapabilities(Parcel source) {
1221             readFromParcel(source);
1222         }
1223 
1224         /**
1225          * @hide
1226          */
readFromParcel(Parcel source)1227         public void readFromParcel(Parcel source) {
1228             int types = source.readInt();
1229             mSupportedHdrTypes = new int[types];
1230             for (int i = 0; i < types; ++i) {
1231                 mSupportedHdrTypes[i] = source.readInt();
1232             }
1233             mMaxLuminance = source.readFloat();
1234             mMaxAverageLuminance = source.readFloat();
1235             mMinLuminance = source.readFloat();
1236         }
1237 
1238         @Override
writeToParcel(Parcel dest, int flags)1239         public void writeToParcel(Parcel dest, int flags) {
1240             dest.writeInt(mSupportedHdrTypes.length);
1241             for (int i = 0; i < mSupportedHdrTypes.length; ++i) {
1242                 dest.writeInt(mSupportedHdrTypes[i]);
1243             }
1244             dest.writeFloat(mMaxLuminance);
1245             dest.writeFloat(mMaxAverageLuminance);
1246             dest.writeFloat(mMinLuminance);
1247         }
1248 
1249         @Override
describeContents()1250         public int describeContents() {
1251             return 0;
1252         }
1253     }
1254 
1255     /**
1256      * A color transform supported by a given display.
1257      *
1258      * @see Display#getSupportedColorTransforms()
1259      * @hide
1260      */
1261     public static final class ColorTransform implements Parcelable {
1262         public static final ColorTransform[] EMPTY_ARRAY = new ColorTransform[0];
1263 
1264         private final int mId;
1265         private final int mColorTransform;
1266 
ColorTransform(int id, int colorTransform)1267         public ColorTransform(int id, int colorTransform) {
1268             mId = id;
1269             mColorTransform = colorTransform;
1270         }
1271 
getId()1272         public int getId() {
1273             return mId;
1274         }
1275 
getColorTransform()1276         public int getColorTransform() {
1277             return mColorTransform;
1278         }
1279 
1280         @Override
equals(Object other)1281         public boolean equals(Object other) {
1282             if (this == other) {
1283                 return true;
1284             }
1285             if (!(other instanceof ColorTransform)) {
1286                 return false;
1287             }
1288             ColorTransform that = (ColorTransform) other;
1289             return mId == that.mId
1290                 && mColorTransform == that.mColorTransform;
1291         }
1292 
1293         @Override
hashCode()1294         public int hashCode() {
1295             int hash = 1;
1296             hash = hash * 17 + mId;
1297             hash = hash * 17 + mColorTransform;
1298             return hash;
1299         }
1300 
1301         @Override
toString()1302         public String toString() {
1303             return new StringBuilder("{")
1304                     .append("id=").append(mId)
1305                     .append(", colorTransform=").append(mColorTransform)
1306                     .append("}")
1307                     .toString();
1308         }
1309 
1310         @Override
describeContents()1311         public int describeContents() {
1312             return 0;
1313         }
1314 
ColorTransform(Parcel in)1315         private ColorTransform(Parcel in) {
1316             this(in.readInt(), in.readInt());
1317         }
1318 
1319         @Override
writeToParcel(Parcel out, int parcelableFlags)1320         public void writeToParcel(Parcel out, int parcelableFlags) {
1321             out.writeInt(mId);
1322             out.writeInt(mColorTransform);
1323         }
1324 
1325         @SuppressWarnings("hiding")
1326         public static final Parcelable.Creator<ColorTransform> CREATOR
1327                 = new Parcelable.Creator<ColorTransform>() {
1328             @Override
1329             public ColorTransform createFromParcel(Parcel in) {
1330                 return new ColorTransform(in);
1331             }
1332 
1333             @Override
1334             public ColorTransform[] newArray(int size) {
1335                 return new ColorTransform[size];
1336             }
1337         };
1338     }
1339 }
1340