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