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.hardware.display.DisplayViewport;
     20 import android.util.DisplayMetrics;
     21 import android.view.Display;
     22 import android.view.Surface;
     23 
     24 import java.util.Arrays;
     25 
     26 import libcore.util.Objects;
     27 
     28 /**
     29  * Describes the characteristics of a physical display device.
     30  */
     31 final class DisplayDeviceInfo {
     32     /**
     33      * Flag: Indicates that this display device should be considered the default display
     34      * device of the system.
     35      */
     36     public static final int FLAG_DEFAULT_DISPLAY = 1 << 0;
     37 
     38     /**
     39      * Flag: Indicates that the orientation of this display device is coupled to the
     40      * rotation of its associated logical display.
     41      * <p>
     42      * This flag should be applied to the default display to indicate that the user
     43      * physically rotates the display when content is presented in a different orientation.
     44      * The display manager will apply a coordinate transformation assuming that the
     45      * physical orientation of the display matches the logical orientation of its content.
     46      * </p><p>
     47      * The flag should not be set when the display device is mounted in a fixed orientation
     48      * such as on a desk.  The display manager will apply a coordinate transformation
     49      * such as a scale and translation to letterbox or pillarbox format under the
     50      * assumption that the physical orientation of the display is invariant.
     51      * </p>
     52      */
     53     public static final int FLAG_ROTATES_WITH_CONTENT = 1 << 1;
     54 
     55     /**
     56      * Flag: Indicates that this display device has secure video output, such as HDCP.
     57      */
     58     public static final int FLAG_SECURE = 1 << 2;
     59 
     60     /**
     61      * Flag: Indicates that this display device supports compositing
     62      * from gralloc protected buffers.
     63      */
     64     public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1 << 3;
     65 
     66     /**
     67      * Flag: Indicates that the display device is owned by a particular application
     68      * and that no other application should be able to interact with it.
     69      * Should typically be used together with {@link #FLAG_OWN_CONTENT_ONLY}.
     70      */
     71     public static final int FLAG_PRIVATE = 1 << 4;
     72 
     73     /**
     74      * Flag: Indicates that the display device is not blanked automatically by
     75      * the power manager.
     76      */
     77     public static final int FLAG_NEVER_BLANK = 1 << 5;
     78 
     79     /**
     80      * Flag: Indicates that the display is suitable for presentations.
     81      */
     82     public static final int FLAG_PRESENTATION = 1 << 6;
     83 
     84     /**
     85      * Flag: Only show this display's own content; do not mirror
     86      * the content of another display.
     87      */
     88     public static final int FLAG_OWN_CONTENT_ONLY = 1 << 7;
     89 
     90     /**
     91      * Flag: This display device has a round shape.
     92      */
     93     public static final int FLAG_ROUND = 1 << 8;
     94 
     95     /**
     96      * Flag: This display can show its content when non-secure keyguard is shown.
     97      */
     98     public static final int FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD = 1 << 9;
     99 
    100     /**
    101      * Flag: This display will destroy its content on removal.
    102      * @hide
    103      */
    104     public static final int FLAG_DESTROY_CONTENT_ON_REMOVAL = 1 << 10;
    105 
    106     /**
    107      * Touch attachment: Display does not receive touch.
    108      */
    109     public static final int TOUCH_NONE = 0;
    110 
    111     /**
    112      * Touch attachment: Touch input is via the internal interface.
    113      */
    114     public static final int TOUCH_INTERNAL = 1;
    115 
    116     /**
    117      * Touch attachment: Touch input is via an external interface, such as USB.
    118      */
    119     public static final int TOUCH_EXTERNAL = 2;
    120 
    121     /**
    122      * Touch attachment: Touch input is via an input device matching {@link VirtualDisplay}'s
    123      * uniqueId.
    124      * @hide
    125      */
    126     public static final int TOUCH_VIRTUAL = 3;
    127 
    128     /**
    129      * Diff result: The {@link #state} fields differ.
    130      */
    131     public static final int DIFF_STATE = 1 << 0;
    132 
    133     /**
    134      * Diff result: Other fields differ.
    135      */
    136     public static final int DIFF_OTHER = 1 << 1;
    137 
    138     /**
    139      * Diff result: The color mode fields differ.
    140      */
    141     public static final int DIFF_COLOR_MODE = 1 << 2;
    142 
    143     /**
    144      * Gets the name of the display device, which may be derived from EDID or
    145      * other sources. The name may be localized and displayed to the user.
    146      */
    147     public String name;
    148 
    149     /**
    150      * Unique Id of display device.
    151      */
    152     public String uniqueId;
    153 
    154     /**
    155      * The width of the display in its natural orientation, in pixels.
    156      * This value is not affected by display rotation.
    157      */
    158     public int width;
    159 
    160     /**
    161      * The height of the display in its natural orientation, in pixels.
    162      * This value is not affected by display rotation.
    163      */
    164     public int height;
    165 
    166     /**
    167      * The active mode of the display.
    168      */
    169     public int modeId;
    170 
    171     /**
    172      * The default mode of the display.
    173      */
    174     public int defaultModeId;
    175 
    176     /**
    177      * The supported modes of the display.
    178      */
    179     public Display.Mode[] supportedModes = Display.Mode.EMPTY_ARRAY;
    180 
    181     /** The active color mode of the display */
    182     public int colorMode;
    183 
    184     /** The supported color modes of the display */
    185     public int[] supportedColorModes = { Display.COLOR_MODE_DEFAULT };
    186 
    187     /**
    188      * The HDR capabilities this display claims to support.
    189      */
    190     public Display.HdrCapabilities hdrCapabilities;
    191 
    192     /**
    193      * The nominal apparent density of the display in DPI used for layout calculations.
    194      * This density is sensitive to the viewing distance.  A big TV and a tablet may have
    195      * the same apparent density even though the pixels on the TV are much bigger than
    196      * those on the tablet.
    197      */
    198     public int densityDpi;
    199 
    200     /**
    201      * The physical density of the display in DPI in the X direction.
    202      * This density should specify the physical size of each pixel.
    203      */
    204     public float xDpi;
    205 
    206     /**
    207      * The physical density of the display in DPI in the X direction.
    208      * This density should specify the physical size of each pixel.
    209      */
    210     public float yDpi;
    211 
    212     /**
    213      * This is a positive value indicating the phase offset of the VSYNC events provided by
    214      * Choreographer relative to the display refresh.  For example, if Choreographer reports
    215      * that the refresh occurred at time N, it actually occurred at (N - appVsyncOffsetNanos).
    216      */
    217     public long appVsyncOffsetNanos;
    218 
    219     /**
    220      * This is how far in advance a buffer must be queued for presentation at
    221      * a given time.  If you want a buffer to appear on the screen at
    222      * time N, you must submit the buffer before (N - bufferDeadlineNanos).
    223      */
    224     public long presentationDeadlineNanos;
    225 
    226     /**
    227      * Display flags.
    228      */
    229     public int flags;
    230 
    231     /**
    232      * The touch attachment, per {@link DisplayViewport#touch}.
    233      */
    234     public int touch;
    235 
    236     /**
    237      * The additional rotation to apply to all content presented on the display device
    238      * relative to its physical coordinate system.  Default is {@link Surface#ROTATION_0}.
    239      * <p>
    240      * This field can be used to compensate for the fact that the display has been
    241      * physically rotated relative to its natural orientation such as an HDMI monitor
    242      * that has been mounted sideways to appear to be portrait rather than landscape.
    243      * </p>
    244      */
    245     public int rotation = Surface.ROTATION_0;
    246 
    247     /**
    248      * Display type.
    249      */
    250     public int type;
    251 
    252     /**
    253      * Display address, or null if none.
    254      * Interpretation varies by display type.
    255      */
    256     public String address;
    257 
    258     /**
    259      * Display state.
    260      */
    261     public int state = Display.STATE_ON;
    262 
    263     /**
    264      * The UID of the application that owns this display, or zero if it is owned by the system.
    265      * <p>
    266      * If the display is private, then only the owner can use it.
    267      * </p>
    268      */
    269     public int ownerUid;
    270 
    271     /**
    272      * The package name of the application that owns this display, or null if it is
    273      * owned by the system.
    274      * <p>
    275      * If the display is private, then only the owner can use it.
    276      * </p>
    277      */
    278     public String ownerPackageName;
    279 
    280     public void setAssumedDensityForExternalDisplay(int width, int height) {
    281         densityDpi = Math.min(width, height) * DisplayMetrics.DENSITY_XHIGH / 1080;
    282         // Technically, these values should be smaller than the apparent density
    283         // but we don't know the physical size of the display.
    284         xDpi = densityDpi;
    285         yDpi = densityDpi;
    286     }
    287 
    288     @Override
    289     public boolean equals(Object o) {
    290         return o instanceof DisplayDeviceInfo && equals((DisplayDeviceInfo)o);
    291     }
    292 
    293     public boolean equals(DisplayDeviceInfo other) {
    294         return other != null && diff(other) == 0;
    295     }
    296 
    297     /**
    298      * Computes the difference between display device infos.
    299      * Assumes other is not null.
    300      */
    301     public int diff(DisplayDeviceInfo other) {
    302         int diff = 0;
    303         if (state != other.state) {
    304             diff |= DIFF_STATE;
    305         }
    306         if (colorMode != other.colorMode) {
    307             diff |= DIFF_COLOR_MODE;
    308         }
    309         if (!Objects.equal(name, other.name)
    310                 || !Objects.equal(uniqueId, other.uniqueId)
    311                 || width != other.width
    312                 || height != other.height
    313                 || modeId != other.modeId
    314                 || defaultModeId != other.defaultModeId
    315                 || !Arrays.equals(supportedModes, other.supportedModes)
    316                 || !Arrays.equals(supportedColorModes, other.supportedColorModes)
    317                 || !Objects.equal(hdrCapabilities, other.hdrCapabilities)
    318                 || densityDpi != other.densityDpi
    319                 || xDpi != other.xDpi
    320                 || yDpi != other.yDpi
    321                 || appVsyncOffsetNanos != other.appVsyncOffsetNanos
    322                 || presentationDeadlineNanos != other.presentationDeadlineNanos
    323                 || flags != other.flags
    324                 || touch != other.touch
    325                 || rotation != other.rotation
    326                 || type != other.type
    327                 || !Objects.equal(address, other.address)
    328                 || ownerUid != other.ownerUid
    329                 || !Objects.equal(ownerPackageName, other.ownerPackageName)) {
    330             diff |= DIFF_OTHER;
    331         }
    332         return diff;
    333     }
    334 
    335     @Override
    336     public int hashCode() {
    337         return 0; // don't care
    338     }
    339 
    340     public void copyFrom(DisplayDeviceInfo other) {
    341         name = other.name;
    342         uniqueId = other.uniqueId;
    343         width = other.width;
    344         height = other.height;
    345         modeId = other.modeId;
    346         defaultModeId = other.defaultModeId;
    347         supportedModes = other.supportedModes;
    348         colorMode = other.colorMode;
    349         supportedColorModes = other.supportedColorModes;
    350         hdrCapabilities = other.hdrCapabilities;
    351         densityDpi = other.densityDpi;
    352         xDpi = other.xDpi;
    353         yDpi = other.yDpi;
    354         appVsyncOffsetNanos = other.appVsyncOffsetNanos;
    355         presentationDeadlineNanos = other.presentationDeadlineNanos;
    356         flags = other.flags;
    357         touch = other.touch;
    358         rotation = other.rotation;
    359         type = other.type;
    360         address = other.address;
    361         state = other.state;
    362         ownerUid = other.ownerUid;
    363         ownerPackageName = other.ownerPackageName;
    364     }
    365 
    366     // For debugging purposes
    367     @Override
    368     public String toString() {
    369         StringBuilder sb = new StringBuilder();
    370         sb.append("DisplayDeviceInfo{\"");
    371         sb.append(name).append("\": uniqueId=\"").append(uniqueId).append("\", ");
    372         sb.append(width).append(" x ").append(height);
    373         sb.append(", modeId ").append(modeId);
    374         sb.append(", defaultModeId ").append(defaultModeId);
    375         sb.append(", supportedModes ").append(Arrays.toString(supportedModes));
    376         sb.append(", colorMode ").append(colorMode);
    377         sb.append(", supportedColorModes ").append(Arrays.toString(supportedColorModes));
    378         sb.append(", HdrCapabilities ").append(hdrCapabilities);
    379         sb.append(", density ").append(densityDpi);
    380         sb.append(", ").append(xDpi).append(" x ").append(yDpi).append(" dpi");
    381         sb.append(", appVsyncOff ").append(appVsyncOffsetNanos);
    382         sb.append(", presDeadline ").append(presentationDeadlineNanos);
    383         sb.append(", touch ").append(touchToString(touch));
    384         sb.append(", rotation ").append(rotation);
    385         sb.append(", type ").append(Display.typeToString(type));
    386         if (address != null) {
    387             sb.append(", address ").append(address);
    388         }
    389         sb.append(", state ").append(Display.stateToString(state));
    390         if (ownerUid != 0 || ownerPackageName != null) {
    391             sb.append(", owner ").append(ownerPackageName);
    392             sb.append(" (uid ").append(ownerUid).append(")");
    393         }
    394         sb.append(flagsToString(flags));
    395         sb.append("}");
    396         return sb.toString();
    397     }
    398 
    399     private static String touchToString(int touch) {
    400         switch (touch) {
    401             case TOUCH_NONE:
    402                 return "NONE";
    403             case TOUCH_INTERNAL:
    404                 return "INTERNAL";
    405             case TOUCH_EXTERNAL:
    406                 return "EXTERNAL";
    407             case TOUCH_VIRTUAL:
    408                 return "VIRTUAL";
    409             default:
    410                 return Integer.toString(touch);
    411         }
    412     }
    413 
    414     private static String flagsToString(int flags) {
    415         StringBuilder msg = new StringBuilder();
    416         if ((flags & FLAG_DEFAULT_DISPLAY) != 0) {
    417             msg.append(", FLAG_DEFAULT_DISPLAY");
    418         }
    419         if ((flags & FLAG_ROTATES_WITH_CONTENT) != 0) {
    420             msg.append(", FLAG_ROTATES_WITH_CONTENT");
    421         }
    422         if ((flags & FLAG_SECURE) != 0) {
    423             msg.append(", FLAG_SECURE");
    424         }
    425         if ((flags & FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
    426             msg.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS");
    427         }
    428         if ((flags & FLAG_PRIVATE) != 0) {
    429             msg.append(", FLAG_PRIVATE");
    430         }
    431         if ((flags & FLAG_NEVER_BLANK) != 0) {
    432             msg.append(", FLAG_NEVER_BLANK");
    433         }
    434         if ((flags & FLAG_PRESENTATION) != 0) {
    435             msg.append(", FLAG_PRESENTATION");
    436         }
    437         if ((flags & FLAG_OWN_CONTENT_ONLY) != 0) {
    438             msg.append(", FLAG_OWN_CONTENT_ONLY");
    439         }
    440         if ((flags & FLAG_ROUND) != 0) {
    441             msg.append(", FLAG_ROUND");
    442         }
    443         if ((flags & FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
    444             msg.append(", FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD");
    445         }
    446         return msg.toString();
    447     }
    448 }
    449