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