DisplayDeviceInfo.java revision 10acf6d3efde60977d2d2e82b90c53d722d9d357
189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project/*
289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Copyright (C) 2012 The Android Open Source Project
389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project *
489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5a64c8c79af1a15911c55306d83a797fa50969f77niko * you may not use this file except in compliance with the License.
6a64c8c79af1a15911c55306d83a797fa50969f77niko * You may obtain a copy of the License at
7a64c8c79af1a15911c55306d83a797fa50969f77niko *
8a64c8c79af1a15911c55306d83a797fa50969f77niko *      http://www.apache.org/licenses/LICENSE-2.0
9a64c8c79af1a15911c55306d83a797fa50969f77niko *
10a64c8c79af1a15911c55306d83a797fa50969f77niko * Unless required by applicable law or agreed to in writing, software
11a64c8c79af1a15911c55306d83a797fa50969f77niko * distributed under the License is distributed on an "AS IS" BASIS,
12a64c8c79af1a15911c55306d83a797fa50969f77niko * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a64c8c79af1a15911c55306d83a797fa50969f77niko * See the License for the specific language governing permissions and
14a64c8c79af1a15911c55306d83a797fa50969f77niko * limitations under the License.
15a64c8c79af1a15911c55306d83a797fa50969f77niko */
16a64c8c79af1a15911c55306d83a797fa50969f77niko
17a64c8c79af1a15911c55306d83a797fa50969f77nikopackage com.android.server.display;
18a64c8c79af1a15911c55306d83a797fa50969f77niko
19a64c8c79af1a15911c55306d83a797fa50969f77nikoimport android.hardware.display.DisplayViewport;
20a64c8c79af1a15911c55306d83a797fa50969f77nikoimport android.util.DisplayMetrics;
21a64c8c79af1a15911c55306d83a797fa50969f77nikoimport android.view.Display;
22a64c8c79af1a15911c55306d83a797fa50969f77nikoimport android.view.Surface;
23c2f1f07084818942352c6bbfb36af9b6b330eb4eEric Laurent
24413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huberimport java.util.Arrays;
25413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber
26413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huberimport libcore.util.EmptyArray;
27413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huberimport libcore.util.Objects;
28413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber
29413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber/**
30413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber * Describes the characteristics of a physical display device.
31413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber */
32413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huberfinal class DisplayDeviceInfo {
3389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    /**
3489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project     * Flag: Indicates that this display device should be considered the default display
35413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber     * device of the system.
3689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project     */
3789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    public static final int FLAG_DEFAULT_DISPLAY = 1 << 0;
3889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project
3989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    /**
402b50fba2b143c2e0597c941d67bea1b8e80c9cafMathias Agopian     * Flag: Indicates that the orientation of this display device is coupled to the
4189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project     * rotation of its associated logical display.
4289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project     * <p>
4389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project     * This flag should be applied to the default display to indicate that the user
4489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project     * physically rotates the display when content is presented in a different orientation.
4589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project     * The display manager will apply a coordinate transformation assuming that the
4689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project     * physical orientation of the display matches the logical orientation of its content.
4789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project     * </p><p>
4810dbb8e97e7a81ca4867663b5517f048820b3094Marco Nelissen     * The flag should not be set when the display device is mounted in a fixed orientation
4910dbb8e97e7a81ca4867663b5517f048820b3094Marco Nelissen     * such as on a desk.  The display manager will apply a coordinate transformation
5010dbb8e97e7a81ca4867663b5517f048820b3094Marco Nelissen     * such as a scale and translation to letterbox or pillarbox format under the
5110dbb8e97e7a81ca4867663b5517f048820b3094Marco Nelissen     * assumption that the physical orientation of the display is invariant.
52413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber     * </p>
53413f523afe96aff02d2b0a7459127b8f67b2b43cAndreas Huber     */
5410dbb8e97e7a81ca4867663b5517f048820b3094Marco Nelissen    public static final int FLAG_ROTATES_WITH_CONTENT = 1 << 1;
5510dbb8e97e7a81ca4867663b5517f048820b3094Marco Nelissen
5689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project    /**
5789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project     * 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     * Diff result: The {@link #state} fields differ.
108     */
109    public static final int DIFF_STATE = 1 << 0;
110
111    /**
112     * Diff result: Other fields differ.
113     */
114    public static final int DIFF_OTHER = 1 << 1;
115
116    /**
117     * Gets the name of the display device, which may be derived from EDID or
118     * other sources. The name may be localized and displayed to the user.
119     */
120    public String name;
121
122    /**
123     * Unique Id of display device.
124     */
125    public String uniqueId;
126
127    /**
128     * The width of the display in its natural orientation, in pixels.
129     * This value is not affected by display rotation.
130     */
131    public int width;
132
133    /**
134     * The height of the display in its natural orientation, in pixels.
135     * This value is not affected by display rotation.
136     */
137    public int height;
138
139    /**
140     * The refresh rate of the display, in frames per second.
141     */
142    public float refreshRate;
143
144    /**
145     * The supported refresh rates of the display at the current resolution in frames per second.
146     */
147    public float[] supportedRefreshRates = EmptyArray.FLOAT;
148
149    /**
150     * The nominal apparent density of the display in DPI used for layout calculations.
151     * This density is sensitive to the viewing distance.  A big TV and a tablet may have
152     * the same apparent density even though the pixels on the TV are much bigger than
153     * those on the tablet.
154     */
155    public int densityDpi;
156
157    /**
158     * The physical density of the display in DPI in the X direction.
159     * This density should specify the physical size of each pixel.
160     */
161    public float xDpi;
162
163    /**
164     * The physical density of the display in DPI in the X direction.
165     * This density should specify the physical size of each pixel.
166     */
167    public float yDpi;
168
169    /**
170     * This is a positive value indicating the phase offset of the VSYNC events provided by
171     * Choreographer relative to the display refresh.  For example, if Choreographer reports
172     * that the refresh occurred at time N, it actually occurred at (N - appVsyncOffsetNanos).
173     */
174    public long appVsyncOffsetNanos;
175
176    /**
177     * This is how far in advance a buffer must be queued for presentation at
178     * a given time.  If you want a buffer to appear on the screen at
179     * time N, you must submit the buffer before (N - bufferDeadlineNanos).
180     */
181    public long presentationDeadlineNanos;
182
183    /**
184     * Display flags.
185     */
186    public int flags;
187
188    /**
189     * The touch attachment, per {@link DisplayViewport#touch}.
190     */
191    public int touch;
192
193    /**
194     * The additional rotation to apply to all content presented on the display device
195     * relative to its physical coordinate system.  Default is {@link Surface#ROTATION_0}.
196     * <p>
197     * This field can be used to compensate for the fact that the display has been
198     * physically rotated relative to its natural orientation such as an HDMI monitor
199     * that has been mounted sideways to appear to be portrait rather than landscape.
200     * </p>
201     */
202    public int rotation = Surface.ROTATION_0;
203
204    /**
205     * Display type.
206     */
207    public int type;
208
209    /**
210     * Display address, or null if none.
211     * Interpretation varies by display type.
212     */
213    public String address;
214
215    /**
216     * Display state.
217     */
218    public int state = Display.STATE_ON;
219
220    /**
221     * The UID of the application that owns this display, or zero if it is owned by the system.
222     * <p>
223     * If the display is private, then only the owner can use it.
224     * </p>
225     */
226    public int ownerUid;
227
228    /**
229     * The package name of the application that owns this display, or null if it is
230     * owned by the system.
231     * <p>
232     * If the display is private, then only the owner can use it.
233     * </p>
234     */
235    public String ownerPackageName;
236
237    public void setAssumedDensityForExternalDisplay(int width, int height) {
238        densityDpi = Math.min(width, height) * DisplayMetrics.DENSITY_XHIGH / 1080;
239        // Technically, these values should be smaller than the apparent density
240        // but we don't know the physical size of the display.
241        xDpi = densityDpi;
242        yDpi = densityDpi;
243    }
244
245    @Override
246    public boolean equals(Object o) {
247        return o instanceof DisplayDeviceInfo && equals((DisplayDeviceInfo)o);
248    }
249
250    public boolean equals(DisplayDeviceInfo other) {
251        return other != null && diff(other) == 0;
252    }
253
254    /**
255     * Computes the difference between display device infos.
256     * Assumes other is not null.
257     */
258    public int diff(DisplayDeviceInfo other) {
259        int diff = 0;
260        if (state != other.state) {
261            diff |= DIFF_STATE;
262        }
263        if (!Objects.equal(name, other.name)
264                || !Objects.equal(uniqueId, other.uniqueId)
265                || width != other.width
266                || height != other.height
267                || refreshRate != other.refreshRate
268                || !Arrays.equals(supportedRefreshRates, other.supportedRefreshRates)
269                || densityDpi != other.densityDpi
270                || xDpi != other.xDpi
271                || yDpi != other.yDpi
272                || appVsyncOffsetNanos != other.appVsyncOffsetNanos
273                || presentationDeadlineNanos != other.presentationDeadlineNanos
274                || flags != other.flags
275                || touch != other.touch
276                || rotation != other.rotation
277                || type != other.type
278                || !Objects.equal(address, other.address)
279                || ownerUid != other.ownerUid
280                || !Objects.equal(ownerPackageName, other.ownerPackageName)) {
281            diff |= DIFF_OTHER;
282        }
283        return diff;
284    }
285
286    @Override
287    public int hashCode() {
288        return 0; // don't care
289    }
290
291    public void copyFrom(DisplayDeviceInfo other) {
292        name = other.name;
293        uniqueId = other.uniqueId;
294        width = other.width;
295        height = other.height;
296        refreshRate = other.refreshRate;
297        supportedRefreshRates = other.supportedRefreshRates;
298        densityDpi = other.densityDpi;
299        xDpi = other.xDpi;
300        yDpi = other.yDpi;
301        appVsyncOffsetNanos = other.appVsyncOffsetNanos;
302        presentationDeadlineNanos = other.presentationDeadlineNanos;
303        flags = other.flags;
304        touch = other.touch;
305        rotation = other.rotation;
306        type = other.type;
307        address = other.address;
308        state = other.state;
309        ownerUid = other.ownerUid;
310        ownerPackageName = other.ownerPackageName;
311    }
312
313    // For debugging purposes
314    @Override
315    public String toString() {
316        StringBuilder sb = new StringBuilder();
317        sb.append("DisplayDeviceInfo{\"");
318        sb.append(name).append("\": uniqueId=\"").append(uniqueId).append("\", ");
319        sb.append(width).append(" x ").append(height);
320        sb.append(", ").append(refreshRate).append(" fps");
321        sb.append(", supportedRefreshRates ").append(Arrays.toString(supportedRefreshRates));
322        sb.append(", density ").append(densityDpi);
323        sb.append(", ").append(xDpi).append(" x ").append(yDpi).append(" dpi");
324        sb.append(", appVsyncOff ").append(appVsyncOffsetNanos);
325        sb.append(", presDeadline ").append(presentationDeadlineNanos);
326        sb.append(", touch ").append(touchToString(touch));
327        sb.append(", rotation ").append(rotation);
328        sb.append(", type ").append(Display.typeToString(type));
329        if (address != null) {
330            sb.append(", address ").append(address);
331        }
332        sb.append(", state ").append(Display.stateToString(state));
333        if (ownerUid != 0 || ownerPackageName != null) {
334            sb.append(", owner ").append(ownerPackageName);
335            sb.append(" (uid ").append(ownerUid).append(")");
336        }
337        sb.append(flagsToString(flags));
338        sb.append("}");
339        return sb.toString();
340    }
341
342    private static String touchToString(int touch) {
343        switch (touch) {
344            case TOUCH_NONE:
345                return "NONE";
346            case TOUCH_INTERNAL:
347                return "INTERNAL";
348            case TOUCH_EXTERNAL:
349                return "EXTERNAL";
350            default:
351                return Integer.toString(touch);
352        }
353    }
354
355    private static String flagsToString(int flags) {
356        StringBuilder msg = new StringBuilder();
357        if ((flags & FLAG_DEFAULT_DISPLAY) != 0) {
358            msg.append(", FLAG_DEFAULT_DISPLAY");
359        }
360        if ((flags & FLAG_ROTATES_WITH_CONTENT) != 0) {
361            msg.append(", FLAG_ROTATES_WITH_CONTENT");
362        }
363        if ((flags & FLAG_SECURE) != 0) {
364            msg.append(", FLAG_SECURE");
365        }
366        if ((flags & FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
367            msg.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS");
368        }
369        if ((flags & FLAG_PRIVATE) != 0) {
370            msg.append(", FLAG_PRIVATE");
371        }
372        if ((flags & FLAG_NEVER_BLANK) != 0) {
373            msg.append(", FLAG_NEVER_BLANK");
374        }
375        if ((flags & FLAG_PRESENTATION) != 0) {
376            msg.append(", FLAG_PRESENTATION");
377        }
378        if ((flags & FLAG_OWN_CONTENT_ONLY) != 0) {
379            msg.append(", FLAG_OWN_CONTENT_ONLY");
380        }
381        return msg.toString();
382    }
383}
384