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