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