DisplayDeviceInfo.java revision 58e829f71d2c525309e5bb5a1c02dc64397df221
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 java.util.Arrays;
25
26import libcore.util.Objects;
27
28/**
29 * Describes the characteristics of a physical display device.
30 */
31final 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     * Touch attachment: Display does not receive touch.
97     */
98    public static final int TOUCH_NONE = 0;
99
100    /**
101     * Touch attachment: Touch input is via the internal interface.
102     */
103    public static final int TOUCH_INTERNAL = 1;
104
105    /**
106     * Touch attachment: Touch input is via an external interface, such as USB.
107     */
108    public static final int TOUCH_EXTERNAL = 2;
109
110    /**
111     * Diff result: The {@link #state} fields differ.
112     */
113    public static final int DIFF_STATE = 1 << 0;
114
115    /**
116     * Diff result: Other fields differ.
117     */
118    public static final int DIFF_OTHER = 1 << 1;
119
120    /**
121     * Gets the name of the display device, which may be derived from EDID or
122     * other sources. The name may be localized and displayed to the user.
123     */
124    public String name;
125
126    /**
127     * Unique Id of display device.
128     */
129    public String uniqueId;
130
131    /**
132     * The width of the display in its natural orientation, in pixels.
133     * This value is not affected by display rotation.
134     */
135    public int width;
136
137    /**
138     * The height of the display in its natural orientation, in pixels.
139     * This value is not affected by display rotation.
140     */
141    public int height;
142
143    /**
144     * The active mode of the display.
145     */
146    public int modeId;
147
148    /**
149     * The default mode of the display.
150     */
151    public int defaultModeId;
152
153    /**
154     * The supported modes of the display.
155     */
156    public Display.Mode[] supportedModes = Display.Mode.EMPTY_ARRAY;
157
158    /** The active color transform of the display */
159    public int colorTransformId;
160
161    /** The default color transform of the display */
162    public int defaultColorTransformId;
163
164    /** The supported color transforms of the display */
165    public Display.ColorTransform[] supportedColorTransforms = Display.ColorTransform.EMPTY_ARRAY;
166
167    /**
168     * The nominal apparent density of the display in DPI used for layout calculations.
169     * This density is sensitive to the viewing distance.  A big TV and a tablet may have
170     * the same apparent density even though the pixels on the TV are much bigger than
171     * those on the tablet.
172     */
173    public int densityDpi;
174
175    /**
176     * The physical density of the display in DPI in the X direction.
177     * This density should specify the physical size of each pixel.
178     */
179    public float xDpi;
180
181    /**
182     * The physical density of the display in DPI in the X direction.
183     * This density should specify the physical size of each pixel.
184     */
185    public float yDpi;
186
187    /**
188     * This is a positive value indicating the phase offset of the VSYNC events provided by
189     * Choreographer relative to the display refresh.  For example, if Choreographer reports
190     * that the refresh occurred at time N, it actually occurred at (N - appVsyncOffsetNanos).
191     */
192    public long appVsyncOffsetNanos;
193
194    /**
195     * This is how far in advance a buffer must be queued for presentation at
196     * a given time.  If you want a buffer to appear on the screen at
197     * time N, you must submit the buffer before (N - bufferDeadlineNanos).
198     */
199    public long presentationDeadlineNanos;
200
201    /**
202     * Display flags.
203     */
204    public int flags;
205
206    /**
207     * The touch attachment, per {@link DisplayViewport#touch}.
208     */
209    public int touch;
210
211    /**
212     * The additional rotation to apply to all content presented on the display device
213     * relative to its physical coordinate system.  Default is {@link Surface#ROTATION_0}.
214     * <p>
215     * This field can be used to compensate for the fact that the display has been
216     * physically rotated relative to its natural orientation such as an HDMI monitor
217     * that has been mounted sideways to appear to be portrait rather than landscape.
218     * </p>
219     */
220    public int rotation = Surface.ROTATION_0;
221
222    /**
223     * Display type.
224     */
225    public int type;
226
227    /**
228     * Display address, or null if none.
229     * Interpretation varies by display type.
230     */
231    public String address;
232
233    /**
234     * Display state.
235     */
236    public int state = Display.STATE_ON;
237
238    /**
239     * The UID of the application that owns this display, or zero if it is owned by the system.
240     * <p>
241     * If the display is private, then only the owner can use it.
242     * </p>
243     */
244    public int ownerUid;
245
246    /**
247     * The package name of the application that owns this display, or null if it is
248     * owned by the system.
249     * <p>
250     * If the display is private, then only the owner can use it.
251     * </p>
252     */
253    public String ownerPackageName;
254
255    public void setAssumedDensityForExternalDisplay(int width, int height) {
256        densityDpi = Math.min(width, height) * DisplayMetrics.DENSITY_XHIGH / 1080;
257        // Technically, these values should be smaller than the apparent density
258        // but we don't know the physical size of the display.
259        xDpi = densityDpi;
260        yDpi = densityDpi;
261    }
262
263    @Override
264    public boolean equals(Object o) {
265        return o instanceof DisplayDeviceInfo && equals((DisplayDeviceInfo)o);
266    }
267
268    public boolean equals(DisplayDeviceInfo other) {
269        return other != null && diff(other) == 0;
270    }
271
272    /**
273     * Computes the difference between display device infos.
274     * Assumes other is not null.
275     */
276    public int diff(DisplayDeviceInfo other) {
277        int diff = 0;
278        if (state != other.state) {
279            diff |= DIFF_STATE;
280        }
281        if (!Objects.equal(name, other.name)
282                || !Objects.equal(uniqueId, other.uniqueId)
283                || width != other.width
284                || height != other.height
285                || modeId != other.modeId
286                || defaultModeId != other.defaultModeId
287                || !Arrays.equals(supportedModes, other.supportedModes)
288                || colorTransformId != other.colorTransformId
289                || defaultColorTransformId != other.defaultColorTransformId
290                || !Arrays.equals(supportedColorTransforms, other.supportedColorTransforms)
291                || densityDpi != other.densityDpi
292                || xDpi != other.xDpi
293                || yDpi != other.yDpi
294                || appVsyncOffsetNanos != other.appVsyncOffsetNanos
295                || presentationDeadlineNanos != other.presentationDeadlineNanos
296                || flags != other.flags
297                || touch != other.touch
298                || rotation != other.rotation
299                || type != other.type
300                || !Objects.equal(address, other.address)
301                || ownerUid != other.ownerUid
302                || !Objects.equal(ownerPackageName, other.ownerPackageName)) {
303            diff |= DIFF_OTHER;
304        }
305        return diff;
306    }
307
308    @Override
309    public int hashCode() {
310        return 0; // don't care
311    }
312
313    public void copyFrom(DisplayDeviceInfo other) {
314        name = other.name;
315        uniqueId = other.uniqueId;
316        width = other.width;
317        height = other.height;
318        modeId = other.modeId;
319        defaultModeId = other.defaultModeId;
320        supportedModes = other.supportedModes;
321        colorTransformId = other.colorTransformId;
322        defaultColorTransformId = other.defaultColorTransformId;
323        supportedColorTransforms = other.supportedColorTransforms;
324        densityDpi = other.densityDpi;
325        xDpi = other.xDpi;
326        yDpi = other.yDpi;
327        appVsyncOffsetNanos = other.appVsyncOffsetNanos;
328        presentationDeadlineNanos = other.presentationDeadlineNanos;
329        flags = other.flags;
330        touch = other.touch;
331        rotation = other.rotation;
332        type = other.type;
333        address = other.address;
334        state = other.state;
335        ownerUid = other.ownerUid;
336        ownerPackageName = other.ownerPackageName;
337    }
338
339    // For debugging purposes
340    @Override
341    public String toString() {
342        StringBuilder sb = new StringBuilder();
343        sb.append("DisplayDeviceInfo{\"");
344        sb.append(name).append("\": uniqueId=\"").append(uniqueId).append("\", ");
345        sb.append(width).append(" x ").append(height);
346        sb.append(", modeId ").append(modeId);
347        sb.append(", defaultModeId ").append(defaultModeId);
348        sb.append(", supportedModes ").append(Arrays.toString(supportedModes));
349        sb.append(", colorTransformId ").append(colorTransformId);
350        sb.append(", defaultColorTransformId ").append(defaultColorTransformId);
351        sb.append(", supportedColorTransforms ").append(Arrays.toString(supportedColorTransforms));
352        sb.append(", density ").append(densityDpi);
353        sb.append(", ").append(xDpi).append(" x ").append(yDpi).append(" dpi");
354        sb.append(", appVsyncOff ").append(appVsyncOffsetNanos);
355        sb.append(", presDeadline ").append(presentationDeadlineNanos);
356        sb.append(", touch ").append(touchToString(touch));
357        sb.append(", rotation ").append(rotation);
358        sb.append(", type ").append(Display.typeToString(type));
359        if (address != null) {
360            sb.append(", address ").append(address);
361        }
362        sb.append(", state ").append(Display.stateToString(state));
363        if (ownerUid != 0 || ownerPackageName != null) {
364            sb.append(", owner ").append(ownerPackageName);
365            sb.append(" (uid ").append(ownerUid).append(")");
366        }
367        sb.append(flagsToString(flags));
368        sb.append("}");
369        return sb.toString();
370    }
371
372    private static String touchToString(int touch) {
373        switch (touch) {
374            case TOUCH_NONE:
375                return "NONE";
376            case TOUCH_INTERNAL:
377                return "INTERNAL";
378            case TOUCH_EXTERNAL:
379                return "EXTERNAL";
380            default:
381                return Integer.toString(touch);
382        }
383    }
384
385    private static String flagsToString(int flags) {
386        StringBuilder msg = new StringBuilder();
387        if ((flags & FLAG_DEFAULT_DISPLAY) != 0) {
388            msg.append(", FLAG_DEFAULT_DISPLAY");
389        }
390        if ((flags & FLAG_ROTATES_WITH_CONTENT) != 0) {
391            msg.append(", FLAG_ROTATES_WITH_CONTENT");
392        }
393        if ((flags & FLAG_SECURE) != 0) {
394            msg.append(", FLAG_SECURE");
395        }
396        if ((flags & FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
397            msg.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS");
398        }
399        if ((flags & FLAG_PRIVATE) != 0) {
400            msg.append(", FLAG_PRIVATE");
401        }
402        if ((flags & FLAG_NEVER_BLANK) != 0) {
403            msg.append(", FLAG_NEVER_BLANK");
404        }
405        if ((flags & FLAG_PRESENTATION) != 0) {
406            msg.append(", FLAG_PRESENTATION");
407        }
408        if ((flags & FLAG_OWN_CONTENT_ONLY) != 0) {
409            msg.append(", FLAG_OWN_CONTENT_ONLY");
410        }
411        if ((flags & FLAG_ROUND) != 0) {
412            msg.append(", FLAG_ROUND");
413        }
414        return msg.toString();
415    }
416}
417