DisplayDeviceInfo.java revision 9158825f9c41869689d6b1786d7c7aa8bdd524ce
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
17package com.android.server.display;
18
19import android.util.DisplayMetrics;
20import android.view.Display;
21import android.view.Surface;
22
23import libcore.util.Objects;
24
25/**
26 * Describes the characteristics of a physical display device.
27 */
28final 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