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.content.res.CompatibilityInfo;
20 import android.graphics.PixelFormat;
21 import android.graphics.Point;
22 import android.graphics.Rect;
23 import android.hardware.display.DisplayManagerGlobal;
24 import android.os.Process;
25 import android.os.SystemClock;
26 import android.util.DisplayMetrics;
27 import android.util.Log;
28 
29 import java.util.Arrays;
30 
31 /**
32  * Provides information about the size and density of a logical display.
33  * <p>
34  * The display area is described in two different ways.
35  * <ul>
36  * <li>The application display area specifies the part of the display that may contain
37  * an application window, excluding the system decorations.  The application display area may
38  * be smaller than the real display area because the system subtracts the space needed
39  * for decor elements such as the status bar.  Use the following methods to query the
40  * application display area: {@link #getSize}, {@link #getRectSize} and {@link #getMetrics}.</li>
41  * <li>The real display area specifies the part of the display that contains content
42  * including the system decorations.  Even so, the real display area may be smaller than the
43  * physical size of the display if the window manager is emulating a smaller display
44  * using (adb shell am display-size).  Use the following methods to query the
45  * real display area: {@link #getRealSize}, {@link #getRealMetrics}.</li>
46  * </ul>
47  * </p><p>
48  * A logical display does not necessarily represent a particular physical display device
49  * such as the built-in screen or an external monitor.  The contents of a logical
50  * display may be presented on one or more physical displays according to the devices
51  * that are currently attached and whether mirroring has been enabled.
52  * </p>
53  */
54 public final class Display {
55     private static final String TAG = "Display";
56     private static final boolean DEBUG = false;
57 
58     private final DisplayManagerGlobal mGlobal;
59     private final int mDisplayId;
60     private final int mLayerStack;
61     private final int mFlags;
62     private final int mType;
63     private final String mAddress;
64     private final int mOwnerUid;
65     private final String mOwnerPackageName;
66     private final DisplayAdjustments mDisplayAdjustments;
67 
68     private DisplayInfo mDisplayInfo; // never null
69     private boolean mIsValid;
70 
71     // Temporary display metrics structure used for compatibility mode.
72     private final DisplayMetrics mTempMetrics = new DisplayMetrics();
73 
74     // We cache the app width and height properties briefly between calls
75     // to getHeight() and getWidth() to ensure that applications perceive
76     // consistent results when the size changes (most of the time).
77     // Applications should now be using getSize() instead.
78     private static final int CACHED_APP_SIZE_DURATION_MILLIS = 20;
79     private long mLastCachedAppSizeUpdate;
80     private int mCachedAppWidthCompat;
81     private int mCachedAppHeightCompat;
82 
83     /**
84      * The default Display id, which is the id of the built-in primary display
85      * assuming there is one.
86      */
87     public static final int DEFAULT_DISPLAY = 0;
88 
89     /**
90      * Display flag: Indicates that the display supports compositing content
91      * that is stored in protected graphics buffers.
92      * <p>
93      * If this flag is set then the display device supports compositing protected buffers.
94      * </p><p>
95      * If this flag is not set then the display device may not support compositing
96      * protected buffers; the user may see a blank region on the screen instead of
97      * the protected content.
98      * </p><p>
99      * Secure (DRM) video decoders may allocate protected graphics buffers to request that
100      * a hardware-protected path be provided between the video decoder and the external
101      * display sink.  If a hardware-protected path is not available, then content stored
102      * in protected graphics buffers may not be composited.
103      * </p><p>
104      * An application can use the absence of this flag as a hint that it should not use protected
105      * buffers for this display because the content may not be visible.  For example,
106      * if the flag is not set then the application may choose not to show content on this
107      * display, show an informative error message, select an alternate content stream
108      * or adopt a different strategy for decoding content that does not rely on
109      * protected buffers.
110      * </p>
111      *
112      * @see #getFlags
113      */
114     public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1 << 0;
115 
116     /**
117      * Display flag: Indicates that the display has a secure video output and
118      * supports compositing secure surfaces.
119      * <p>
120      * If this flag is set then the display device has a secure video output
121      * and is capable of showing secure surfaces.  It may also be capable of
122      * showing {@link #FLAG_SUPPORTS_PROTECTED_BUFFERS protected buffers}.
123      * </p><p>
124      * If this flag is not set then the display device may not have a secure video
125      * output; the user may see a blank region on the screen instead of
126      * the contents of secure surfaces or protected buffers.
127      * </p><p>
128      * Secure surfaces are used to prevent content rendered into those surfaces
129      * by applications from appearing in screenshots or from being viewed
130      * on non-secure displays.  Protected buffers are used by secure video decoders
131      * for a similar purpose.
132      * </p><p>
133      * An application creates a window with a secure surface by specifying the
134      * {@link WindowManager.LayoutParams#FLAG_SECURE} window flag.
135      * Likewise, an application creates a {@link SurfaceView} with a secure surface
136      * by calling {@link SurfaceView#setSecure} before attaching the secure view to
137      * its containing window.
138      * </p><p>
139      * An application can use the absence of this flag as a hint that it should not create
140      * secure surfaces or protected buffers on this display because the content may
141      * not be visible.  For example, if the flag is not set then the application may
142      * choose not to show content on this display, show an informative error message,
143      * select an alternate content stream or adopt a different strategy for decoding
144      * content that does not rely on secure surfaces or protected buffers.
145      * </p>
146      *
147      * @see #getFlags
148      */
149     public static final int FLAG_SECURE = 1 << 1;
150 
151     /**
152      * Display flag: Indicates that the display is private.  Only the application that
153      * owns the display can create windows on it.
154      *
155      * @see #getFlags
156      */
157     public static final int FLAG_PRIVATE = 1 << 2;
158 
159     /**
160      * Display flag: Indicates that the display is a presentation display.
161      * <p>
162      * This flag identifies secondary displays that are suitable for
163      * use as presentation displays such as HDMI or Wireless displays.  Applications
164      * may automatically project their content to presentation displays to provide
165      * richer second screen experiences.
166      * </p>
167      *
168      * @see #getFlags
169      */
170     public static final int FLAG_PRESENTATION = 1 << 3;
171 
172     /**
173      * Display type: Unknown display type.
174      * @hide
175      */
176     public static final int TYPE_UNKNOWN = 0;
177 
178     /**
179      * Display type: Built-in display.
180      * @hide
181      */
182     public static final int TYPE_BUILT_IN = 1;
183 
184     /**
185      * Display type: HDMI display.
186      * @hide
187      */
188     public static final int TYPE_HDMI = 2;
189 
190     /**
191      * Display type: WiFi display.
192      * @hide
193      */
194     public static final int TYPE_WIFI = 3;
195 
196     /**
197      * Display type: Overlay display.
198      * @hide
199      */
200     public static final int TYPE_OVERLAY = 4;
201 
202     /**
203      * Display type: Virtual display.
204      * @hide
205      */
206     public static final int TYPE_VIRTUAL = 5;
207 
208     /**
209      * Display state: The display state is unknown.
210      *
211      * @see #getState
212      */
213     public static final int STATE_UNKNOWN = 0;
214 
215     /**
216      * Display state: The display is off.
217      *
218      * @see #getState
219      */
220     public static final int STATE_OFF = 1;
221 
222     /**
223      * Display state: The display is on.
224      *
225      * @see #getState
226      */
227     public static final int STATE_ON = 2;
228 
229     /**
230      * Display state: The display is dozing in a low power state; it is still
231      * on but is optimized for showing system-provided content while the
232      * device is non-interactive.
233      *
234      * @see #getState
235      * @see android.os.PowerManager#isInteractive
236      */
237     public static final int STATE_DOZE = 3;
238 
239     /**
240      * Display state: The display is dozing in a suspended low power state; it is still
241      * on but is optimized for showing static system-provided content while the device
242      * is non-interactive.  This mode may be used to conserve even more power by allowing
243      * the hardware to stop applying frame buffer updates from the graphics subsystem or
244      * to take over the display and manage it autonomously to implement low power always-on
245      * display functionality.
246      *
247      * @see #getState
248      * @see android.os.PowerManager#isInteractive
249      */
250     public static final int STATE_DOZE_SUSPEND = 4;
251 
252     /**
253      * Internal method to create a display.
254      * Applications should use {@link android.view.WindowManager#getDefaultDisplay()}
255      * or {@link android.hardware.display.DisplayManager#getDisplay}
256      * to get a display object.
257      *
258      * @hide
259      */
Display(DisplayManagerGlobal global, int displayId, DisplayInfo displayInfo , DisplayAdjustments daj)260     public Display(DisplayManagerGlobal global,
261             int displayId, DisplayInfo displayInfo /*not null*/,
262             DisplayAdjustments daj) {
263         mGlobal = global;
264         mDisplayId = displayId;
265         mDisplayInfo = displayInfo;
266         mDisplayAdjustments = new DisplayAdjustments(daj);
267         mIsValid = true;
268 
269         // Cache properties that cannot change as long as the display is valid.
270         mLayerStack = displayInfo.layerStack;
271         mFlags = displayInfo.flags;
272         mType = displayInfo.type;
273         mAddress = displayInfo.address;
274         mOwnerUid = displayInfo.ownerUid;
275         mOwnerPackageName = displayInfo.ownerPackageName;
276     }
277 
278     /**
279      * Gets the display id.
280      * <p>
281      * Each logical display has a unique id.
282      * The default display has id {@link #DEFAULT_DISPLAY}.
283      * </p>
284      */
getDisplayId()285     public int getDisplayId() {
286         return mDisplayId;
287     }
288 
289     /**
290      * Returns true if this display is still valid, false if the display has been removed.
291      *
292      * If the display is invalid, then the methods of this class will
293      * continue to report the most recently observed display information.
294      * However, it is unwise (and rather fruitless) to continue using a
295      * {@link Display} object after the display's demise.
296      *
297      * It's possible for a display that was previously invalid to become
298      * valid again if a display with the same id is reconnected.
299      *
300      * @return True if the display is still valid.
301      */
isValid()302     public boolean isValid() {
303         synchronized (this) {
304             updateDisplayInfoLocked();
305             return mIsValid;
306         }
307     }
308 
309     /**
310      * Gets a full copy of the display information.
311      *
312      * @param outDisplayInfo The object to receive the copy of the display information.
313      * @return True if the display is still valid.
314      * @hide
315      */
getDisplayInfo(DisplayInfo outDisplayInfo)316     public boolean getDisplayInfo(DisplayInfo outDisplayInfo) {
317         synchronized (this) {
318             updateDisplayInfoLocked();
319             outDisplayInfo.copyFrom(mDisplayInfo);
320             return mIsValid;
321         }
322     }
323 
324     /**
325      * Gets the display's layer stack.
326      *
327      * Each display has its own independent layer stack upon which surfaces
328      * are placed to be managed by surface flinger.
329      *
330      * @return The display's layer stack number.
331      * @hide
332      */
getLayerStack()333     public int getLayerStack() {
334         return mLayerStack;
335     }
336 
337     /**
338      * Returns a combination of flags that describe the capabilities of the display.
339      *
340      * @return The display flags.
341      *
342      * @see #FLAG_SUPPORTS_PROTECTED_BUFFERS
343      * @see #FLAG_SECURE
344      * @see #FLAG_PRIVATE
345      */
getFlags()346     public int getFlags() {
347         return mFlags;
348     }
349 
350     /**
351      * Gets the display type.
352      *
353      * @return The display type.
354      *
355      * @see #TYPE_UNKNOWN
356      * @see #TYPE_BUILT_IN
357      * @see #TYPE_HDMI
358      * @see #TYPE_WIFI
359      * @see #TYPE_OVERLAY
360      * @see #TYPE_VIRTUAL
361      * @hide
362      */
getType()363     public int getType() {
364         return mType;
365     }
366 
367     /**
368      * Gets the display address, or null if none.
369      * Interpretation varies by display type.
370      *
371      * @return The display address.
372      * @hide
373      */
getAddress()374     public String getAddress() {
375         return mAddress;
376     }
377 
378     /**
379      * Gets the UID of the application that owns this display, or zero if it is
380      * owned by the system.
381      * <p>
382      * If the display is private, then only the owner can use it.
383      * </p>
384      *
385      * @hide
386      */
getOwnerUid()387     public int getOwnerUid() {
388         return mOwnerUid;
389     }
390 
391     /**
392      * Gets the package name of the application that owns this display, or null if it is
393      * owned by the system.
394      * <p>
395      * If the display is private, then only the owner can use it.
396      * </p>
397      *
398      * @hide
399      */
getOwnerPackageName()400     public String getOwnerPackageName() {
401         return mOwnerPackageName;
402     }
403 
404     /**
405      * Gets the compatibility info used by this display instance.
406      *
407      * @return The display adjustments holder, or null if none is required.
408      * @hide
409      */
getDisplayAdjustments()410     public DisplayAdjustments getDisplayAdjustments() {
411         return mDisplayAdjustments;
412     }
413 
414     /**
415      * Gets the name of the display.
416      * <p>
417      * Note that some displays may be renamed by the user.
418      * </p>
419      *
420      * @return The display's name.
421      */
getName()422     public String getName() {
423         synchronized (this) {
424             updateDisplayInfoLocked();
425             return mDisplayInfo.name;
426         }
427     }
428 
429     /**
430      * Gets the size of the display, in pixels.
431      * <p>
432      * Note that this value should <em>not</em> be used for computing layouts,
433      * since a device will typically have screen decoration (such as a status bar)
434      * along the edges of the display that reduce the amount of application
435      * space available from the size returned here.  Layouts should instead use
436      * the window size.
437      * </p><p>
438      * The size is adjusted based on the current rotation of the display.
439      * </p><p>
440      * The size returned by this method does not necessarily represent the
441      * actual raw size (native resolution) of the display.  The returned size may
442      * be adjusted to exclude certain system decoration elements that are always visible.
443      * It may also be scaled to provide compatibility with older applications that
444      * were originally designed for smaller displays.
445      * </p>
446      *
447      * @param outSize A {@link Point} object to receive the size information.
448      */
getSize(Point outSize)449     public void getSize(Point outSize) {
450         synchronized (this) {
451             updateDisplayInfoLocked();
452             mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments);
453             outSize.x = mTempMetrics.widthPixels;
454             outSize.y = mTempMetrics.heightPixels;
455         }
456     }
457 
458     /**
459      * Gets the size of the display as a rectangle, in pixels.
460      *
461      * @param outSize A {@link Rect} object to receive the size information.
462      * @see #getSize(Point)
463      */
getRectSize(Rect outSize)464     public void getRectSize(Rect outSize) {
465         synchronized (this) {
466             updateDisplayInfoLocked();
467             mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments);
468             outSize.set(0, 0, mTempMetrics.widthPixels, mTempMetrics.heightPixels);
469         }
470     }
471 
472     /**
473      * Return the range of display sizes an application can expect to encounter
474      * under normal operation, as long as there is no physical change in screen
475      * size.  This is basically the sizes you will see as the orientation
476      * changes, taking into account whatever screen decoration there is in
477      * each rotation.  For example, the status bar is always at the top of the
478      * screen, so it will reduce the height both in landscape and portrait, and
479      * the smallest height returned here will be the smaller of the two.
480      *
481      * This is intended for applications to get an idea of the range of sizes
482      * they will encounter while going through device rotations, to provide a
483      * stable UI through rotation.  The sizes here take into account all standard
484      * system decorations that reduce the size actually available to the
485      * application: the status bar, navigation bar, system bar, etc.  It does
486      * <em>not</em> take into account more transient elements like an IME
487      * soft keyboard.
488      *
489      * @param outSmallestSize Filled in with the smallest width and height
490      * that the application will encounter, in pixels (not dp units).  The x
491      * (width) dimension here directly corresponds to
492      * {@link android.content.res.Configuration#smallestScreenWidthDp
493      * Configuration.smallestScreenWidthDp}, except the value here is in raw
494      * screen pixels rather than dp units.  Your application may of course
495      * still get smaller space yet if, for example, a soft keyboard is
496      * being displayed.
497      * @param outLargestSize Filled in with the largest width and height
498      * that the application will encounter, in pixels (not dp units).  Your
499      * application may of course still get larger space than this if,
500      * for example, screen decorations like the status bar are being hidden.
501      */
getCurrentSizeRange(Point outSmallestSize, Point outLargestSize)502     public void getCurrentSizeRange(Point outSmallestSize, Point outLargestSize) {
503         synchronized (this) {
504             updateDisplayInfoLocked();
505             outSmallestSize.x = mDisplayInfo.smallestNominalAppWidth;
506             outSmallestSize.y = mDisplayInfo.smallestNominalAppHeight;
507             outLargestSize.x = mDisplayInfo.largestNominalAppWidth;
508             outLargestSize.y = mDisplayInfo.largestNominalAppHeight;
509         }
510     }
511 
512     /**
513      * Return the maximum screen size dimension that will happen.  This is
514      * mostly for wallpapers.
515      * @hide
516      */
getMaximumSizeDimension()517     public int getMaximumSizeDimension() {
518         synchronized (this) {
519             updateDisplayInfoLocked();
520             return Math.max(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
521         }
522     }
523 
524     /**
525      * @deprecated Use {@link #getSize(Point)} instead.
526      */
527     @Deprecated
getWidth()528     public int getWidth() {
529         synchronized (this) {
530             updateCachedAppSizeIfNeededLocked();
531             return mCachedAppWidthCompat;
532         }
533     }
534 
535     /**
536      * @deprecated Use {@link #getSize(Point)} instead.
537      */
538     @Deprecated
getHeight()539     public int getHeight() {
540         synchronized (this) {
541             updateCachedAppSizeIfNeededLocked();
542             return mCachedAppHeightCompat;
543         }
544     }
545 
546     /**
547      * @hide
548      * Return a rectangle defining the insets of the overscan region of the display.
549      * Each field of the rectangle is the number of pixels the overscan area extends
550      * into the display on that side.
551      */
getOverscanInsets(Rect outRect)552     public void getOverscanInsets(Rect outRect) {
553         synchronized (this) {
554             updateDisplayInfoLocked();
555             outRect.set(mDisplayInfo.overscanLeft, mDisplayInfo.overscanTop,
556                     mDisplayInfo.overscanRight, mDisplayInfo.overscanBottom);
557         }
558     }
559 
560     /**
561      * Returns the rotation of the screen from its "natural" orientation.
562      * The returned value may be {@link Surface#ROTATION_0 Surface.ROTATION_0}
563      * (no rotation), {@link Surface#ROTATION_90 Surface.ROTATION_90},
564      * {@link Surface#ROTATION_180 Surface.ROTATION_180}, or
565      * {@link Surface#ROTATION_270 Surface.ROTATION_270}.  For
566      * example, if a device has a naturally tall screen, and the user has
567      * turned it on its side to go into a landscape orientation, the value
568      * returned here may be either {@link Surface#ROTATION_90 Surface.ROTATION_90}
569      * or {@link Surface#ROTATION_270 Surface.ROTATION_270} depending on
570      * the direction it was turned.  The angle is the rotation of the drawn
571      * graphics on the screen, which is the opposite direction of the physical
572      * rotation of the device.  For example, if the device is rotated 90
573      * degrees counter-clockwise, to compensate rendering will be rotated by
574      * 90 degrees clockwise and thus the returned value here will be
575      * {@link Surface#ROTATION_90 Surface.ROTATION_90}.
576      */
577     @Surface.Rotation
getRotation()578     public int getRotation() {
579         synchronized (this) {
580             updateDisplayInfoLocked();
581             return mDisplayInfo.rotation;
582         }
583     }
584 
585     /**
586      * @deprecated use {@link #getRotation}
587      * @return orientation of this display.
588      */
589     @Deprecated
590     @Surface.Rotation
getOrientation()591     public int getOrientation() {
592         return getRotation();
593     }
594 
595     /**
596      * Gets the pixel format of the display.
597      * @return One of the constants defined in {@link android.graphics.PixelFormat}.
598      *
599      * @deprecated This method is no longer supported.
600      * The result is always {@link PixelFormat#RGBA_8888}.
601      */
602     @Deprecated
getPixelFormat()603     public int getPixelFormat() {
604         return PixelFormat.RGBA_8888;
605     }
606 
607     /**
608      * Gets the refresh rate of this display in frames per second.
609      */
getRefreshRate()610     public float getRefreshRate() {
611         synchronized (this) {
612             updateDisplayInfoLocked();
613             return mDisplayInfo.refreshRate;
614         }
615     }
616 
617     /**
618      * Get the supported refresh rates of this display in frames per second.
619      */
getSupportedRefreshRates()620     public float[] getSupportedRefreshRates() {
621         synchronized (this) {
622             updateDisplayInfoLocked();
623             final float[] refreshRates = mDisplayInfo.supportedRefreshRates;
624             return Arrays.copyOf(refreshRates, refreshRates.length);
625         }
626     }
627 
628     /**
629      * Gets the app VSYNC offset, in nanoseconds.  This is a positive value indicating
630      * the phase offset of the VSYNC events provided by Choreographer relative to the
631      * display refresh.  For example, if Choreographer reports that the refresh occurred
632      * at time N, it actually occurred at (N - appVsyncOffset).
633      * <p>
634      * Apps generally do not need to be aware of this.  It's only useful for fine-grained
635      * A/V synchronization.
636      */
getAppVsyncOffsetNanos()637     public long getAppVsyncOffsetNanos() {
638         synchronized (this) {
639             updateDisplayInfoLocked();
640             return mDisplayInfo.appVsyncOffsetNanos;
641         }
642     }
643 
644     /**
645      * This is how far in advance a buffer must be queued for presentation at
646      * a given time.  If you want a buffer to appear on the screen at
647      * time N, you must submit the buffer before (N - presentationDeadline).
648      * <p>
649      * The desired presentation time for GLES rendering may be set with
650      * {@link android.opengl.EGLExt#eglPresentationTimeANDROID}.  For video decoding, use
651      * {@link android.media.MediaCodec#releaseOutputBuffer(int, long)}.  Times are
652      * expressed in nanoseconds, using the system monotonic clock
653      * ({@link System#nanoTime}).
654      */
getPresentationDeadlineNanos()655     public long getPresentationDeadlineNanos() {
656         synchronized (this) {
657             updateDisplayInfoLocked();
658             return mDisplayInfo.presentationDeadlineNanos;
659         }
660     }
661 
662     /**
663      * Gets display metrics that describe the size and density of this display.
664      * <p>
665      * The size is adjusted based on the current rotation of the display.
666      * </p><p>
667      * The size returned by this method does not necessarily represent the
668      * actual raw size (native resolution) of the display.  The returned size may
669      * be adjusted to exclude certain system decor elements that are always visible.
670      * It may also be scaled to provide compatibility with older applications that
671      * were originally designed for smaller displays.
672      * </p>
673      *
674      * @param outMetrics A {@link DisplayMetrics} object to receive the metrics.
675      */
getMetrics(DisplayMetrics outMetrics)676     public void getMetrics(DisplayMetrics outMetrics) {
677         synchronized (this) {
678             updateDisplayInfoLocked();
679             mDisplayInfo.getAppMetrics(outMetrics, mDisplayAdjustments);
680         }
681     }
682 
683     /**
684      * Gets the real size of the display without subtracting any window decor or
685      * applying any compatibility scale factors.
686      * <p>
687      * The size is adjusted based on the current rotation of the display.
688      * </p><p>
689      * The real size may be smaller than the physical size of the screen when the
690      * window manager is emulating a smaller display (using adb shell am display-size).
691      * </p>
692      *
693      * @param outSize Set to the real size of the display.
694      */
getRealSize(Point outSize)695     public void getRealSize(Point outSize) {
696         synchronized (this) {
697             updateDisplayInfoLocked();
698             outSize.x = mDisplayInfo.logicalWidth;
699             outSize.y = mDisplayInfo.logicalHeight;
700         }
701     }
702 
703     /**
704      * Gets display metrics based on the real size of this display.
705      * <p>
706      * The size is adjusted based on the current rotation of the display.
707      * </p><p>
708      * The real size may be smaller than the physical size of the screen when the
709      * window manager is emulating a smaller display (using adb shell am display-size).
710      * </p>
711      *
712      * @param outMetrics A {@link DisplayMetrics} object to receive the metrics.
713      */
getRealMetrics(DisplayMetrics outMetrics)714     public void getRealMetrics(DisplayMetrics outMetrics) {
715         synchronized (this) {
716             updateDisplayInfoLocked();
717             mDisplayInfo.getLogicalMetrics(outMetrics,
718                     CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO,
719                     mDisplayAdjustments.getActivityToken());
720         }
721     }
722 
723     /**
724      * Gets the state of the display, such as whether it is on or off.
725      *
726      * @return The state of the display: one of {@link #STATE_OFF}, {@link #STATE_ON},
727      * {@link #STATE_DOZE}, {@link #STATE_DOZE_SUSPEND}, or {@link #STATE_UNKNOWN}.
728      */
getState()729     public int getState() {
730         synchronized (this) {
731             updateDisplayInfoLocked();
732             return mIsValid ? mDisplayInfo.state : STATE_UNKNOWN;
733         }
734     }
735 
736     /**
737      * Returns true if the specified UID has access to this display.
738      * @hide
739      */
hasAccess(int uid)740     public boolean hasAccess(int uid) {
741         return Display.hasAccess(uid, mFlags, mOwnerUid);
742     }
743 
744     /** @hide */
hasAccess(int uid, int flags, int ownerUid)745     public static boolean hasAccess(int uid, int flags, int ownerUid) {
746         return (flags & Display.FLAG_PRIVATE) == 0
747                 || uid == ownerUid
748                 || uid == Process.SYSTEM_UID
749                 || uid == 0;
750     }
751 
752     /**
753      * Returns true if the display is a public presentation display.
754      * @hide
755      */
isPublicPresentation()756     public boolean isPublicPresentation() {
757         return (mFlags & (Display.FLAG_PRIVATE | Display.FLAG_PRESENTATION)) ==
758                 Display.FLAG_PRESENTATION;
759     }
760 
updateDisplayInfoLocked()761     private void updateDisplayInfoLocked() {
762         // Note: The display manager caches display info objects on our behalf.
763         DisplayInfo newInfo = mGlobal.getDisplayInfo(mDisplayId);
764         if (newInfo == null) {
765             // Preserve the old mDisplayInfo after the display is removed.
766             if (mIsValid) {
767                 mIsValid = false;
768                 if (DEBUG) {
769                     Log.d(TAG, "Logical display " + mDisplayId + " was removed.");
770                 }
771             }
772         } else {
773             // Use the new display info.  (It might be the same object if nothing changed.)
774             mDisplayInfo = newInfo;
775             if (!mIsValid) {
776                 mIsValid = true;
777                 if (DEBUG) {
778                     Log.d(TAG, "Logical display " + mDisplayId + " was recreated.");
779                 }
780             }
781         }
782     }
783 
updateCachedAppSizeIfNeededLocked()784     private void updateCachedAppSizeIfNeededLocked() {
785         long now = SystemClock.uptimeMillis();
786         if (now > mLastCachedAppSizeUpdate + CACHED_APP_SIZE_DURATION_MILLIS) {
787             updateDisplayInfoLocked();
788             mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments);
789             mCachedAppWidthCompat = mTempMetrics.widthPixels;
790             mCachedAppHeightCompat = mTempMetrics.heightPixels;
791             mLastCachedAppSizeUpdate = now;
792         }
793     }
794 
795     // For debugging purposes
796     @Override
toString()797     public String toString() {
798         synchronized (this) {
799             updateDisplayInfoLocked();
800             mDisplayInfo.getAppMetrics(mTempMetrics, mDisplayAdjustments);
801             return "Display id " + mDisplayId + ": " + mDisplayInfo
802                     + ", " + mTempMetrics + ", isValid=" + mIsValid;
803         }
804     }
805 
806     /**
807      * @hide
808      */
typeToString(int type)809     public static String typeToString(int type) {
810         switch (type) {
811             case TYPE_UNKNOWN:
812                 return "UNKNOWN";
813             case TYPE_BUILT_IN:
814                 return "BUILT_IN";
815             case TYPE_HDMI:
816                 return "HDMI";
817             case TYPE_WIFI:
818                 return "WIFI";
819             case TYPE_OVERLAY:
820                 return "OVERLAY";
821             case TYPE_VIRTUAL:
822                 return "VIRTUAL";
823             default:
824                 return Integer.toString(type);
825         }
826     }
827 
828     /**
829      * @hide
830      */
stateToString(int state)831     public static String stateToString(int state) {
832         switch (state) {
833             case STATE_UNKNOWN:
834                 return "UNKNOWN";
835             case STATE_OFF:
836                 return "OFF";
837             case STATE_ON:
838                 return "ON";
839             case STATE_DOZE:
840                 return "DOZE";
841             case STATE_DOZE_SUSPEND:
842                 return "DOZE_SUSPEND";
843             default:
844                 return Integer.toString(state);
845         }
846     }
847 
848     /**
849      * Returns true if display updates may be suspended while in the specified
850      * display power state.
851      * @hide
852      */
isSuspendedState(int state)853     public static boolean isSuspendedState(int state) {
854         return state == STATE_OFF || state == STATE_DOZE_SUSPEND;
855     }
856 }
857