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