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