DisplayDeviceInfo.java revision 3f145a2f958320766ae9240c7a57debc20d578aa
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
108     * EDID or other sources.  The name may be displayed to the user.
109     */
110    public String name;
111
112    /**
113     * The width of the display in its natural orientation, in pixels.
114     * This value is not affected by display rotation.
115     */
116    public int width;
117
118    /**
119     * The height of the display in its natural orientation, in pixels.
120     * This value is not affected by display rotation.
121     */
122    public int height;
123
124    /**
125     * The refresh rate of the display, in frames per second.
126     */
127    public float refreshRate;
128
129    /**
130     * The supported refresh rates of the display at the current resolution in frames per second.
131     */
132    public float[] supportedRefreshRates = EmptyArray.FLOAT;
133
134    /**
135     * The nominal apparent density of the display in DPI used for layout calculations.
136     * This density is sensitive to the viewing distance.  A big TV and a tablet may have
137     * the same apparent density even though the pixels on the TV are much bigger than
138     * those on the tablet.
139     */
140    public int densityDpi;
141
142    /**
143     * The physical density of the display in DPI in the X direction.
144     * This density should specify the physical size of each pixel.
145     */
146    public float xDpi;
147
148    /**
149     * The physical density of the display in DPI in the X direction.
150     * This density should specify the physical size of each pixel.
151     */
152    public float yDpi;
153
154    /**
155     * This is a positive value indicating the phase offset of the VSYNC events provided by
156     * Choreographer relative to the display refresh.  For example, if Choreographer reports
157     * that the refresh occurred at time N, it actually occurred at (N - appVsyncOffsetNanos).
158     */
159    public long appVsyncOffsetNanos;
160
161    /**
162     * This is how far in advance a buffer must be queued for presentation at
163     * a given time.  If you want a buffer to appear on the screen at
164     * time N, you must submit the buffer before (N - bufferDeadlineNanos).
165     */
166    public long presentationDeadlineNanos;
167
168    /**
169     * Display flags.
170     */
171    public int flags;
172
173    /**
174     * The touch attachment, per {@link DisplayViewport#touch}.
175     */
176    public int touch;
177
178    /**
179     * The additional rotation to apply to all content presented on the display device
180     * relative to its physical coordinate system.  Default is {@link Surface#ROTATION_0}.
181     * <p>
182     * This field can be used to compensate for the fact that the display has been
183     * physically rotated relative to its natural orientation such as an HDMI monitor
184     * that has been mounted sideways to appear to be portrait rather than landscape.
185     * </p>
186     */
187    public int rotation = Surface.ROTATION_0;
188
189    /**
190     * Display type.
191     */
192    public int type;
193
194    /**
195     * Display address, or null if none.
196     * Interpretation varies by display type.
197     */
198    public String address;
199
200    /**
201     * Display state.
202     */
203    public int state = Display.STATE_ON;
204
205    /**
206     * The UID of the application that owns this display, or zero if it is owned by the system.
207     * <p>
208     * If the display is private, then only the owner can use it.
209     * </p>
210     */
211    public int ownerUid;
212
213    /**
214     * The package name of the application that owns this display, or null if it is
215     * owned by the system.
216     * <p>
217     * If the display is private, then only the owner can use it.
218     * </p>
219     */
220    public String ownerPackageName;
221
222    public void setAssumedDensityForExternalDisplay(int width, int height) {
223        densityDpi = Math.min(width, height) * DisplayMetrics.DENSITY_XHIGH / 1080;
224        // Technically, these values should be smaller than the apparent density
225        // but we don't know the physical size of the display.
226        xDpi = densityDpi;
227        yDpi = densityDpi;
228    }
229
230    @Override
231    public boolean equals(Object o) {
232        return o instanceof DisplayDeviceInfo && equals((DisplayDeviceInfo)o);
233    }
234
235    public boolean equals(DisplayDeviceInfo other) {
236        return other != null
237                && Objects.equal(name, other.name)
238                && width == other.width
239                && height == other.height
240                && refreshRate == other.refreshRate
241                && Arrays.equals(supportedRefreshRates, other.supportedRefreshRates)
242                && densityDpi == other.densityDpi
243                && xDpi == other.xDpi
244                && yDpi == other.yDpi
245                && appVsyncOffsetNanos == other.appVsyncOffsetNanos
246                && presentationDeadlineNanos == other.presentationDeadlineNanos
247                && flags == other.flags
248                && touch == other.touch
249                && rotation == other.rotation
250                && type == other.type
251                && Objects.equal(address, other.address)
252                && state == other.state
253                && ownerUid == other.ownerUid
254                && Objects.equal(ownerPackageName, other.ownerPackageName);
255    }
256
257    @Override
258    public int hashCode() {
259        return 0; // don't care
260    }
261
262    public void copyFrom(DisplayDeviceInfo other) {
263        name = other.name;
264        width = other.width;
265        height = other.height;
266        refreshRate = other.refreshRate;
267        supportedRefreshRates = other.supportedRefreshRates;
268        densityDpi = other.densityDpi;
269        xDpi = other.xDpi;
270        yDpi = other.yDpi;
271        appVsyncOffsetNanos = other.appVsyncOffsetNanos;
272        presentationDeadlineNanos = other.presentationDeadlineNanos;
273        flags = other.flags;
274        touch = other.touch;
275        rotation = other.rotation;
276        type = other.type;
277        address = other.address;
278        state = other.state;
279        ownerUid = other.ownerUid;
280        ownerPackageName = other.ownerPackageName;
281    }
282
283    // For debugging purposes
284    @Override
285    public String toString() {
286        StringBuilder sb = new StringBuilder();
287        sb.append("DisplayDeviceInfo{\"");
288        sb.append(name).append("\": ").append(width).append(" x ").append(height);
289        sb.append(", ").append(refreshRate).append(" fps");
290        sb.append(", supportedRefreshRates ").append(Arrays.toString(supportedRefreshRates));
291        sb.append(", density ").append(densityDpi);
292        sb.append(", ").append(xDpi).append(" x ").append(yDpi).append(" dpi");
293        sb.append(", appVsyncOff ").append(appVsyncOffsetNanos);
294        sb.append(", presDeadline ").append(presentationDeadlineNanos);
295        sb.append(", touch ").append(touchToString(touch));
296        sb.append(", rotation ").append(rotation);
297        sb.append(", type ").append(Display.typeToString(type));
298        if (address != null) {
299            sb.append(", address ").append(address);
300        }
301        sb.append(", state ").append(Display.stateToString(state));
302        if (ownerUid != 0 || ownerPackageName != null) {
303            sb.append(", owner ").append(ownerPackageName);
304            sb.append(" (uid ").append(ownerUid).append(")");
305        }
306        sb.append(flagsToString(flags));
307        sb.append("}");
308        return sb.toString();
309    }
310
311    private static String touchToString(int touch) {
312        switch (touch) {
313            case TOUCH_NONE:
314                return "NONE";
315            case TOUCH_INTERNAL:
316                return "INTERNAL";
317            case TOUCH_EXTERNAL:
318                return "EXTERNAL";
319            default:
320                return Integer.toString(touch);
321        }
322    }
323
324    private static String flagsToString(int flags) {
325        StringBuilder msg = new StringBuilder();
326        if ((flags & FLAG_DEFAULT_DISPLAY) != 0) {
327            msg.append(", FLAG_DEFAULT_DISPLAY");
328        }
329        if ((flags & FLAG_ROTATES_WITH_CONTENT) != 0) {
330            msg.append(", FLAG_ROTATES_WITH_CONTENT");
331        }
332        if ((flags & FLAG_SECURE) != 0) {
333            msg.append(", FLAG_SECURE");
334        }
335        if ((flags & FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
336            msg.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS");
337        }
338        if ((flags & FLAG_PRIVATE) != 0) {
339            msg.append(", FLAG_PRIVATE");
340        }
341        if ((flags & FLAG_NEVER_BLANK) != 0) {
342            msg.append(", FLAG_NEVER_BLANK");
343        }
344        if ((flags & FLAG_PRESENTATION) != 0) {
345            msg.append(", FLAG_PRESENTATION");
346        }
347        if ((flags & FLAG_OWN_CONTENT_ONLY) != 0) {
348            msg.append(", FLAG_OWN_CONTENT_ONLY");
349        }
350        return msg.toString();
351    }
352}
353