OSDN Git Service

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