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 android.view;
18 
19 import android.content.res.CompatibilityInfo;
20 import android.content.res.Configuration;
21 import android.os.Parcel;
22 import android.os.Parcelable;
23 import android.util.ArraySet;
24 import android.util.DisplayMetrics;
25 
26 import java.util.Arrays;
27 
28 import libcore.util.Objects;
29 
30 /**
31  * Describes the characteristics of a particular logical display.
32  * @hide
33  */
34 public final class DisplayInfo implements Parcelable {
35     /**
36      * The surface flinger layer stack associated with this logical display.
37      */
38     public int layerStack;
39 
40     /**
41      * Display flags.
42      */
43     public int flags;
44 
45     /**
46      * Display type.
47      */
48     public int type;
49 
50     /**
51      * Display address, or null if none.
52      * Interpretation varies by display type.
53      */
54     public String address;
55 
56     /**
57      * The human-readable name of the display.
58      */
59     public String name;
60 
61     /**
62      * Unique identifier for the display. Shouldn't be displayed to the user.
63      */
64     public String uniqueId;
65 
66     /**
67      * The width of the portion of the display that is available to applications, in pixels.
68      * Represents the size of the display minus any system decorations.
69      */
70     public int appWidth;
71 
72     /**
73      * The height of the portion of the display that is available to applications, in pixels.
74      * Represents the size of the display minus any system decorations.
75      */
76     public int appHeight;
77 
78     /**
79      * The smallest value of {@link #appWidth} that an application is likely to encounter,
80      * in pixels, excepting cases where the width may be even smaller due to the presence
81      * of a soft keyboard, for example.
82      */
83     public int smallestNominalAppWidth;
84 
85     /**
86      * The smallest value of {@link #appHeight} that an application is likely to encounter,
87      * in pixels, excepting cases where the height may be even smaller due to the presence
88      * of a soft keyboard, for example.
89      */
90     public int smallestNominalAppHeight;
91 
92     /**
93      * The largest value of {@link #appWidth} that an application is likely to encounter,
94      * in pixels, excepting cases where the width may be even larger due to system decorations
95      * such as the status bar being hidden, for example.
96      */
97     public int largestNominalAppWidth;
98 
99     /**
100      * The largest value of {@link #appHeight} that an application is likely to encounter,
101      * in pixels, excepting cases where the height may be even larger due to system decorations
102      * such as the status bar being hidden, for example.
103      */
104     public int largestNominalAppHeight;
105 
106     /**
107      * The logical width of the display, in pixels.
108      * Represents the usable size of the display which may be smaller than the
109      * physical size when the system is emulating a smaller display.
110      */
111     public int logicalWidth;
112 
113     /**
114      * The logical height of the display, in pixels.
115      * Represents the usable size of the display which may be smaller than the
116      * physical size when the system is emulating a smaller display.
117      */
118     public int logicalHeight;
119 
120     /**
121      * @hide
122      * Number of overscan pixels on the left side of the display.
123      */
124     public int overscanLeft;
125 
126     /**
127      * @hide
128      * Number of overscan pixels on the top side of the display.
129      */
130     public int overscanTop;
131 
132     /**
133      * @hide
134      * Number of overscan pixels on the right side of the display.
135      */
136     public int overscanRight;
137 
138     /**
139      * @hide
140      * Number of overscan pixels on the bottom side of the display.
141      */
142     public int overscanBottom;
143 
144     /**
145      * The rotation of the display relative to its natural orientation.
146      * May be one of {@link android.view.Surface#ROTATION_0},
147      * {@link android.view.Surface#ROTATION_90}, {@link android.view.Surface#ROTATION_180},
148      * {@link android.view.Surface#ROTATION_270}.
149      * <p>
150      * The value of this field is indeterminate if the logical display is presented on
151      * more than one physical display.
152      * </p>
153      */
154     @Surface.Rotation
155     public int rotation;
156 
157     /**
158      * The active display mode.
159      */
160     public int modeId;
161 
162     /**
163      * The default display mode.
164      */
165     public int defaultModeId;
166 
167     /**
168      * The supported modes of this display.
169      */
170     public Display.Mode[] supportedModes = Display.Mode.EMPTY_ARRAY;
171 
172     /** The active color transform. */
173     public int colorTransformId;
174 
175     /** The default color transform. */
176     public int defaultColorTransformId;
177 
178     /** The list of supported color transforms */
179     public Display.ColorTransform[] supportedColorTransforms = Display.ColorTransform.EMPTY_ARRAY;
180 
181     /** The display's HDR capabilities */
182     public Display.HdrCapabilities hdrCapabilities;
183 
184     /**
185      * The logical display density which is the basis for density-independent
186      * pixels.
187      */
188     public int logicalDensityDpi;
189 
190     /**
191      * The exact physical pixels per inch of the screen in the X dimension.
192      * <p>
193      * The value of this field is indeterminate if the logical display is presented on
194      * more than one physical display.
195      * </p>
196      */
197     public float physicalXDpi;
198 
199     /**
200      * The exact physical pixels per inch of the screen in the Y dimension.
201      * <p>
202      * The value of this field is indeterminate if the logical display is presented on
203      * more than one physical display.
204      * </p>
205      */
206     public float physicalYDpi;
207 
208     /**
209      * This is a positive value indicating the phase offset of the VSYNC events provided by
210      * Choreographer relative to the display refresh.  For example, if Choreographer reports
211      * that the refresh occurred at time N, it actually occurred at (N - appVsyncOffsetNanos).
212      */
213     public long appVsyncOffsetNanos;
214 
215     /**
216      * This is how far in advance a buffer must be queued for presentation at
217      * a given time.  If you want a buffer to appear on the screen at
218      * time N, you must submit the buffer before (N - bufferDeadlineNanos).
219      */
220     public long presentationDeadlineNanos;
221 
222     /**
223      * The state of the display, such as {@link android.view.Display#STATE_ON}.
224      */
225     public int state;
226 
227     /**
228      * The UID of the application that owns this display, or zero if it is owned by the system.
229      * <p>
230      * If the display is private, then only the owner can use it.
231      * </p>
232      */
233     public int ownerUid;
234 
235     /**
236      * The package name of the application that owns this display, or null if it is
237      * owned by the system.
238      * <p>
239      * If the display is private, then only the owner can use it.
240      * </p>
241      */
242     public String ownerPackageName;
243 
244     public static final Creator<DisplayInfo> CREATOR = new Creator<DisplayInfo>() {
245         @Override
246         public DisplayInfo createFromParcel(Parcel source) {
247             return new DisplayInfo(source);
248         }
249 
250         @Override
251         public DisplayInfo[] newArray(int size) {
252             return new DisplayInfo[size];
253         }
254     };
255 
DisplayInfo()256     public DisplayInfo() {
257     }
258 
DisplayInfo(DisplayInfo other)259     public DisplayInfo(DisplayInfo other) {
260         copyFrom(other);
261     }
262 
DisplayInfo(Parcel source)263     private DisplayInfo(Parcel source) {
264         readFromParcel(source);
265     }
266 
267     @Override
equals(Object o)268     public boolean equals(Object o) {
269         return o instanceof DisplayInfo && equals((DisplayInfo)o);
270     }
271 
equals(DisplayInfo other)272     public boolean equals(DisplayInfo other) {
273         return other != null
274                 && layerStack == other.layerStack
275                 && flags == other.flags
276                 && type == other.type
277                 && Objects.equal(address, other.address)
278                 && Objects.equal(uniqueId, other.uniqueId)
279                 && appWidth == other.appWidth
280                 && appHeight == other.appHeight
281                 && smallestNominalAppWidth == other.smallestNominalAppWidth
282                 && smallestNominalAppHeight == other.smallestNominalAppHeight
283                 && largestNominalAppWidth == other.largestNominalAppWidth
284                 && largestNominalAppHeight == other.largestNominalAppHeight
285                 && logicalWidth == other.logicalWidth
286                 && logicalHeight == other.logicalHeight
287                 && overscanLeft == other.overscanLeft
288                 && overscanTop == other.overscanTop
289                 && overscanRight == other.overscanRight
290                 && overscanBottom == other.overscanBottom
291                 && rotation == other.rotation
292                 && modeId == other.modeId
293                 && defaultModeId == other.defaultModeId
294                 && colorTransformId == other.colorTransformId
295                 && defaultColorTransformId == other.defaultColorTransformId
296                 && Objects.equal(hdrCapabilities, other.hdrCapabilities)
297                 && logicalDensityDpi == other.logicalDensityDpi
298                 && physicalXDpi == other.physicalXDpi
299                 && physicalYDpi == other.physicalYDpi
300                 && appVsyncOffsetNanos == other.appVsyncOffsetNanos
301                 && presentationDeadlineNanos == other.presentationDeadlineNanos
302                 && state == other.state
303                 && ownerUid == other.ownerUid
304                 && Objects.equal(ownerPackageName, other.ownerPackageName);
305     }
306 
307     @Override
hashCode()308     public int hashCode() {
309         return 0; // don't care
310     }
311 
copyFrom(DisplayInfo other)312     public void copyFrom(DisplayInfo other) {
313         layerStack = other.layerStack;
314         flags = other.flags;
315         type = other.type;
316         address = other.address;
317         name = other.name;
318         uniqueId = other.uniqueId;
319         appWidth = other.appWidth;
320         appHeight = other.appHeight;
321         smallestNominalAppWidth = other.smallestNominalAppWidth;
322         smallestNominalAppHeight = other.smallestNominalAppHeight;
323         largestNominalAppWidth = other.largestNominalAppWidth;
324         largestNominalAppHeight = other.largestNominalAppHeight;
325         logicalWidth = other.logicalWidth;
326         logicalHeight = other.logicalHeight;
327         overscanLeft = other.overscanLeft;
328         overscanTop = other.overscanTop;
329         overscanRight = other.overscanRight;
330         overscanBottom = other.overscanBottom;
331         rotation = other.rotation;
332         modeId = other.modeId;
333         defaultModeId = other.defaultModeId;
334         supportedModes = Arrays.copyOf(other.supportedModes, other.supportedModes.length);
335         colorTransformId = other.colorTransformId;
336         defaultColorTransformId = other.defaultColorTransformId;
337         supportedColorTransforms = Arrays.copyOf(
338                 other.supportedColorTransforms, other.supportedColorTransforms.length);
339         hdrCapabilities = other.hdrCapabilities;
340         logicalDensityDpi = other.logicalDensityDpi;
341         physicalXDpi = other.physicalXDpi;
342         physicalYDpi = other.physicalYDpi;
343         appVsyncOffsetNanos = other.appVsyncOffsetNanos;
344         presentationDeadlineNanos = other.presentationDeadlineNanos;
345         state = other.state;
346         ownerUid = other.ownerUid;
347         ownerPackageName = other.ownerPackageName;
348     }
349 
readFromParcel(Parcel source)350     public void readFromParcel(Parcel source) {
351         layerStack = source.readInt();
352         flags = source.readInt();
353         type = source.readInt();
354         address = source.readString();
355         name = source.readString();
356         appWidth = source.readInt();
357         appHeight = source.readInt();
358         smallestNominalAppWidth = source.readInt();
359         smallestNominalAppHeight = source.readInt();
360         largestNominalAppWidth = source.readInt();
361         largestNominalAppHeight = source.readInt();
362         logicalWidth = source.readInt();
363         logicalHeight = source.readInt();
364         overscanLeft = source.readInt();
365         overscanTop = source.readInt();
366         overscanRight = source.readInt();
367         overscanBottom = source.readInt();
368         rotation = source.readInt();
369         modeId = source.readInt();
370         defaultModeId = source.readInt();
371         int nModes = source.readInt();
372         supportedModes = new Display.Mode[nModes];
373         for (int i = 0; i < nModes; i++) {
374             supportedModes[i] = Display.Mode.CREATOR.createFromParcel(source);
375         }
376         colorTransformId = source.readInt();
377         defaultColorTransformId = source.readInt();
378         int nColorTransforms = source.readInt();
379         supportedColorTransforms = new Display.ColorTransform[nColorTransforms];
380         for (int i = 0; i < nColorTransforms; i++) {
381             supportedColorTransforms[i] = Display.ColorTransform.CREATOR.createFromParcel(source);
382         }
383         hdrCapabilities = source.readParcelable(null);
384         logicalDensityDpi = source.readInt();
385         physicalXDpi = source.readFloat();
386         physicalYDpi = source.readFloat();
387         appVsyncOffsetNanos = source.readLong();
388         presentationDeadlineNanos = source.readLong();
389         state = source.readInt();
390         ownerUid = source.readInt();
391         ownerPackageName = source.readString();
392         uniqueId = source.readString();
393     }
394 
395     @Override
writeToParcel(Parcel dest, int flags)396     public void writeToParcel(Parcel dest, int flags) {
397         dest.writeInt(layerStack);
398         dest.writeInt(this.flags);
399         dest.writeInt(type);
400         dest.writeString(address);
401         dest.writeString(name);
402         dest.writeInt(appWidth);
403         dest.writeInt(appHeight);
404         dest.writeInt(smallestNominalAppWidth);
405         dest.writeInt(smallestNominalAppHeight);
406         dest.writeInt(largestNominalAppWidth);
407         dest.writeInt(largestNominalAppHeight);
408         dest.writeInt(logicalWidth);
409         dest.writeInt(logicalHeight);
410         dest.writeInt(overscanLeft);
411         dest.writeInt(overscanTop);
412         dest.writeInt(overscanRight);
413         dest.writeInt(overscanBottom);
414         dest.writeInt(rotation);
415         dest.writeInt(modeId);
416         dest.writeInt(defaultModeId);
417         dest.writeInt(supportedModes.length);
418         for (int i = 0; i < supportedModes.length; i++) {
419             supportedModes[i].writeToParcel(dest, flags);
420         }
421         dest.writeInt(colorTransformId);
422         dest.writeInt(defaultColorTransformId);
423         dest.writeInt(supportedColorTransforms.length);
424         for (int i = 0; i < supportedColorTransforms.length; i++) {
425             supportedColorTransforms[i].writeToParcel(dest, flags);
426         }
427         dest.writeParcelable(hdrCapabilities, flags);
428         dest.writeInt(logicalDensityDpi);
429         dest.writeFloat(physicalXDpi);
430         dest.writeFloat(physicalYDpi);
431         dest.writeLong(appVsyncOffsetNanos);
432         dest.writeLong(presentationDeadlineNanos);
433         dest.writeInt(state);
434         dest.writeInt(ownerUid);
435         dest.writeString(ownerPackageName);
436         dest.writeString(uniqueId);
437     }
438 
439     @Override
describeContents()440     public int describeContents() {
441         return 0;
442     }
443 
getMode()444     public Display.Mode getMode() {
445         return findMode(modeId);
446     }
447 
getDefaultMode()448     public Display.Mode getDefaultMode() {
449         return findMode(defaultModeId);
450     }
451 
findMode(int id)452     private Display.Mode findMode(int id) {
453         for (int i = 0; i < supportedModes.length; i++) {
454             if (supportedModes[i].getModeId() == id) {
455                 return supportedModes[i];
456             }
457         }
458         throw new IllegalStateException("Unable to locate mode " + id);
459     }
460 
461     /**
462      * Returns the id of the "default" mode with the given refresh rate, or {@code 0} if no suitable
463      * mode could be found.
464      */
findDefaultModeByRefreshRate(float refreshRate)465     public int findDefaultModeByRefreshRate(float refreshRate) {
466         Display.Mode[] modes = supportedModes;
467         Display.Mode defaultMode = getDefaultMode();
468         for (int i = 0; i < modes.length; i++) {
469             if (modes[i].matches(
470                     defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), refreshRate)) {
471                 return modes[i].getModeId();
472             }
473         }
474         return 0;
475     }
476 
477     /**
478      * Returns the list of supported refresh rates in the default mode.
479      */
getDefaultRefreshRates()480     public float[] getDefaultRefreshRates() {
481         Display.Mode[] modes = supportedModes;
482         ArraySet<Float> rates = new ArraySet<>();
483         Display.Mode defaultMode = getDefaultMode();
484         for (int i = 0; i < modes.length; i++) {
485             Display.Mode mode = modes[i];
486             if (mode.getPhysicalWidth() == defaultMode.getPhysicalWidth()
487                     && mode.getPhysicalHeight() == defaultMode.getPhysicalHeight()) {
488                 rates.add(mode.getRefreshRate());
489             }
490         }
491         float[] result = new float[rates.size()];
492         int i = 0;
493         for (Float rate : rates) {
494             result[i++] = rate;
495         }
496         return result;
497     }
498 
getColorTransform()499     public Display.ColorTransform getColorTransform() {
500         return findColorTransform(colorTransformId);
501     }
502 
getDefaultColorTransform()503     public Display.ColorTransform getDefaultColorTransform() {
504         return findColorTransform(defaultColorTransformId);
505     }
506 
findColorTransform(int colorTransformId)507     private Display.ColorTransform findColorTransform(int colorTransformId) {
508         for (int i = 0; i < supportedColorTransforms.length; i++) {
509             Display.ColorTransform colorTransform = supportedColorTransforms[i];
510             if (colorTransform.getId() == colorTransformId) {
511                 return colorTransform;
512             }
513         }
514         throw new IllegalStateException("Unable to locate color transform: " + colorTransformId);
515     }
516 
getAppMetrics(DisplayMetrics outMetrics)517     public void getAppMetrics(DisplayMetrics outMetrics) {
518         getAppMetrics(outMetrics, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
519     }
520 
getAppMetrics(DisplayMetrics outMetrics, DisplayAdjustments displayAdjustments)521     public void getAppMetrics(DisplayMetrics outMetrics, DisplayAdjustments displayAdjustments) {
522         getMetricsWithSize(outMetrics, displayAdjustments.getCompatibilityInfo(),
523                 displayAdjustments.getConfiguration(), appWidth, appHeight);
524     }
525 
getAppMetrics(DisplayMetrics outMetrics, CompatibilityInfo ci, Configuration configuration)526     public void getAppMetrics(DisplayMetrics outMetrics, CompatibilityInfo ci,
527             Configuration configuration) {
528         getMetricsWithSize(outMetrics, ci, configuration, appWidth, appHeight);
529     }
530 
getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo, Configuration configuration)531     public void getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
532             Configuration configuration) {
533         getMetricsWithSize(outMetrics, compatInfo, configuration, logicalWidth, logicalHeight);
534     }
535 
getNaturalWidth()536     public int getNaturalWidth() {
537         return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ?
538                 logicalWidth : logicalHeight;
539     }
540 
getNaturalHeight()541     public int getNaturalHeight() {
542         return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ?
543                 logicalHeight : logicalWidth;
544     }
545 
546     /**
547      * Returns true if the specified UID has access to this display.
548      */
hasAccess(int uid)549     public boolean hasAccess(int uid) {
550         return Display.hasAccess(uid, flags, ownerUid);
551     }
552 
getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfo compatInfo, Configuration configuration, int width, int height)553     private void getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
554             Configuration configuration, int width, int height) {
555         outMetrics.densityDpi = outMetrics.noncompatDensityDpi = logicalDensityDpi;
556         outMetrics.density = outMetrics.noncompatDensity =
557                 logicalDensityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
558         outMetrics.scaledDensity = outMetrics.noncompatScaledDensity = outMetrics.density;
559         outMetrics.xdpi = outMetrics.noncompatXdpi = physicalXDpi;
560         outMetrics.ydpi = outMetrics.noncompatYdpi = physicalYDpi;
561 
562         width = (configuration != null
563                 && configuration.screenWidthDp != Configuration.SCREEN_WIDTH_DP_UNDEFINED)
564                 ? (int)((configuration.screenWidthDp * outMetrics.density) + 0.5f) : width;
565         height = (configuration != null
566                 && configuration.screenHeightDp != Configuration.SCREEN_HEIGHT_DP_UNDEFINED)
567                 ? (int)((configuration.screenHeightDp * outMetrics.density) + 0.5f) : height;
568 
569         outMetrics.noncompatWidthPixels  = outMetrics.widthPixels = width;
570         outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height;
571 
572         if (!compatInfo.equals(CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO)) {
573             compatInfo.applyToDisplayMetrics(outMetrics);
574         }
575     }
576 
577     // For debugging purposes
578     @Override
toString()579     public String toString() {
580         StringBuilder sb = new StringBuilder();
581         sb.append("DisplayInfo{\"");
582         sb.append(name);
583         sb.append("\", uniqueId \"");
584         sb.append(uniqueId);
585         sb.append("\", app ");
586         sb.append(appWidth);
587         sb.append(" x ");
588         sb.append(appHeight);
589         sb.append(", real ");
590         sb.append(logicalWidth);
591         sb.append(" x ");
592         sb.append(logicalHeight);
593         if (overscanLeft != 0 || overscanTop != 0 || overscanRight != 0 || overscanBottom != 0) {
594             sb.append(", overscan (");
595             sb.append(overscanLeft);
596             sb.append(",");
597             sb.append(overscanTop);
598             sb.append(",");
599             sb.append(overscanRight);
600             sb.append(",");
601             sb.append(overscanBottom);
602             sb.append(")");
603         }
604         sb.append(", largest app ");
605         sb.append(largestNominalAppWidth);
606         sb.append(" x ");
607         sb.append(largestNominalAppHeight);
608         sb.append(", smallest app ");
609         sb.append(smallestNominalAppWidth);
610         sb.append(" x ");
611         sb.append(smallestNominalAppHeight);
612         sb.append(", mode ");
613         sb.append(modeId);
614         sb.append(", defaultMode ");
615         sb.append(defaultModeId);
616         sb.append(", modes ");
617         sb.append(Arrays.toString(supportedModes));
618         sb.append(", colorTransformId ");
619         sb.append(colorTransformId);
620         sb.append(", defaultColorTransformId ");
621         sb.append(defaultColorTransformId);
622         sb.append(", supportedColorTransforms ");
623         sb.append(Arrays.toString(supportedColorTransforms));
624         sb.append(", hdrCapabilities ");
625         sb.append(hdrCapabilities);
626         sb.append(", rotation ");
627         sb.append(rotation);
628         sb.append(", density ");
629         sb.append(logicalDensityDpi);
630         sb.append(" (");
631         sb.append(physicalXDpi);
632         sb.append(" x ");
633         sb.append(physicalYDpi);
634         sb.append(") dpi, layerStack ");
635         sb.append(layerStack);
636         sb.append(", appVsyncOff ");
637         sb.append(appVsyncOffsetNanos);
638         sb.append(", presDeadline ");
639         sb.append(presentationDeadlineNanos);
640         sb.append(", type ");
641         sb.append(Display.typeToString(type));
642         if (address != null) {
643             sb.append(", address ").append(address);
644         }
645         sb.append(", state ");
646         sb.append(Display.stateToString(state));
647         if (ownerUid != 0 || ownerPackageName != null) {
648             sb.append(", owner ").append(ownerPackageName);
649             sb.append(" (uid ").append(ownerUid).append(")");
650         }
651         sb.append(flagsToString(flags));
652         sb.append("}");
653         return sb.toString();
654     }
655 
flagsToString(int flags)656     private static String flagsToString(int flags) {
657         StringBuilder result = new StringBuilder();
658         if ((flags & Display.FLAG_SECURE) != 0) {
659             result.append(", FLAG_SECURE");
660         }
661         if ((flags & Display.FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
662             result.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS");
663         }
664         if ((flags & Display.FLAG_PRIVATE) != 0) {
665             result.append(", FLAG_PRIVATE");
666         }
667         if ((flags & Display.FLAG_PRESENTATION) != 0) {
668             result.append(", FLAG_PRESENTATION");
669         }
670         if ((flags & Display.FLAG_SCALING_DISABLED) != 0) {
671             result.append(", FLAG_SCALING_DISABLED");
672         }
673         if ((flags & Display.FLAG_ROUND) != 0) {
674             result.append(", FLAG_ROUND");
675         }
676         return result.toString();
677     }
678 }
679