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