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