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