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 static android.view.Display.Mode.INVALID_MODE_ID;
20 
21 import android.hardware.display.DeviceProductInfo;
22 import android.hardware.display.DisplayViewport;
23 import android.util.DisplayMetrics;
24 import android.view.Display;
25 import android.view.DisplayAddress;
26 import android.view.DisplayCutout;
27 import android.view.DisplayEventReceiver;
28 import android.view.DisplayShape;
29 import android.view.RoundedCorners;
30 import android.view.Surface;
31 
32 import com.android.internal.display.BrightnessSynchronizer;
33 
34 import java.util.Arrays;
35 import java.util.Objects;
36 
37 /**
38  * Describes the characteristics of a physical display device.
39  */
40 final class DisplayDeviceInfo {
41     /**
42      * Flag: Indicates that this display device should be considered the default display
43      * device of the system.
44      */
45     public static final int FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY = 1 << 0;
46 
47     /**
48      * Flag: Indicates that the orientation of this display device is coupled to the
49      * rotation of its associated logical display.
50      * <p>
51      * This flag should be applied to the default display to indicate that the user
52      * physically rotates the display when content is presented in a different orientation.
53      * The display manager will apply a coordinate transformation assuming that the
54      * physical orientation of the display matches the logical orientation of its content.
55      * </p><p>
56      * The flag should not be set when the display device is mounted in a fixed orientation
57      * such as on a desk.  The display manager will apply a coordinate transformation
58      * such as a scale and translation to letterbox or pillarbox format under the
59      * assumption that the physical orientation of the display is invariant.
60      * </p>
61      */
62     public static final int FLAG_ROTATES_WITH_CONTENT = 1 << 1;
63 
64     /**
65      * Flag: Indicates that this display device has secure video output, such as HDCP.
66      */
67     public static final int FLAG_SECURE = 1 << 2;
68 
69     /**
70      * Flag: Indicates that this display device supports compositing
71      * from gralloc protected buffers.
72      */
73     public static final int FLAG_SUPPORTS_PROTECTED_BUFFERS = 1 << 3;
74 
75     /**
76      * Flag: Indicates that the display device is owned by a particular application
77      * and that no other application should be able to interact with it.
78      * Should typically be used together with {@link #FLAG_OWN_CONTENT_ONLY}.
79      */
80     public static final int FLAG_PRIVATE = 1 << 4;
81 
82     /**
83      * Flag: Indicates that the display device is not blanked automatically by
84      * the power manager.
85      */
86     public static final int FLAG_NEVER_BLANK = 1 << 5;
87 
88     /**
89      * Flag: Indicates that the display is suitable for presentations.
90      */
91     public static final int FLAG_PRESENTATION = 1 << 6;
92 
93     /**
94      * Flag: Only show this display's own content; do not mirror
95      * the content of another display.
96      */
97     public static final int FLAG_OWN_CONTENT_ONLY = 1 << 7;
98 
99     /**
100      * Flag: This display device has a round shape.
101      */
102     public static final int FLAG_ROUND = 1 << 8;
103 
104     /**
105      * Flag: This display can show its content when non-secure keyguard is shown.
106      */
107     // TODO (b/114338689): Remove the flag and use IWindowManager#shouldShowWithInsecureKeyguard
108     public static final int FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD = 1 << 9;
109 
110     /**
111      * Flag: This display will destroy its content on removal.
112      * @hide
113      */
114     // TODO (b/114338689): Remove the flag and use WindowManager#REMOVE_CONTENT_MODE_DESTROY
115     public static final int FLAG_DESTROY_CONTENT_ON_REMOVAL = 1 << 10;
116 
117     /**
118      * Flag: The display cutout of this display is masked.
119      * @hide
120      */
121     public static final int FLAG_MASK_DISPLAY_CUTOUT = 1 << 11;
122 
123     /**
124      * Flag: This flag identifies secondary displays that should show system decorations, such as
125      * navigation bar, home activity or wallpaper.
126      * <p>Note that this flag doesn't work without {@link #FLAG_TRUSTED}</p>
127      * @hide
128      */
129     public static final int FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS = 1 << 12;
130 
131     /**
132      * Flag: The display is trusted to show system decorations and receive inputs without users'
133      * touch.
134      * @see #FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS
135      */
136     public static final int FLAG_TRUSTED = 1 << 13;
137 
138     /**
139      * Flag: Indicates that the display should not be a part of the default {@link DisplayGroup} and
140      * instead be part of a new {@link DisplayGroup}.
141      *
142      * @hide
143      */
144     public static final int FLAG_OWN_DISPLAY_GROUP = 1 << 14;
145 
146     /**
147      * Flag: Indicates that the display should always be unlocked. Only valid on virtual displays
148      * that aren't in the default display group.
149      * @see #FLAG_OWN_DISPLAY_GROUP and #FLAG_DEVICE_DISPLAY_GROUP
150      * @hide
151      */
152     public static final int FLAG_ALWAYS_UNLOCKED = 1 << 15;
153 
154     /**
155      * Flag: Indicates that the display should not play sound effects or perform haptic feedback
156      * when the user touches the screen.
157      *
158      * @hide
159      */
160     public static final int FLAG_TOUCH_FEEDBACK_DISABLED = 1 << 16;
161 
162     /**
163      * Flag: Indicates that the display maintains its own focus and touch mode.
164      *
165      * This flag is similar to {@link com.android.internal.R.bool.config_perDisplayFocusEnabled} in
166      * behavior, but only applies to the specific display instead of system-wide to all displays.
167      *
168      * Note: The display must be trusted in order to have its own focus.
169      *
170      * @see #FLAG_TRUSTED
171      * @hide
172      */
173     public static final int FLAG_OWN_FOCUS = 1 << 17;
174 
175     /**
176      * Flag: indicates that the display should not be a part of the default {@link DisplayGroup} and
177      * instead be part of a {@link DisplayGroup} associated with the Virtual Device.
178      *
179      * @hide
180      */
181     public static final int FLAG_DEVICE_DISPLAY_GROUP = 1 << 18;
182 
183     /**
184      * Flag: Indicates that the display should not become the top focused display by stealing the
185      * top focus from another display.
186      *
187      * @see Display#FLAG_STEAL_TOP_FOCUS_DISABLED
188      * @hide
189      */
190     public static final int FLAG_STEAL_TOP_FOCUS_DISABLED = 1 << 19;
191 
192     /**
193      * Touch attachment: Display does not receive touch.
194      */
195     public static final int TOUCH_NONE = 0;
196 
197     /**
198      * Touch attachment: Touch input is via the internal interface.
199      */
200     public static final int TOUCH_INTERNAL = 1;
201 
202     /**
203      * Touch attachment: Touch input is via an external interface, such as USB.
204      */
205     public static final int TOUCH_EXTERNAL = 2;
206 
207     /**
208      * Touch attachment: Touch input is via an input device matching {@link VirtualDisplay}'s
209      * uniqueId.
210      * @hide
211      */
212     public static final int TOUCH_VIRTUAL = 3;
213 
214     /**
215      * Diff result: Other fields differ.
216      */
217     public static final int DIFF_OTHER = 1 << 0;
218 
219     /**
220      * Diff result: The {@link #state} or {@link #committedState} fields differ.
221      */
222     public static final int DIFF_STATE = 1 << 1;
223 
224     /**
225      * Diff result: The committed state differs. Note this is slightly different from the state,
226      * which is what most of the device should care about.
227      */
228     public static final int DIFF_COMMITTED_STATE = 1 << 2;
229 
230     /**
231      * Diff result: The color mode fields differ.
232      */
233     public static final int DIFF_COLOR_MODE = 1 << 3;
234 
235     /**
236      * Diff result: The hdr/sdr ratio differs
237      */
238     public static final int DIFF_HDR_SDR_RATIO = 1 << 4;
239 
240     /**
241      * Diff result: The rotation differs
242      */
243     public static final int DIFF_ROTATION = 1 << 5;
244 
245     /**
246      * Diff result: The render timings. Note this could be any of {@link #renderFrameRate},
247      * {@link #presentationDeadlineNanos}, or {@link #appVsyncOffsetNanos}.
248      */
249     public static final int DIFF_RENDER_TIMINGS = 1 << 6;
250 
251     /**
252      * Diff result: The mode ID differs.
253      */
254     public static final int DIFF_MODE_ID = 1 << 7;
255 
256     /**
257      * Diff result: Catch-all for "everything changed"
258      */
259     public static final int DIFF_EVERYTHING = 0XFFFFFFFF;
260 
261     /**
262      * Gets the name of the display device, which may be derived from EDID or
263      * other sources. The name may be localized and displayed to the user.
264      */
265     public String name;
266 
267     /**
268      * Unique Id of display device.
269      */
270     public String uniqueId;
271 
272     /**
273      * The width of the display in its natural orientation, in pixels.
274      * This value is not affected by display rotation.
275      */
276     public int width;
277 
278     /**
279      * The height of the display in its natural orientation, in pixels.
280      * This value is not affected by display rotation.
281      */
282     public int height;
283 
284     /**
285      * The active mode of the display.
286      */
287     public int modeId;
288 
289     /**
290      * The render frame rate this display is scheduled at.
291      * @see android.view.DisplayInfo#renderFrameRate for more details.
292      */
293     public float renderFrameRate;
294 
295     /**
296      * The default mode of the display.
297      */
298     public int defaultModeId;
299 
300     /**
301      * The mode of the display which is preferred by user.
302      */
303     public int userPreferredModeId = INVALID_MODE_ID;
304 
305     /**
306      * The supported modes of the display.
307      */
308     public Display.Mode[] supportedModes = Display.Mode.EMPTY_ARRAY;
309 
310     /** The active color mode of the display */
311     public int colorMode;
312 
313     /** The supported color modes of the display */
314     public int[] supportedColorModes = { Display.COLOR_MODE_DEFAULT };
315 
316     /**
317      * The HDR capabilities this display claims to support.
318      */
319     public Display.HdrCapabilities hdrCapabilities;
320 
321     /**
322      * Indicates whether this display supports Auto Low Latency Mode.
323      */
324     public boolean allmSupported;
325 
326     /**
327      * Indicates whether this display suppors Game content type.
328      */
329     public boolean gameContentTypeSupported;
330 
331     /**
332      * The nominal apparent density of the display in DPI used for layout calculations.
333      * This density is sensitive to the viewing distance.  A big TV and a tablet may have
334      * the same apparent density even though the pixels on the TV are much bigger than
335      * those on the tablet.
336      */
337     public int densityDpi;
338 
339     /**
340      * The physical density of the display in DPI in the X direction.
341      * This density should specify the physical size of each pixel.
342      */
343     public float xDpi;
344 
345     /**
346      * The physical density of the display in DPI in the X direction.
347      * This density should specify the physical size of each pixel.
348      */
349     public float yDpi;
350 
351     /**
352      * This is a positive value indicating the phase offset of the VSYNC events provided by
353      * Choreographer relative to the display refresh.  For example, if Choreographer reports
354      * that the refresh occurred at time N, it actually occurred at (N - appVsyncOffsetNanos).
355      */
356     public long appVsyncOffsetNanos;
357 
358     /**
359      * This is how far in advance a buffer must be queued for presentation at
360      * a given time.  If you want a buffer to appear on the screen at
361      * time N, you must submit the buffer before (N - bufferDeadlineNanos).
362      */
363     public long presentationDeadlineNanos;
364 
365     /**
366      * Display flags.
367      */
368     public int flags;
369 
370     /**
371      * The {@link DisplayCutout} if present or {@code null} otherwise.
372      */
373     public DisplayCutout displayCutout;
374 
375     /**
376      * The {@link RoundedCorners} if present or {@code null} otherwise.
377      */
378     public RoundedCorners roundedCorners;
379 
380     /**
381      * The {@link RoundedCorners} if present or {@code null} otherwise.
382      */
383     public DisplayShape displayShape;
384 
385     /**
386      * The touch attachment, per {@link DisplayViewport#touch}.
387      */
388     public int touch;
389 
390     /**
391      * The additional rotation to apply to all content presented on the display device
392      * relative to its physical coordinate system.  Default is {@link Surface#ROTATION_0}.
393      * <p>
394      * This field can be used to compensate for the fact that the display has been
395      * physically rotated relative to its natural orientation such as an HDMI monitor
396      * that has been mounted sideways to appear to be portrait rather than landscape.
397      * </p>
398      */
399     public int rotation = Surface.ROTATION_0;
400 
401     /**
402      * Display type.
403      */
404     public int type;
405 
406     /**
407      * Display address, or null if none.
408      * Interpretation varies by display type.
409      */
410     public DisplayAddress address;
411 
412     /**
413      * Product-specific information about the display or the directly connected device on the
414      * display chain. For example, if the display is transitively connected, this field may contain
415      * product information about the intermediate device.
416      */
417     public DeviceProductInfo deviceProductInfo;
418 
419     /**
420      * Display state.
421      */
422     public int state = Display.STATE_ON;
423 
424     /**
425      * Display committed state.
426      *
427      * This matches {@link DisplayDeviceInfo#state} only after the power state change finishes.
428      */
429     public int committedState = Display.STATE_UNKNOWN;
430 
431     /**
432      * The UID of the application that owns this display, or zero if it is owned by the system.
433      * <p>
434      * If the display is private, then only the owner can use it.
435      * </p>
436      */
437     public int ownerUid;
438 
439     /**
440      * The package name of the application that owns this display, or null if it is
441      * owned by the system.
442      * <p>
443      * If the display is private, then only the owner can use it.
444      * </p>
445      */
446     public String ownerPackageName;
447 
448     public DisplayEventReceiver.FrameRateOverride[] frameRateOverrides =
449             new DisplayEventReceiver.FrameRateOverride[0];
450 
451     public float brightnessMinimum;
452     public float brightnessMaximum;
453     public float brightnessDefault;
454 
455     // NaN means unsupported
456     public float hdrSdrRatio = Float.NaN;
457 
458     /**
459      * Install orientation of display panel relative to its natural orientation.
460      */
461     @Surface.Rotation
462     public int installOrientation = Surface.ROTATION_0;
463 
setAssumedDensityForExternalDisplay(int width, int height)464     public void setAssumedDensityForExternalDisplay(int width, int height) {
465         densityDpi = Math.min(width, height) * DisplayMetrics.DENSITY_XHIGH / 1080;
466         // Technically, these values should be smaller than the apparent density
467         // but we don't know the physical size of the display.
468         xDpi = densityDpi;
469         yDpi = densityDpi;
470     }
471 
472     @Override
equals(Object o)473     public boolean equals(Object o) {
474         return o instanceof DisplayDeviceInfo && equals((DisplayDeviceInfo)o);
475     }
476 
equals(DisplayDeviceInfo other)477     public boolean equals(DisplayDeviceInfo other) {
478         return other != null && diff(other) == 0;
479     }
480 
481     /**
482      * Computes the difference between display device infos.
483      * Assumes other is not null.
484      */
diff(DisplayDeviceInfo other)485     public int diff(DisplayDeviceInfo other) {
486         int diff = 0;
487         if (state != other.state) {
488             diff |= DIFF_STATE;
489         }
490         if (committedState != other.committedState) {
491             diff |= DIFF_COMMITTED_STATE;
492         }
493         if (colorMode != other.colorMode) {
494             diff |= DIFF_COLOR_MODE;
495         }
496         if (!BrightnessSynchronizer.floatEquals(hdrSdrRatio, other.hdrSdrRatio)) {
497             diff |= DIFF_HDR_SDR_RATIO;
498         }
499         if (rotation != other.rotation) {
500             diff |= DIFF_ROTATION;
501         }
502         if (renderFrameRate != other.renderFrameRate
503                 || presentationDeadlineNanos != other.presentationDeadlineNanos
504                 || appVsyncOffsetNanos != other.appVsyncOffsetNanos) {
505             diff |= DIFF_RENDER_TIMINGS;
506         }
507         if (modeId != other.modeId) {
508             diff |= DIFF_MODE_ID;
509         }
510         if (!Objects.equals(name, other.name)
511                 || !Objects.equals(uniqueId, other.uniqueId)
512                 || width != other.width
513                 || height != other.height
514                 || defaultModeId != other.defaultModeId
515                 || userPreferredModeId != other.userPreferredModeId
516                 || !Arrays.equals(supportedModes, other.supportedModes)
517                 || !Arrays.equals(supportedColorModes, other.supportedColorModes)
518                 || !Objects.equals(hdrCapabilities, other.hdrCapabilities)
519                 || allmSupported != other.allmSupported
520                 || gameContentTypeSupported != other.gameContentTypeSupported
521                 || densityDpi != other.densityDpi
522                 || xDpi != other.xDpi
523                 || yDpi != other.yDpi
524                 || flags != other.flags
525                 || !Objects.equals(displayCutout, other.displayCutout)
526                 || touch != other.touch
527                 || type != other.type
528                 || !Objects.equals(address, other.address)
529                 || !Objects.equals(deviceProductInfo, other.deviceProductInfo)
530                 || ownerUid != other.ownerUid
531                 || !Objects.equals(ownerPackageName, other.ownerPackageName)
532                 || !Arrays.equals(frameRateOverrides, other.frameRateOverrides)
533                 || !BrightnessSynchronizer.floatEquals(brightnessMinimum, other.brightnessMinimum)
534                 || !BrightnessSynchronizer.floatEquals(brightnessMaximum, other.brightnessMaximum)
535                 || !BrightnessSynchronizer.floatEquals(brightnessDefault,
536                 other.brightnessDefault)
537                 || !Objects.equals(roundedCorners, other.roundedCorners)
538                 || installOrientation != other.installOrientation
539                 || !Objects.equals(displayShape, other.displayShape)) {
540             diff |= DIFF_OTHER;
541         }
542         return diff;
543     }
544 
545     @Override
hashCode()546     public int hashCode() {
547         return 0; // don't care
548     }
549 
copyFrom(DisplayDeviceInfo other)550     public void copyFrom(DisplayDeviceInfo other) {
551         name = other.name;
552         uniqueId = other.uniqueId;
553         width = other.width;
554         height = other.height;
555         modeId = other.modeId;
556         renderFrameRate = other.renderFrameRate;
557         defaultModeId = other.defaultModeId;
558         userPreferredModeId = other.userPreferredModeId;
559         supportedModes = other.supportedModes;
560         colorMode = other.colorMode;
561         supportedColorModes = other.supportedColorModes;
562         hdrCapabilities = other.hdrCapabilities;
563         allmSupported = other.allmSupported;
564         gameContentTypeSupported = other.gameContentTypeSupported;
565         densityDpi = other.densityDpi;
566         xDpi = other.xDpi;
567         yDpi = other.yDpi;
568         appVsyncOffsetNanos = other.appVsyncOffsetNanos;
569         presentationDeadlineNanos = other.presentationDeadlineNanos;
570         flags = other.flags;
571         displayCutout = other.displayCutout;
572         touch = other.touch;
573         rotation = other.rotation;
574         type = other.type;
575         address = other.address;
576         deviceProductInfo = other.deviceProductInfo;
577         state = other.state;
578         committedState = other.committedState;
579         ownerUid = other.ownerUid;
580         ownerPackageName = other.ownerPackageName;
581         frameRateOverrides = other.frameRateOverrides;
582         brightnessMinimum = other.brightnessMinimum;
583         brightnessMaximum = other.brightnessMaximum;
584         brightnessDefault = other.brightnessDefault;
585         hdrSdrRatio = other.hdrSdrRatio;
586         roundedCorners = other.roundedCorners;
587         installOrientation = other.installOrientation;
588         displayShape = other.displayShape;
589     }
590 
591     // For debugging purposes
592     @Override
toString()593     public String toString() {
594         StringBuilder sb = new StringBuilder();
595         sb.append("DisplayDeviceInfo{\"");
596         sb.append(name).append("\": uniqueId=\"").append(uniqueId).append("\", ");
597         sb.append(width).append(" x ").append(height);
598         sb.append(", modeId ").append(modeId);
599         sb.append(", renderFrameRate ").append(renderFrameRate);
600         sb.append(", defaultModeId ").append(defaultModeId);
601         sb.append(", userPreferredModeId ").append(userPreferredModeId);
602         sb.append(", supportedModes ").append(Arrays.toString(supportedModes));
603         sb.append(", colorMode ").append(colorMode);
604         sb.append(", supportedColorModes ").append(Arrays.toString(supportedColorModes));
605         sb.append(", hdrCapabilities ").append(hdrCapabilities);
606         sb.append(", allmSupported ").append(allmSupported);
607         sb.append(", gameContentTypeSupported ").append(gameContentTypeSupported);
608         sb.append(", density ").append(densityDpi);
609         sb.append(", ").append(xDpi).append(" x ").append(yDpi).append(" dpi");
610         sb.append(", appVsyncOff ").append(appVsyncOffsetNanos);
611         sb.append(", presDeadline ").append(presentationDeadlineNanos);
612         if (displayCutout != null) {
613             sb.append(", cutout ").append(displayCutout);
614         }
615         sb.append(", touch ").append(touchToString(touch));
616         sb.append(", rotation ").append(rotation);
617         sb.append(", type ").append(Display.typeToString(type));
618         if (address != null) {
619             sb.append(", address ").append(address);
620         }
621         sb.append(", deviceProductInfo ").append(deviceProductInfo);
622         sb.append(", state ").append(Display.stateToString(state));
623         sb.append(", committedState ").append(Display.stateToString(committedState));
624         if (ownerUid != 0 || ownerPackageName != null) {
625             sb.append(", owner ").append(ownerPackageName);
626             sb.append(" (uid ").append(ownerUid).append(")");
627         }
628         sb.append(", frameRateOverride ");
629         for (DisplayEventReceiver.FrameRateOverride frameRateOverride : frameRateOverrides) {
630             sb.append(frameRateOverride).append(" ");
631         }
632         sb.append(", brightnessMinimum ").append(brightnessMinimum);
633         sb.append(", brightnessMaximum ").append(brightnessMaximum);
634         sb.append(", brightnessDefault ").append(brightnessDefault);
635         sb.append(", hdrSdrRatio ").append(hdrSdrRatio);
636         if (roundedCorners != null) {
637             sb.append(", roundedCorners ").append(roundedCorners);
638         }
639         sb.append(flagsToString(flags));
640         sb.append(", installOrientation ").append(installOrientation);
641         if (displayShape != null) {
642             sb.append(", displayShape ").append(displayShape);
643         }
644         sb.append("}");
645         return sb.toString();
646     }
647 
touchToString(int touch)648     private static String touchToString(int touch) {
649         switch (touch) {
650             case TOUCH_NONE:
651                 return "NONE";
652             case TOUCH_INTERNAL:
653                 return "INTERNAL";
654             case TOUCH_EXTERNAL:
655                 return "EXTERNAL";
656             case TOUCH_VIRTUAL:
657                 return "VIRTUAL";
658             default:
659                 return Integer.toString(touch);
660         }
661     }
662 
flagsToString(int flags)663     private static String flagsToString(int flags) {
664         StringBuilder msg = new StringBuilder();
665         if ((flags & FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY) != 0) {
666             msg.append(", FLAG_ALLOWED_TO_BE_DEFAULT_DISPLAY");
667         }
668         if ((flags & FLAG_ROTATES_WITH_CONTENT) != 0) {
669             msg.append(", FLAG_ROTATES_WITH_CONTENT");
670         }
671         if ((flags & FLAG_SECURE) != 0) {
672             msg.append(", FLAG_SECURE");
673         }
674         if ((flags & FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
675             msg.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS");
676         }
677         if ((flags & FLAG_PRIVATE) != 0) {
678             msg.append(", FLAG_PRIVATE");
679         }
680         if ((flags & FLAG_NEVER_BLANK) != 0) {
681             msg.append(", FLAG_NEVER_BLANK");
682         }
683         if ((flags & FLAG_PRESENTATION) != 0) {
684             msg.append(", FLAG_PRESENTATION");
685         }
686         if ((flags & FLAG_OWN_CONTENT_ONLY) != 0) {
687             msg.append(", FLAG_OWN_CONTENT_ONLY");
688         }
689         if ((flags & FLAG_ROUND) != 0) {
690             msg.append(", FLAG_ROUND");
691         }
692         if ((flags & FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
693             msg.append(", FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD");
694         }
695         if ((flags & FLAG_DESTROY_CONTENT_ON_REMOVAL) != 0) {
696             msg.append(", FLAG_DESTROY_CONTENT_ON_REMOVAL");
697         }
698         if ((flags & FLAG_MASK_DISPLAY_CUTOUT) != 0) {
699             msg.append(", FLAG_MASK_DISPLAY_CUTOUT");
700         }
701         if ((flags & FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0) {
702             msg.append(", FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS");
703         }
704         if ((flags & FLAG_TRUSTED) != 0) {
705             msg.append(", FLAG_TRUSTED");
706         }
707         if ((flags & FLAG_OWN_DISPLAY_GROUP) != 0) {
708             msg.append(", FLAG_OWN_DISPLAY_GROUP");
709         }
710         if ((flags & FLAG_ALWAYS_UNLOCKED) != 0) {
711             msg.append(", FLAG_ALWAYS_UNLOCKED");
712         }
713         if ((flags & FLAG_TOUCH_FEEDBACK_DISABLED) != 0) {
714             msg.append(", FLAG_TOUCH_FEEDBACK_DISABLED");
715         }
716         if ((flags & FLAG_OWN_FOCUS) != 0) {
717             msg.append(", FLAG_OWN_FOCUS");
718         }
719         if ((flags & FLAG_STEAL_TOP_FOCUS_DISABLED) != 0) {
720             msg.append(", FLAG_STEAL_TOP_FOCUS_DISABLED");
721         }
722         return msg.toString();
723     }
724 }
725