Home | History | Annotate | Download | only in view
      1 /*
      2  * Copyright (C) 2012 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.os.IBinder;
     21 import android.os.Parcel;
     22 import android.os.Parcelable;
     23 import android.util.DisplayMetrics;
     24 
     25 import java.util.Arrays;
     26 
     27 import libcore.util.EmptyArray;
     28 import libcore.util.Objects;
     29 
     30 /**
     31  * Describes the characteristics of a particular logical display.
     32  * @hide
     33  */
     34 public final class DisplayInfo implements Parcelable {
     35     /**
     36      * The surface flinger layer stack associated with this logical display.
     37      */
     38     public int layerStack;
     39 
     40     /**
     41      * Display flags.
     42      */
     43     public int flags;
     44 
     45     /**
     46      * Display type.
     47      */
     48     public int type;
     49 
     50     /**
     51      * Display address, or null if none.
     52      * Interpretation varies by display type.
     53      */
     54     public String address;
     55 
     56     /**
     57      * The human-readable name of the display.
     58      */
     59     public String name;
     60 
     61     /**
     62      * Unique identifier for the display. Shouldn't be displayed to the user.
     63      */
     64     public String uniqueId;
     65 
     66     /**
     67      * The width of the portion of the display that is available to applications, in pixels.
     68      * Represents the size of the display minus any system decorations.
     69      */
     70     public int appWidth;
     71 
     72     /**
     73      * The height of the portion of the display that is available to applications, in pixels.
     74      * Represents the size of the display minus any system decorations.
     75      */
     76     public int appHeight;
     77 
     78     /**
     79      * The smallest value of {@link #appWidth} that an application is likely to encounter,
     80      * in pixels, excepting cases where the width may be even smaller due to the presence
     81      * of a soft keyboard, for example.
     82      */
     83     public int smallestNominalAppWidth;
     84 
     85     /**
     86      * The smallest value of {@link #appHeight} that an application is likely to encounter,
     87      * in pixels, excepting cases where the height may be even smaller due to the presence
     88      * of a soft keyboard, for example.
     89      */
     90     public int smallestNominalAppHeight;
     91 
     92     /**
     93      * The largest value of {@link #appWidth} that an application is likely to encounter,
     94      * in pixels, excepting cases where the width may be even larger due to system decorations
     95      * such as the status bar being hidden, for example.
     96      */
     97     public int largestNominalAppWidth;
     98 
     99     /**
    100      * The largest value of {@link #appHeight} that an application is likely to encounter,
    101      * in pixels, excepting cases where the height may be even larger due to system decorations
    102      * such as the status bar being hidden, for example.
    103      */
    104     public int largestNominalAppHeight;
    105 
    106     /**
    107      * The logical width of the display, in pixels.
    108      * Represents the usable size of the display which may be smaller than the
    109      * physical size when the system is emulating a smaller display.
    110      */
    111     public int logicalWidth;
    112 
    113     /**
    114      * The logical height of the display, in pixels.
    115      * Represents the usable size of the display which may be smaller than the
    116      * physical size when the system is emulating a smaller display.
    117      */
    118     public int logicalHeight;
    119 
    120     /**
    121      * @hide
    122      * Number of overscan pixels on the left side of the display.
    123      */
    124     public int overscanLeft;
    125 
    126     /**
    127      * @hide
    128      * Number of overscan pixels on the top side of the display.
    129      */
    130     public int overscanTop;
    131 
    132     /**
    133      * @hide
    134      * Number of overscan pixels on the right side of the display.
    135      */
    136     public int overscanRight;
    137 
    138     /**
    139      * @hide
    140      * Number of overscan pixels on the bottom side of the display.
    141      */
    142     public int overscanBottom;
    143 
    144     /**
    145      * The rotation of the display relative to its natural orientation.
    146      * May be one of {@link android.view.Surface#ROTATION_0},
    147      * {@link android.view.Surface#ROTATION_90}, {@link android.view.Surface#ROTATION_180},
    148      * {@link android.view.Surface#ROTATION_270}.
    149      * <p>
    150      * The value of this field is indeterminate if the logical display is presented on
    151      * more than one physical display.
    152      * </p>
    153      */
    154     @Surface.Rotation
    155     public int rotation;
    156 
    157     /**
    158      * The refresh rate of this display in frames per second.
    159      * <p>
    160      * The value of this field is indeterminate if the logical display is presented on
    161      * more than one physical display.
    162      * </p>
    163      */
    164     public float refreshRate;
    165 
    166     /**
    167      * The supported refresh rates of this display at the current resolution in frames per second.
    168      */
    169     public float[] supportedRefreshRates = EmptyArray.FLOAT;
    170 
    171     /**
    172      * The logical display density which is the basis for density-independent
    173      * pixels.
    174      */
    175     public int logicalDensityDpi;
    176 
    177     /**
    178      * The exact physical pixels per inch of the screen in the X dimension.
    179      * <p>
    180      * The value of this field is indeterminate if the logical display is presented on
    181      * more than one physical display.
    182      * </p>
    183      */
    184     public float physicalXDpi;
    185 
    186     /**
    187      * The exact physical pixels per inch of the screen in the Y dimension.
    188      * <p>
    189      * The value of this field is indeterminate if the logical display is presented on
    190      * more than one physical display.
    191      * </p>
    192      */
    193     public float physicalYDpi;
    194 
    195     /**
    196      * This is a positive value indicating the phase offset of the VSYNC events provided by
    197      * Choreographer relative to the display refresh.  For example, if Choreographer reports
    198      * that the refresh occurred at time N, it actually occurred at (N - appVsyncOffsetNanos).
    199      */
    200     public long appVsyncOffsetNanos;
    201 
    202     /**
    203      * This is how far in advance a buffer must be queued for presentation at
    204      * a given time.  If you want a buffer to appear on the screen at
    205      * time N, you must submit the buffer before (N - bufferDeadlineNanos).
    206      */
    207     public long presentationDeadlineNanos;
    208 
    209     /**
    210      * The state of the display, such as {@link android.view.Display#STATE_ON}.
    211      */
    212     public int state;
    213 
    214     /**
    215      * The UID of the application that owns this display, or zero if it is owned by the system.
    216      * <p>
    217      * If the display is private, then only the owner can use it.
    218      * </p>
    219      */
    220     public int ownerUid;
    221 
    222     /**
    223      * The package name of the application that owns this display, or null if it is
    224      * owned by the system.
    225      * <p>
    226      * If the display is private, then only the owner can use it.
    227      * </p>
    228      */
    229     public String ownerPackageName;
    230 
    231     public static final Creator<DisplayInfo> CREATOR = new Creator<DisplayInfo>() {
    232         @Override
    233         public DisplayInfo createFromParcel(Parcel source) {
    234             return new DisplayInfo(source);
    235         }
    236 
    237         @Override
    238         public DisplayInfo[] newArray(int size) {
    239             return new DisplayInfo[size];
    240         }
    241     };
    242 
    243     public DisplayInfo() {
    244     }
    245 
    246     public DisplayInfo(DisplayInfo other) {
    247         copyFrom(other);
    248     }
    249 
    250     private DisplayInfo(Parcel source) {
    251         readFromParcel(source);
    252     }
    253 
    254     @Override
    255     public boolean equals(Object o) {
    256         return o instanceof DisplayInfo && equals((DisplayInfo)o);
    257     }
    258 
    259     public boolean equals(DisplayInfo other) {
    260         return other != null
    261                 && layerStack == other.layerStack
    262                 && flags == other.flags
    263                 && type == other.type
    264                 && Objects.equal(address, other.address)
    265                 && Objects.equal(uniqueId, other.uniqueId)
    266                 && appWidth == other.appWidth
    267                 && appHeight == other.appHeight
    268                 && smallestNominalAppWidth == other.smallestNominalAppWidth
    269                 && smallestNominalAppHeight == other.smallestNominalAppHeight
    270                 && largestNominalAppWidth == other.largestNominalAppWidth
    271                 && largestNominalAppHeight == other.largestNominalAppHeight
    272                 && logicalWidth == other.logicalWidth
    273                 && logicalHeight == other.logicalHeight
    274                 && overscanLeft == other.overscanLeft
    275                 && overscanTop == other.overscanTop
    276                 && overscanRight == other.overscanRight
    277                 && overscanBottom == other.overscanBottom
    278                 && rotation == other.rotation
    279                 && refreshRate == other.refreshRate
    280                 && logicalDensityDpi == other.logicalDensityDpi
    281                 && physicalXDpi == other.physicalXDpi
    282                 && physicalYDpi == other.physicalYDpi
    283                 && appVsyncOffsetNanos == other.appVsyncOffsetNanos
    284                 && presentationDeadlineNanos == other.presentationDeadlineNanos
    285                 && state == other.state
    286                 && ownerUid == other.ownerUid
    287                 && Objects.equal(ownerPackageName, other.ownerPackageName);
    288     }
    289 
    290     @Override
    291     public int hashCode() {
    292         return 0; // don't care
    293     }
    294 
    295     public void copyFrom(DisplayInfo other) {
    296         layerStack = other.layerStack;
    297         flags = other.flags;
    298         type = other.type;
    299         address = other.address;
    300         name = other.name;
    301         uniqueId = other.uniqueId;
    302         appWidth = other.appWidth;
    303         appHeight = other.appHeight;
    304         smallestNominalAppWidth = other.smallestNominalAppWidth;
    305         smallestNominalAppHeight = other.smallestNominalAppHeight;
    306         largestNominalAppWidth = other.largestNominalAppWidth;
    307         largestNominalAppHeight = other.largestNominalAppHeight;
    308         logicalWidth = other.logicalWidth;
    309         logicalHeight = other.logicalHeight;
    310         overscanLeft = other.overscanLeft;
    311         overscanTop = other.overscanTop;
    312         overscanRight = other.overscanRight;
    313         overscanBottom = other.overscanBottom;
    314         rotation = other.rotation;
    315         refreshRate = other.refreshRate;
    316         supportedRefreshRates = Arrays.copyOf(
    317                 other.supportedRefreshRates, other.supportedRefreshRates.length);
    318         logicalDensityDpi = other.logicalDensityDpi;
    319         physicalXDpi = other.physicalXDpi;
    320         physicalYDpi = other.physicalYDpi;
    321         appVsyncOffsetNanos = other.appVsyncOffsetNanos;
    322         presentationDeadlineNanos = other.presentationDeadlineNanos;
    323         state = other.state;
    324         ownerUid = other.ownerUid;
    325         ownerPackageName = other.ownerPackageName;
    326     }
    327 
    328     public void readFromParcel(Parcel source) {
    329         layerStack = source.readInt();
    330         flags = source.readInt();
    331         type = source.readInt();
    332         address = source.readString();
    333         name = source.readString();
    334         appWidth = source.readInt();
    335         appHeight = source.readInt();
    336         smallestNominalAppWidth = source.readInt();
    337         smallestNominalAppHeight = source.readInt();
    338         largestNominalAppWidth = source.readInt();
    339         largestNominalAppHeight = source.readInt();
    340         logicalWidth = source.readInt();
    341         logicalHeight = source.readInt();
    342         overscanLeft = source.readInt();
    343         overscanTop = source.readInt();
    344         overscanRight = source.readInt();
    345         overscanBottom = source.readInt();
    346         rotation = source.readInt();
    347         refreshRate = source.readFloat();
    348         supportedRefreshRates = source.createFloatArray();
    349         logicalDensityDpi = source.readInt();
    350         physicalXDpi = source.readFloat();
    351         physicalYDpi = source.readFloat();
    352         appVsyncOffsetNanos = source.readLong();
    353         presentationDeadlineNanos = source.readLong();
    354         state = source.readInt();
    355         ownerUid = source.readInt();
    356         ownerPackageName = source.readString();
    357         uniqueId = source.readString();
    358     }
    359 
    360     @Override
    361     public void writeToParcel(Parcel dest, int flags) {
    362         dest.writeInt(layerStack);
    363         dest.writeInt(this.flags);
    364         dest.writeInt(type);
    365         dest.writeString(address);
    366         dest.writeString(name);
    367         dest.writeInt(appWidth);
    368         dest.writeInt(appHeight);
    369         dest.writeInt(smallestNominalAppWidth);
    370         dest.writeInt(smallestNominalAppHeight);
    371         dest.writeInt(largestNominalAppWidth);
    372         dest.writeInt(largestNominalAppHeight);
    373         dest.writeInt(logicalWidth);
    374         dest.writeInt(logicalHeight);
    375         dest.writeInt(overscanLeft);
    376         dest.writeInt(overscanTop);
    377         dest.writeInt(overscanRight);
    378         dest.writeInt(overscanBottom);
    379         dest.writeInt(rotation);
    380         dest.writeFloat(refreshRate);
    381         dest.writeFloatArray(supportedRefreshRates);
    382         dest.writeInt(logicalDensityDpi);
    383         dest.writeFloat(physicalXDpi);
    384         dest.writeFloat(physicalYDpi);
    385         dest.writeLong(appVsyncOffsetNanos);
    386         dest.writeLong(presentationDeadlineNanos);
    387         dest.writeInt(state);
    388         dest.writeInt(ownerUid);
    389         dest.writeString(ownerPackageName);
    390         dest.writeString(uniqueId);
    391     }
    392 
    393     @Override
    394     public int describeContents() {
    395         return 0;
    396     }
    397 
    398     public void getAppMetrics(DisplayMetrics outMetrics) {
    399         getAppMetrics(outMetrics, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
    400     }
    401 
    402     public void getAppMetrics(DisplayMetrics outMetrics, DisplayAdjustments displayAdjustments) {
    403         getMetricsWithSize(outMetrics, displayAdjustments.getCompatibilityInfo(),
    404                 displayAdjustments.getActivityToken(), appWidth, appHeight);
    405     }
    406 
    407     public void getAppMetrics(DisplayMetrics outMetrics, CompatibilityInfo ci, IBinder token) {
    408         getMetricsWithSize(outMetrics, ci, token, appWidth, appHeight);
    409     }
    410 
    411     public void getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
    412             IBinder token) {
    413         getMetricsWithSize(outMetrics, compatInfo, token, logicalWidth, logicalHeight);
    414     }
    415 
    416     public int getNaturalWidth() {
    417         return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ?
    418                 logicalWidth : logicalHeight;
    419     }
    420 
    421     public int getNaturalHeight() {
    422         return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ?
    423                 logicalHeight : logicalWidth;
    424     }
    425 
    426     /**
    427      * Returns true if the specified UID has access to this display.
    428      */
    429     public boolean hasAccess(int uid) {
    430         return Display.hasAccess(uid, flags, ownerUid);
    431     }
    432 
    433     private void getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
    434             IBinder token, int width, int height) {
    435         outMetrics.densityDpi = outMetrics.noncompatDensityDpi = logicalDensityDpi;
    436         outMetrics.noncompatWidthPixels  = outMetrics.widthPixels = width;
    437         outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height;
    438 
    439         outMetrics.density = outMetrics.noncompatDensity =
    440                 logicalDensityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
    441         outMetrics.scaledDensity = outMetrics.noncompatScaledDensity = outMetrics.density;
    442         outMetrics.xdpi = outMetrics.noncompatXdpi = physicalXDpi;
    443         outMetrics.ydpi = outMetrics.noncompatYdpi = physicalYDpi;
    444 
    445         if (!compatInfo.equals(CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO)) {
    446             compatInfo.applyToDisplayMetrics(outMetrics);
    447         }
    448     }
    449 
    450     // For debugging purposes
    451     @Override
    452     public String toString() {
    453         StringBuilder sb = new StringBuilder();
    454         sb.append("DisplayInfo{\"");
    455         sb.append(name);
    456         sb.append("\", uniqueId \"");
    457         sb.append(uniqueId);
    458         sb.append("\", app ");
    459         sb.append(appWidth);
    460         sb.append(" x ");
    461         sb.append(appHeight);
    462         sb.append(", real ");
    463         sb.append(logicalWidth);
    464         sb.append(" x ");
    465         sb.append(logicalHeight);
    466         if (overscanLeft != 0 || overscanTop != 0 || overscanRight != 0 || overscanBottom != 0) {
    467             sb.append(", overscan (");
    468             sb.append(overscanLeft);
    469             sb.append(",");
    470             sb.append(overscanTop);
    471             sb.append(",");
    472             sb.append(overscanRight);
    473             sb.append(",");
    474             sb.append(overscanBottom);
    475             sb.append(")");
    476         }
    477         sb.append(", largest app ");
    478         sb.append(largestNominalAppWidth);
    479         sb.append(" x ");
    480         sb.append(largestNominalAppHeight);
    481         sb.append(", smallest app ");
    482         sb.append(smallestNominalAppWidth);
    483         sb.append(" x ");
    484         sb.append(smallestNominalAppHeight);
    485         sb.append(", ");
    486         sb.append(refreshRate);
    487         sb.append(" fps, supportedRefreshRates ");
    488         sb.append(Arrays.toString(supportedRefreshRates));
    489         sb.append(", rotation ");
    490         sb.append(rotation);
    491         sb.append(", density ");
    492         sb.append(logicalDensityDpi);
    493         sb.append(" (");
    494         sb.append(physicalXDpi);
    495         sb.append(" x ");
    496         sb.append(physicalYDpi);
    497         sb.append(") dpi, layerStack ");
    498         sb.append(layerStack);
    499         sb.append(", appVsyncOff ");
    500         sb.append(appVsyncOffsetNanos);
    501         sb.append(", presDeadline ");
    502         sb.append(presentationDeadlineNanos);
    503         sb.append(", type ");
    504         sb.append(Display.typeToString(type));
    505         if (address != null) {
    506             sb.append(", address ").append(address);
    507         }
    508         sb.append(", state ");
    509         sb.append(Display.stateToString(state));
    510         if (ownerUid != 0 || ownerPackageName != null) {
    511             sb.append(", owner ").append(ownerPackageName);
    512             sb.append(" (uid ").append(ownerUid).append(")");
    513         }
    514         sb.append(flagsToString(flags));
    515         sb.append("}");
    516         return sb.toString();
    517     }
    518 
    519     private static String flagsToString(int flags) {
    520         StringBuilder result = new StringBuilder();
    521         if ((flags & Display.FLAG_SECURE) != 0) {
    522             result.append(", FLAG_SECURE");
    523         }
    524         if ((flags & Display.FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
    525             result.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS");
    526         }
    527         if ((flags & Display.FLAG_PRIVATE) != 0) {
    528             result.append(", FLAG_PRIVATE");
    529         }
    530         if ((flags & Display.FLAG_PRESENTATION) != 0) {
    531             result.append(", FLAG_PRESENTATION");
    532         }
    533         return result.toString();
    534     }
    535 }
    536