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