Home | History | Annotate | Download | only in display
      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 com.android.server.display;
     18 
     19 import android.util.DisplayMetrics;
     20 import android.view.Display;
     21 import android.view.Surface;
     22 
     23 import libcore.util.Objects;
     24 
     25 /**
     26  * Describes the characteristics of a physical display device.
     27  */
     28 final class DisplayDeviceInfo {
     29     /**
     30      * Flag: Indicates that this display device should be considered the default display
     31      * device of the system.
     32      */
     33     public static final int FLAG_DEFAULT_DISPLAY = 1 << 0;
     34 
     35     /**
     36      * Flag: Indicates that the orientation of this display device is coupled to the
     37      * rotation of its associated logical display.
     38      * <p>
     39      * This flag should be applied to the default display to indicate that the user
     40      * physically rotates the display when content is presented in a different orientation.
     41      * The display manager will apply a coordinate transformation assuming that the
     42      * physical orientation of the display matches the logical orientation of its content.
     43      * </p><p>
     44      * The flag should not be set when the display device is mounted in a fixed orientation
     45      * such as on a desk.  The display manager will apply a coordinate transformation
     46      * such as a scale and translation to letterbox or pillarbox format under the
     47      * assumption that the physical orientation of the display is invariant.
     48      * </p>
     49      */
     50     public static final int FLAG_ROTATES_WITH_CONTENT = 1 << 1;
     51 
     52     /**
     53      * Flag: Indicates that this display device has secure video output, such as HDCP.
     54      */
     55     public static final int FLAG_SECURE = 1 << 2;
     56 
     57     /**
     58      * Flag: Indicates that this display device supports compositing
     59      * from gralloc protected buffers.
     60      */
     61     public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1 << 3;
     62 
     63     /**
     64      * Flag: Indicates that the display device is owned by a particular application
     65      * and that no other application should be able to interact with it.
     66      */
     67     public static final int FLAG_PRIVATE = 1 << 4;
     68 
     69     /**
     70      * Flag: Indicates that the display device is not blanked automatically by
     71      * the power manager.
     72      */
     73     public static final int FLAG_NEVER_BLANK = 1 << 5;
     74 
     75     /**
     76      * Flag: Indicates that the display is suitable for presentations.
     77      */
     78     public static final int FLAG_PRESENTATION = 1 << 6;
     79 
     80     /**
     81      * Touch attachment: Display does not receive touch.
     82      */
     83     public static final int TOUCH_NONE = 0;
     84 
     85     /**
     86      * Touch attachment: Touch input is via the internal interface.
     87      */
     88     public static final int TOUCH_INTERNAL = 1;
     89 
     90     /**
     91      * Touch attachment: Touch input is via an external interface, such as USB.
     92      */
     93     public static final int TOUCH_EXTERNAL = 2;
     94 
     95     /**
     96      * Gets the name of the display device, which may be derived from
     97      * EDID or other sources.  The name may be displayed to the user.
     98      */
     99     public String name;
    100 
    101     /**
    102      * The width of the display in its natural orientation, in pixels.
    103      * This value is not affected by display rotation.
    104      */
    105     public int width;
    106 
    107     /**
    108      * The height of the display in its natural orientation, in pixels.
    109      * This value is not affected by display rotation.
    110      */
    111     public int height;
    112 
    113     /**
    114      * The refresh rate of the display.
    115      */
    116     public float refreshRate;
    117 
    118     /**
    119      * The nominal apparent density of the display in DPI used for layout calculations.
    120      * This density is sensitive to the viewing distance.  A big TV and a tablet may have
    121      * the same apparent density even though the pixels on the TV are much bigger than
    122      * those on the tablet.
    123      */
    124     public int densityDpi;
    125 
    126     /**
    127      * The physical density of the display in DPI in the X direction.
    128      * This density should specify the physical size of each pixel.
    129      */
    130     public float xDpi;
    131 
    132     /**
    133      * The physical density of the display in DPI in the X direction.
    134      * This density should specify the physical size of each pixel.
    135      */
    136     public float yDpi;
    137 
    138     /**
    139      * Display flags.
    140      */
    141     public int flags;
    142 
    143     /**
    144      * The touch attachment, per {@link DisplayViewport#touch}.
    145      */
    146     public int touch;
    147 
    148     /**
    149      * The additional rotation to apply to all content presented on the display device
    150      * relative to its physical coordinate system.  Default is {@link Surface#ROTATION_0}.
    151      * <p>
    152      * This field can be used to compensate for the fact that the display has been
    153      * physically rotated relative to its natural orientation such as an HDMI monitor
    154      * that has been mounted sideways to appear to be portrait rather than landscape.
    155      * </p>
    156      */
    157     public int rotation = Surface.ROTATION_0;
    158 
    159     /**
    160      * Display type.
    161      */
    162     public int type;
    163 
    164     /**
    165      * Display address, or null if none.
    166      * Interpretation varies by display type.
    167      */
    168     public String address;
    169 
    170     /**
    171      * The UID of the application that owns this display, or zero if it is owned by the system.
    172      * <p>
    173      * If the display is private, then only the owner can use it.
    174      * </p>
    175      */
    176     public int ownerUid;
    177 
    178     /**
    179      * The package name of the application that owns this display, or null if it is
    180      * owned by the system.
    181      * <p>
    182      * If the display is private, then only the owner can use it.
    183      * </p>
    184      */
    185     public String ownerPackageName;
    186 
    187     public void setAssumedDensityForExternalDisplay(int width, int height) {
    188         densityDpi = Math.min(width, height) * DisplayMetrics.DENSITY_XHIGH / 1080;
    189         // Technically, these values should be smaller than the apparent density
    190         // but we don't know the physical size of the display.
    191         xDpi = densityDpi;
    192         yDpi = densityDpi;
    193     }
    194 
    195     @Override
    196     public boolean equals(Object o) {
    197         return o instanceof DisplayDeviceInfo && equals((DisplayDeviceInfo)o);
    198     }
    199 
    200     public boolean equals(DisplayDeviceInfo other) {
    201         return other != null
    202                 && Objects.equal(name, other.name)
    203                 && width == other.width
    204                 && height == other.height
    205                 && refreshRate == other.refreshRate
    206                 && densityDpi == other.densityDpi
    207                 && xDpi == other.xDpi
    208                 && yDpi == other.yDpi
    209                 && flags == other.flags
    210                 && touch == other.touch
    211                 && rotation == other.rotation
    212                 && type == other.type
    213                 && Objects.equal(address, other.address)
    214                 && ownerUid == other.ownerUid
    215                 && Objects.equal(ownerPackageName, other.ownerPackageName);
    216     }
    217 
    218     @Override
    219     public int hashCode() {
    220         return 0; // don't care
    221     }
    222 
    223     public void copyFrom(DisplayDeviceInfo other) {
    224         name = other.name;
    225         width = other.width;
    226         height = other.height;
    227         refreshRate = other.refreshRate;
    228         densityDpi = other.densityDpi;
    229         xDpi = other.xDpi;
    230         yDpi = other.yDpi;
    231         flags = other.flags;
    232         touch = other.touch;
    233         rotation = other.rotation;
    234         type = other.type;
    235         address = other.address;
    236         ownerUid = other.ownerUid;
    237         ownerPackageName = other.ownerPackageName;
    238     }
    239 
    240     // For debugging purposes
    241     @Override
    242     public String toString() {
    243         StringBuilder sb = new StringBuilder();
    244         sb.append("DisplayDeviceInfo{\"");
    245         sb.append(name).append("\": ").append(width).append(" x ").append(height);
    246         sb.append(", ").append(refreshRate).append(" fps, ");
    247         sb.append("density ").append(densityDpi);
    248         sb.append(", ").append(xDpi).append(" x ").append(yDpi).append(" dpi");
    249         sb.append(", touch ").append(touchToString(touch));
    250         sb.append(", rotation ").append(rotation);
    251         sb.append(", type ").append(Display.typeToString(type));
    252         if (address != null) {
    253             sb.append(", address ").append(address);
    254         }
    255         if (ownerUid != 0 || ownerPackageName != null) {
    256             sb.append(", owner ").append(ownerPackageName);
    257             sb.append(" (uid ").append(ownerUid).append(")");
    258         }
    259         sb.append(flagsToString(flags));
    260         sb.append("}");
    261         return sb.toString();
    262     }
    263 
    264     private static String touchToString(int touch) {
    265         switch (touch) {
    266             case TOUCH_NONE:
    267                 return "NONE";
    268             case TOUCH_INTERNAL:
    269                 return "INTERNAL";
    270             case TOUCH_EXTERNAL:
    271                 return "EXTERNAL";
    272             default:
    273                 return Integer.toString(touch);
    274         }
    275     }
    276 
    277     private static String flagsToString(int flags) {
    278         StringBuilder msg = new StringBuilder();
    279         if ((flags & FLAG_DEFAULT_DISPLAY) != 0) {
    280             msg.append(", FLAG_DEFAULT_DISPLAY");
    281         }
    282         if ((flags & FLAG_ROTATES_WITH_CONTENT) != 0) {
    283             msg.append(", FLAG_ROTATES_WITH_CONTENT");
    284         }
    285         if ((flags & FLAG_SECURE) != 0) {
    286             msg.append(", FLAG_SECURE");
    287         }
    288         if ((flags & FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
    289             msg.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS");
    290         }
    291         if ((flags & FLAG_PRIVATE) != 0) {
    292             msg.append(", FLAG_PRIVATE");
    293         }
    294         if ((flags & FLAG_NEVER_BLANK) != 0) {
    295             msg.append(", FLAG_NEVER_BLANK");
    296         }
    297         if ((flags & FLAG_PRESENTATION) != 0) {
    298             msg.append(", FLAG_PRESENTATION");
    299         }
    300         return msg.toString();
    301     }
    302 }
    303