• 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_ALLOWED_TO_BE_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      * Flag: Indicates that the display should always be unlocked. Only valid on virtual displays
146      * that aren't in the default display group.
147      * @see #FLAG_OWN_DISPLAY_GROUP
148      * @hide
149      */
150     public static final int FLAG_ALWAYS_UNLOCKED = 1 << 15;
151 
152     /**
153      * Flag: Indicates that the display should not play sound effects or perform haptic feedback
154      * when the user touches the screen.
155      *
156      * @hide
157      */
158     public static final int FLAG_TOUCH_FEEDBACK_DISABLED = 1 << 16;
159 
160     /**
161      * Touch attachment: Display does not receive touch.
162      */
163     public static final int TOUCH_NONE = 0;
164 
165     /**
166      * Touch attachment: Touch input is via the internal interface.
167      */
168     public static final int TOUCH_INTERNAL = 1;
169 
170     /**
171      * Touch attachment: Touch input is via an external interface, such as USB.
172      */
173     public static final int TOUCH_EXTERNAL = 2;
174 
175     /**
176      * Touch attachment: Touch input is via an input device matching {@link VirtualDisplay}'s
177      * uniqueId.
178      * @hide
179      */
180     public static final int TOUCH_VIRTUAL = 3;
181 
182     /**
183      * Diff result: The {@link #state} or {@link #committedState} fields differ.
184      */
185     public static final int DIFF_STATE = 1 << 0;
186 
187     /**
188      * Diff result: Other fields differ.
189      */
190     public static final int DIFF_OTHER = 1 << 1;
191 
192     /**
193      * Diff result: The color mode fields differ.
194      */
195     public static final int DIFF_COLOR_MODE = 1 << 2;
196 
197     /**
198      * Gets the name of the display device, which may be derived from EDID or
199      * other sources. The name may be localized and displayed to the user.
200      */
201     public String name;
202 
203     /**
204      * Unique Id of display device.
205      */
206     public String uniqueId;
207 
208     /**
209      * The width of the display in its natural orientation, in pixels.
210      * This value is not affected by display rotation.
211      */
212     public int width;
213 
214     /**
215      * The height of the display in its natural orientation, in pixels.
216      * This value is not affected by display rotation.
217      */
218     public int height;
219 
220     /**
221      * The active mode of the display.
222      */
223     public int modeId;
224 
225     /**
226      * The default mode of the display.
227      */
228     public int defaultModeId;
229 
230     /**
231      * The supported modes of the display.
232      */
233     public Display.Mode[] supportedModes = Display.Mode.EMPTY_ARRAY;
234 
235     /** The active color mode of the display */
236     public int colorMode;
237 
238     /** The supported color modes of the display */
239     public int[] supportedColorModes = { Display.COLOR_MODE_DEFAULT };
240 
241     /**
242      * The HDR capabilities this display claims to support.
243      */
244     public Display.HdrCapabilities hdrCapabilities;
245 
246     /**
247      * Indicates whether this display supports Auto Low Latency Mode.
248      */
249     public boolean allmSupported;
250 
251     /**
252      * Indicates whether this display suppors Game content type.
253      */
254     public boolean gameContentTypeSupported;
255 
256     /**
257      * The nominal apparent density of the display in DPI used for layout calculations.
258      * This density is sensitive to the viewing distance.  A big TV and a tablet may have
259      * the same apparent density even though the pixels on the TV are much bigger than
260      * those on the tablet.
261      */
262     public int densityDpi;
263 
264     /**
265      * The physical density of the display in DPI in the X direction.
266      * This density should specify the physical size of each pixel.
267      */
268     public float xDpi;
269 
270     /**
271      * The physical density of the display in DPI in the X direction.
272      * This density should specify the physical size of each pixel.
273      */
274     public float yDpi;
275 
276     /**
277      * This is a positive value indicating the phase offset of the VSYNC events provided by
278      * Choreographer relative to the display refresh.  For example, if Choreographer reports
279      * that the refresh occurred at time N, it actually occurred at (N - appVsyncOffsetNanos).
280      */
281     public long appVsyncOffsetNanos;
282 
283     /**
284      * This is how far in advance a buffer must be queued for presentation at
285      * a given time.  If you want a buffer to appear on the screen at
286      * time N, you must submit the buffer before (N - bufferDeadlineNanos).
287      */
288     public long presentationDeadlineNanos;
289 
290     /**
291      * Display flags.
292      */
293     public int flags;
294 
295     /**
296      * The {@link DisplayCutout} if present or {@code null} otherwise.
297      */
298     public DisplayCutout displayCutout;
299 
300     /**
301      * The {@link RoundedCorners} if present or {@code null} otherwise.
302      */
303     public RoundedCorners roundedCorners;
304 
305     /**
306      * The touch attachment, per {@link DisplayViewport#touch}.
307      */
308     public int touch;
309 
310     /**
311      * The additional rotation to apply to all content presented on the display device
312      * relative to its physical coordinate system.  Default is {@link Surface#ROTATION_0}.
313      * <p>
314      * This field can be used to compensate for the fact that the display has been
315      * physically rotated relative to its natural orientation such as an HDMI monitor
316      * that has been mounted sideways to appear to be portrait rather than landscape.
317      * </p>
318      */
319     public int rotation = Surface.ROTATION_0;
320 
321     /**
322      * Display type.
323      */
324     public int type;
325 
326     /**
327      * Display address, or null if none.
328      * Interpretation varies by display type.
329      */
330     public DisplayAddress address;
331 
332     /**
333      * Product-specific information about the display or the directly connected device on the
334      * display chain. For example, if the display is transitively connected, this field may contain
335      * product information about the intermediate device.
336      */
337     public DeviceProductInfo deviceProductInfo;
338 
339     /**
340      * Display state.
341      */
342     public int state = Display.STATE_ON;
343 
344     /**
345      * Display committed state.
346      *
347      * This matches {@link DisplayDeviceInfo#state} only after the power state change finishes.
348      */
349     public int committedState = Display.STATE_UNKNOWN;
350 
351     /**
352      * The UID of the application that owns this display, or zero if it is owned by the system.
353      * <p>
354      * If the display is private, then only the owner can use it.
355      * </p>
356      */
357     public int ownerUid;
358 
359     /**
360      * The package name of the application that owns this display, or null if it is
361      * owned by the system.
362      * <p>
363      * If the display is private, then only the owner can use it.
364      * </p>
365      */
366     public String ownerPackageName;
367 
368     public DisplayEventReceiver.FrameRateOverride[] frameRateOverrides =
369             new DisplayEventReceiver.FrameRateOverride[0];
370 
371     public float brightnessMinimum;
372     public float brightnessMaximum;
373     public float brightnessDefault;
374 
375     /**
376      * Install orientation of display panel relative to its natural orientation.
377      */
378     @Surface.Rotation
379     public int installOrientation = Surface.ROTATION_0;
380 
setAssumedDensityForExternalDisplay(int width, int height)381     public void setAssumedDensityForExternalDisplay(int width, int height) {
382         densityDpi = Math.min(width, height) * DisplayMetrics.DENSITY_XHIGH / 1080;
383         // Technically, these values should be smaller than the apparent density
384         // but we don't know the physical size of the display.
385         xDpi = densityDpi;
386         yDpi = densityDpi;
387     }
388 
389     @Override
equals(Object o)390     public boolean equals(Object o) {
391         return o instanceof DisplayDeviceInfo && equals((DisplayDeviceInfo)o);
392     }
393 
equals(DisplayDeviceInfo other)394     public boolean equals(DisplayDeviceInfo other) {
395         return other != null && diff(other) == 0;
396     }
397 
398     /**
399      * Computes the difference between display device infos.
400      * Assumes other is not null.
401      */
diff(DisplayDeviceInfo other)402     public int diff(DisplayDeviceInfo other) {
403         int diff = 0;
404         if (state != other.state || committedState != other.committedState) {
405             diff |= DIFF_STATE;
406         }
407         if (colorMode != other.colorMode) {
408             diff |= DIFF_COLOR_MODE;
409         }
410         if (!Objects.equals(name, other.name)
411                 || !Objects.equals(uniqueId, other.uniqueId)
412                 || width != other.width
413                 || height != other.height
414                 || modeId != other.modeId
415                 || defaultModeId != other.defaultModeId
416                 || !Arrays.equals(supportedModes, other.supportedModes)
417                 || !Arrays.equals(supportedColorModes, other.supportedColorModes)
418                 || !Objects.equals(hdrCapabilities, other.hdrCapabilities)
419                 || allmSupported != other.allmSupported
420                 || gameContentTypeSupported != other.gameContentTypeSupported
421                 || densityDpi != other.densityDpi
422                 || xDpi != other.xDpi
423                 || yDpi != other.yDpi
424                 || appVsyncOffsetNanos != other.appVsyncOffsetNanos
425                 || presentationDeadlineNanos != other.presentationDeadlineNanos
426                 || flags != other.flags
427                 || !Objects.equals(displayCutout, other.displayCutout)
428                 || touch != other.touch
429                 || rotation != other.rotation
430                 || type != other.type
431                 || !Objects.equals(address, other.address)
432                 || !Objects.equals(deviceProductInfo, other.deviceProductInfo)
433                 || ownerUid != other.ownerUid
434                 || !Objects.equals(ownerPackageName, other.ownerPackageName)
435                 || !Arrays.equals(frameRateOverrides, other.frameRateOverrides)
436                 || !BrightnessSynchronizer.floatEquals(brightnessMinimum, other.brightnessMinimum)
437                 || !BrightnessSynchronizer.floatEquals(brightnessMaximum, other.brightnessMaximum)
438                 || !BrightnessSynchronizer.floatEquals(brightnessDefault,
439                 other.brightnessDefault)
440                 || !Objects.equals(roundedCorners, other.roundedCorners)
441                 || installOrientation != other.installOrientation) {
442             diff |= DIFF_OTHER;
443         }
444         return diff;
445     }
446 
447     @Override
hashCode()448     public int hashCode() {
449         return 0; // don't care
450     }
451 
copyFrom(DisplayDeviceInfo other)452     public void copyFrom(DisplayDeviceInfo other) {
453         name = other.name;
454         uniqueId = other.uniqueId;
455         width = other.width;
456         height = other.height;
457         modeId = other.modeId;
458         defaultModeId = other.defaultModeId;
459         supportedModes = other.supportedModes;
460         colorMode = other.colorMode;
461         supportedColorModes = other.supportedColorModes;
462         hdrCapabilities = other.hdrCapabilities;
463         allmSupported = other.allmSupported;
464         gameContentTypeSupported = other.gameContentTypeSupported;
465         densityDpi = other.densityDpi;
466         xDpi = other.xDpi;
467         yDpi = other.yDpi;
468         appVsyncOffsetNanos = other.appVsyncOffsetNanos;
469         presentationDeadlineNanos = other.presentationDeadlineNanos;
470         flags = other.flags;
471         displayCutout = other.displayCutout;
472         touch = other.touch;
473         rotation = other.rotation;
474         type = other.type;
475         address = other.address;
476         deviceProductInfo = other.deviceProductInfo;
477         state = other.state;
478         committedState = other.committedState;
479         ownerUid = other.ownerUid;
480         ownerPackageName = other.ownerPackageName;
481         frameRateOverrides = other.frameRateOverrides;
482         brightnessMinimum = other.brightnessMinimum;
483         brightnessMaximum = other.brightnessMaximum;
484         brightnessDefault = other.brightnessDefault;
485         roundedCorners = other.roundedCorners;
486         installOrientation = other.installOrientation;
487     }
488 
489     // For debugging purposes
490     @Override
toString()491     public String toString() {
492         StringBuilder sb = new StringBuilder();
493         sb.append("DisplayDeviceInfo{\"");
494         sb.append(name).append("\": uniqueId=\"").append(uniqueId).append("\", ");
495         sb.append(width).append(" x ").append(height);
496         sb.append(", modeId ").append(modeId);
497         sb.append(", defaultModeId ").append(defaultModeId);
498         sb.append(", supportedModes ").append(Arrays.toString(supportedModes));
499         sb.append(", colorMode ").append(colorMode);
500         sb.append(", supportedColorModes ").append(Arrays.toString(supportedColorModes));
501         sb.append(", hdrCapabilities ").append(hdrCapabilities);
502         sb.append(", allmSupported ").append(allmSupported);
503         sb.append(", gameContentTypeSupported ").append(gameContentTypeSupported);
504         sb.append(", density ").append(densityDpi);
505         sb.append(", ").append(xDpi).append(" x ").append(yDpi).append(" dpi");
506         sb.append(", appVsyncOff ").append(appVsyncOffsetNanos);
507         sb.append(", presDeadline ").append(presentationDeadlineNanos);
508         if (displayCutout != null) {
509             sb.append(", cutout ").append(displayCutout);
510         }
511         sb.append(", touch ").append(touchToString(touch));
512         sb.append(", rotation ").append(rotation);
513         sb.append(", type ").append(Display.typeToString(type));
514         if (address != null) {
515             sb.append(", address ").append(address);
516         }
517         sb.append(", deviceProductInfo ").append(deviceProductInfo);
518         sb.append(", state ").append(Display.stateToString(state));
519         sb.append(", committedState ").append(Display.stateToString(committedState));
520         if (ownerUid != 0 || ownerPackageName != null) {
521             sb.append(", owner ").append(ownerPackageName);
522             sb.append(" (uid ").append(ownerUid).append(")");
523         }
524         sb.append(", frameRateOverride ");
525         for (DisplayEventReceiver.FrameRateOverride frameRateOverride : frameRateOverrides) {
526             sb.append(frameRateOverride).append(" ");
527         }
528         sb.append(", brightnessMinimum ").append(brightnessMinimum);
529         sb.append(", brightnessMaximum ").append(brightnessMaximum);
530         sb.append(", brightnessDefault ").append(brightnessDefault);
531         if (roundedCorners != null) {
532             sb.append(", roundedCorners ").append(roundedCorners);
533         }
534         sb.append(flagsToString(flags));
535         sb.append(", installOrientation ").append(installOrientation);
536         sb.append("}");
537         return sb.toString();
538     }
539 
touchToString(int touch)540     private static String touchToString(int touch) {
541         switch (touch) {
542             case TOUCH_NONE:
543                 return "NONE";
544             case TOUCH_INTERNAL:
545                 return "INTERNAL";
546             case TOUCH_EXTERNAL:
547                 return "EXTERNAL";
548             case TOUCH_VIRTUAL:
549                 return "VIRTUAL";
550             default:
551                 return Integer.toString(touch);
552         }
553     }
554 
flagsToString(int flags)555     private static String flagsToString(int flags) {
556         StringBuilder msg = new StringBuilder();
557         if ((flags & FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY) != 0) {
558             msg.append(", FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY");
559         }
560         if ((flags & FLAG_ROTATES_WITH_CONTENT) != 0) {
561             msg.append(", FLAG_ROTATES_WITH_CONTENT");
562         }
563         if ((flags & FLAG_SECURE) != 0) {
564             msg.append(", FLAG_SECURE");
565         }
566         if ((flags & FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
567             msg.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS");
568         }
569         if ((flags & FLAG_PRIVATE) != 0) {
570             msg.append(", FLAG_PRIVATE");
571         }
572         if ((flags & FLAG_NEVER_BLANK) != 0) {
573             msg.append(", FLAG_NEVER_BLANK");
574         }
575         if ((flags & FLAG_PRESENTATION) != 0) {
576             msg.append(", FLAG_PRESENTATION");
577         }
578         if ((flags & FLAG_OWN_CONTENT_ONLY) != 0) {
579             msg.append(", FLAG_OWN_CONTENT_ONLY");
580         }
581         if ((flags & FLAG_ROUND) != 0) {
582             msg.append(", FLAG_ROUND");
583         }
584         if ((flags & FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
585             msg.append(", FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD");
586         }
587         if ((flags & FLAG_MASK_DISPLAY_CUTOUT) != 0) {
588             msg.append(", FLAG_MASK_DISPLAY_CUTOUT");
589         }
590         return msg.toString();
591     }
592 }
593