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