• 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 android.view;
18 
19 import static android.view.DisplayInfoProto.APP_HEIGHT;
20 import static android.view.DisplayInfoProto.APP_WIDTH;
21 import static android.view.DisplayInfoProto.FLAGS;
22 import static android.view.DisplayInfoProto.LOGICAL_HEIGHT;
23 import static android.view.DisplayInfoProto.LOGICAL_WIDTH;
24 import static android.view.DisplayInfoProto.NAME;
25 
26 import android.annotation.Nullable;
27 import android.app.WindowConfiguration;
28 import android.compat.annotation.UnsupportedAppUsage;
29 import android.content.res.CompatibilityInfo;
30 import android.content.res.Configuration;
31 import android.graphics.Rect;
32 import android.hardware.display.DeviceProductInfo;
33 import android.os.Build;
34 import android.os.Parcel;
35 import android.os.Parcelable;
36 import android.os.Process;
37 import android.util.ArraySet;
38 import android.util.DisplayMetrics;
39 import android.util.proto.ProtoOutputStream;
40 
41 import java.util.Arrays;
42 import java.util.Objects;
43 
44 /**
45  * Describes the characteristics of a particular logical display.
46  * @hide
47  */
48 public final class DisplayInfo implements Parcelable {
49     /**
50      * The surface flinger layer stack associated with this logical display.
51      */
52     public int layerStack;
53 
54     /**
55      * Display flags.
56      */
57     public int flags;
58 
59     /**
60      * Display type.
61      */
62     public int type;
63 
64     /**
65      * Logical display identifier.
66      */
67     public int displayId;
68 
69     /**
70      * Display Group identifier.
71      */
72     public int displayGroupId;
73 
74     /**
75      * Display address, or null if none.
76      * Interpretation varies by display type.
77      */
78     public DisplayAddress address;
79 
80     /**
81      * Product-specific information about the display or the directly connected device on the
82      * display chain. For example, if the display is transitively connected, this field may contain
83      * product information about the intermediate device.
84      */
85     public DeviceProductInfo deviceProductInfo;
86 
87     /**
88      * The human-readable name of the display.
89      */
90     public String name;
91 
92     /**
93      * Unique identifier for the display. Shouldn't be displayed to the user.
94      */
95     public String uniqueId;
96 
97     /**
98      * The width of the portion of the display that is available to applications, in pixels.
99      * Represents the size of the display minus any system decorations.
100      */
101     public int appWidth;
102 
103     /**
104      * The height of the portion of the display that is available to applications, in pixels.
105      * Represents the size of the display minus any system decorations.
106      */
107     public int appHeight;
108 
109     /**
110      * The smallest value of {@link #appWidth} that an application is likely to encounter,
111      * in pixels, excepting cases where the width may be even smaller due to the presence
112      * of a soft keyboard, for example.
113      */
114     public int smallestNominalAppWidth;
115 
116     /**
117      * The smallest value of {@link #appHeight} that an application is likely to encounter,
118      * in pixels, excepting cases where the height may be even smaller due to the presence
119      * of a soft keyboard, for example.
120      */
121     public int smallestNominalAppHeight;
122 
123     /**
124      * The largest value of {@link #appWidth} that an application is likely to encounter,
125      * in pixels, excepting cases where the width may be even larger due to system decorations
126      * such as the status bar being hidden, for example.
127      */
128     public int largestNominalAppWidth;
129 
130     /**
131      * The largest value of {@link #appHeight} that an application is likely to encounter,
132      * in pixels, excepting cases where the height may be even larger due to system decorations
133      * such as the status bar being hidden, for example.
134      */
135     public int largestNominalAppHeight;
136 
137     /**
138      * The logical width of the display, in pixels.
139      * Represents the usable size of the display which may be smaller than the
140      * physical size when the system is emulating a smaller display.
141      */
142     @UnsupportedAppUsage
143     public int logicalWidth;
144 
145     /**
146      * The logical height of the display, in pixels.
147      * Represents the usable size of the display which may be smaller than the
148      * physical size when the system is emulating a smaller display.
149      */
150     @UnsupportedAppUsage
151     public int logicalHeight;
152 
153     /**
154      * The {@link DisplayCutout} if present, otherwise {@code null}.
155      *
156      * @hide
157      */
158     // Remark on @UnsupportedAppUsage: Display.getCutout should be used instead
159     @Nullable
160     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
161     public DisplayCutout displayCutout;
162 
163     /**
164      * The rotation of the display relative to its natural orientation.
165      * May be one of {@link android.view.Surface#ROTATION_0},
166      * {@link android.view.Surface#ROTATION_90}, {@link android.view.Surface#ROTATION_180},
167      * {@link android.view.Surface#ROTATION_270}.
168      * <p>
169      * The value of this field is indeterminate if the logical display is presented on
170      * more than one physical display.
171      * </p>
172      */
173     @Surface.Rotation
174     @UnsupportedAppUsage
175     public int rotation;
176 
177     /**
178      * The active display mode.
179      */
180     public int modeId;
181 
182     /**
183      * The default display mode.
184      */
185     public int defaultModeId;
186 
187     /**
188      * The supported modes of this display.
189      */
190     public Display.Mode[] supportedModes = Display.Mode.EMPTY_ARRAY;
191 
192     /** The active color mode. */
193     public int colorMode;
194 
195     /** The list of supported color modes */
196     public int[] supportedColorModes = { Display.COLOR_MODE_DEFAULT };
197 
198     /** The display's HDR capabilities */
199     public Display.HdrCapabilities hdrCapabilities;
200 
201     /** The formats disabled by user **/
202     public int[] userDisabledHdrTypes = {};
203 
204     /**
205      * Indicates whether the display can be switched into a mode with minimal post
206      * processing.
207      *
208      * @see android.view.Display#isMinimalPostProcessingSupported
209      */
210     public boolean minimalPostProcessingSupported;
211 
212     /**
213      * The logical display density which is the basis for density-independent
214      * pixels.
215      */
216     public int logicalDensityDpi;
217 
218     /**
219      * The exact physical pixels per inch of the screen in the X dimension.
220      * <p>
221      * The value of this field is indeterminate if the logical display is presented on
222      * more than one physical display.
223      * </p>
224      */
225     public float physicalXDpi;
226 
227     /**
228      * The exact physical pixels per inch of the screen in the Y dimension.
229      * <p>
230      * The value of this field is indeterminate if the logical display is presented on
231      * more than one physical display.
232      * </p>
233      */
234     public float physicalYDpi;
235 
236     /**
237      * This is a positive value indicating the phase offset of the VSYNC events provided by
238      * Choreographer relative to the display refresh.  For example, if Choreographer reports
239      * that the refresh occurred at time N, it actually occurred at (N - appVsyncOffsetNanos).
240      */
241     public long appVsyncOffsetNanos;
242 
243     /**
244      * This is how far in advance a buffer must be queued for presentation at
245      * a given time.  If you want a buffer to appear on the screen at
246      * time N, you must submit the buffer before (N - bufferDeadlineNanos).
247      */
248     public long presentationDeadlineNanos;
249 
250     /**
251      * The state of the display, such as {@link android.view.Display#STATE_ON}.
252      */
253     public int state;
254 
255     /**
256      * The UID of the application that owns this display, or zero if it is owned by the system.
257      * <p>
258      * If the display is private, then only the owner can use it.
259      * </p>
260      */
261     public int ownerUid;
262 
263     /**
264      * The package name of the application that owns this display, or null if it is
265      * owned by the system.
266      * <p>
267      * If the display is private, then only the owner can use it.
268      * </p>
269      */
270     public String ownerPackageName;
271 
272     /**
273      * The refresh rate override for this app. 0 means no override.
274      */
275     public float refreshRateOverride;
276 
277     /**
278      * @hide
279      * Get current remove mode of the display - what actions should be performed with the display's
280      * content when it is removed.
281      *
282      * @see Display#getRemoveMode()
283      */
284     // TODO (b/114338689): Remove the flag and use IWindowManager#getRemoveContentMode
285     public int removeMode = Display.REMOVE_MODE_MOVE_CONTENT_TO_PRIMARY;
286 
287     /**
288      * @hide
289      * The current minimum brightness constraint of the display. Value between 0.0 and 1.0,
290      * derived from the config constraints of the display device of this logical display.
291      */
292     public float brightnessMinimum;
293 
294     /**
295      * @hide
296      * The current maximum brightness constraint of the display. Value between 0.0 and 1.0,
297      * derived from the config constraints of the display device of this logical display.
298      */
299     public float brightnessMaximum;
300 
301     /**
302      * @hide
303      * The current default brightness of the display. Value between 0.0 and 1.0,
304      * derived from the configuration of the display device of this logical display.
305      */
306     public float brightnessDefault;
307 
308     /**
309      * The {@link RoundedCorners} if present, otherwise {@code null}.
310      */
311     @Nullable
312     public RoundedCorners roundedCorners;
313 
314     public static final @android.annotation.NonNull Creator<DisplayInfo> CREATOR = new Creator<DisplayInfo>() {
315         @Override
316         public DisplayInfo createFromParcel(Parcel source) {
317             return new DisplayInfo(source);
318         }
319 
320         @Override
321         public DisplayInfo[] newArray(int size) {
322             return new DisplayInfo[size];
323         }
324     };
325 
326     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769467)
DisplayInfo()327     public DisplayInfo() {
328     }
329 
DisplayInfo(DisplayInfo other)330     public DisplayInfo(DisplayInfo other) {
331         copyFrom(other);
332     }
333 
DisplayInfo(Parcel source)334     private DisplayInfo(Parcel source) {
335         readFromParcel(source);
336     }
337 
338     @Override
equals(@ullable Object o)339     public boolean equals(@Nullable Object o) {
340         return o instanceof DisplayInfo && equals((DisplayInfo)o);
341     }
342 
equals(DisplayInfo other)343     public boolean equals(DisplayInfo other) {
344         return other != null
345                 && layerStack == other.layerStack
346                 && flags == other.flags
347                 && type == other.type
348                 && displayId == other.displayId
349                 && displayGroupId == other.displayGroupId
350                 && Objects.equals(address, other.address)
351                 && Objects.equals(deviceProductInfo, other.deviceProductInfo)
352                 && Objects.equals(uniqueId, other.uniqueId)
353                 && appWidth == other.appWidth
354                 && appHeight == other.appHeight
355                 && smallestNominalAppWidth == other.smallestNominalAppWidth
356                 && smallestNominalAppHeight == other.smallestNominalAppHeight
357                 && largestNominalAppWidth == other.largestNominalAppWidth
358                 && largestNominalAppHeight == other.largestNominalAppHeight
359                 && logicalWidth == other.logicalWidth
360                 && logicalHeight == other.logicalHeight
361                 && Objects.equals(displayCutout, other.displayCutout)
362                 && rotation == other.rotation
363                 && modeId == other.modeId
364                 && defaultModeId == other.defaultModeId
365                 && Arrays.equals(supportedModes, other.supportedModes)
366                 && colorMode == other.colorMode
367                 && Arrays.equals(supportedColorModes, other.supportedColorModes)
368                 && Objects.equals(hdrCapabilities, other.hdrCapabilities)
369                 && Arrays.equals(userDisabledHdrTypes, other.userDisabledHdrTypes)
370                 && minimalPostProcessingSupported == other.minimalPostProcessingSupported
371                 && logicalDensityDpi == other.logicalDensityDpi
372                 && physicalXDpi == other.physicalXDpi
373                 && physicalYDpi == other.physicalYDpi
374                 && appVsyncOffsetNanos == other.appVsyncOffsetNanos
375                 && presentationDeadlineNanos == other.presentationDeadlineNanos
376                 && state == other.state
377                 && ownerUid == other.ownerUid
378                 && Objects.equals(ownerPackageName, other.ownerPackageName)
379                 && removeMode == other.removeMode
380                 && getRefreshRate() == other.getRefreshRate()
381                 && brightnessMinimum == other.brightnessMinimum
382                 && brightnessMaximum == other.brightnessMaximum
383                 && brightnessDefault == other.brightnessDefault
384                 && Objects.equals(roundedCorners, other.roundedCorners);
385     }
386 
387     @Override
hashCode()388     public int hashCode() {
389         return 0; // don't care
390     }
391 
copyFrom(DisplayInfo other)392     public void copyFrom(DisplayInfo other) {
393         layerStack = other.layerStack;
394         flags = other.flags;
395         type = other.type;
396         displayId = other.displayId;
397         displayGroupId = other.displayGroupId;
398         address = other.address;
399         deviceProductInfo = other.deviceProductInfo;
400         name = other.name;
401         uniqueId = other.uniqueId;
402         appWidth = other.appWidth;
403         appHeight = other.appHeight;
404         smallestNominalAppWidth = other.smallestNominalAppWidth;
405         smallestNominalAppHeight = other.smallestNominalAppHeight;
406         largestNominalAppWidth = other.largestNominalAppWidth;
407         largestNominalAppHeight = other.largestNominalAppHeight;
408         logicalWidth = other.logicalWidth;
409         logicalHeight = other.logicalHeight;
410         displayCutout = other.displayCutout;
411         rotation = other.rotation;
412         modeId = other.modeId;
413         defaultModeId = other.defaultModeId;
414         supportedModes = Arrays.copyOf(other.supportedModes, other.supportedModes.length);
415         colorMode = other.colorMode;
416         supportedColorModes = Arrays.copyOf(
417                 other.supportedColorModes, other.supportedColorModes.length);
418         hdrCapabilities = other.hdrCapabilities;
419         userDisabledHdrTypes = other.userDisabledHdrTypes;
420         minimalPostProcessingSupported = other.minimalPostProcessingSupported;
421         logicalDensityDpi = other.logicalDensityDpi;
422         physicalXDpi = other.physicalXDpi;
423         physicalYDpi = other.physicalYDpi;
424         appVsyncOffsetNanos = other.appVsyncOffsetNanos;
425         presentationDeadlineNanos = other.presentationDeadlineNanos;
426         state = other.state;
427         ownerUid = other.ownerUid;
428         ownerPackageName = other.ownerPackageName;
429         removeMode = other.removeMode;
430         refreshRateOverride = other.refreshRateOverride;
431         brightnessMinimum = other.brightnessMinimum;
432         brightnessMaximum = other.brightnessMaximum;
433         brightnessDefault = other.brightnessDefault;
434         roundedCorners = other.roundedCorners;
435     }
436 
readFromParcel(Parcel source)437     public void readFromParcel(Parcel source) {
438         layerStack = source.readInt();
439         flags = source.readInt();
440         type = source.readInt();
441         displayId = source.readInt();
442         displayGroupId = source.readInt();
443         address = source.readParcelable(null);
444         deviceProductInfo = source.readParcelable(null);
445         name = source.readString8();
446         appWidth = source.readInt();
447         appHeight = source.readInt();
448         smallestNominalAppWidth = source.readInt();
449         smallestNominalAppHeight = source.readInt();
450         largestNominalAppWidth = source.readInt();
451         largestNominalAppHeight = source.readInt();
452         logicalWidth = source.readInt();
453         logicalHeight = source.readInt();
454         displayCutout = DisplayCutout.ParcelableWrapper.readCutoutFromParcel(source);
455         rotation = source.readInt();
456         modeId = source.readInt();
457         defaultModeId = source.readInt();
458         int nModes = source.readInt();
459         supportedModes = new Display.Mode[nModes];
460         for (int i = 0; i < nModes; i++) {
461             supportedModes[i] = Display.Mode.CREATOR.createFromParcel(source);
462         }
463         colorMode = source.readInt();
464         int nColorModes = source.readInt();
465         supportedColorModes = new int[nColorModes];
466         for (int i = 0; i < nColorModes; i++) {
467             supportedColorModes[i] = source.readInt();
468         }
469         hdrCapabilities = source.readParcelable(null);
470         minimalPostProcessingSupported = source.readBoolean();
471         logicalDensityDpi = source.readInt();
472         physicalXDpi = source.readFloat();
473         physicalYDpi = source.readFloat();
474         appVsyncOffsetNanos = source.readLong();
475         presentationDeadlineNanos = source.readLong();
476         state = source.readInt();
477         ownerUid = source.readInt();
478         ownerPackageName = source.readString8();
479         uniqueId = source.readString8();
480         removeMode = source.readInt();
481         refreshRateOverride = source.readFloat();
482         brightnessMinimum = source.readFloat();
483         brightnessMaximum = source.readFloat();
484         brightnessDefault = source.readFloat();
485         roundedCorners = source.readTypedObject(RoundedCorners.CREATOR);
486         int numUserDisabledFormats = source.readInt();
487         userDisabledHdrTypes = new int[numUserDisabledFormats];
488         for (int i = 0; i < numUserDisabledFormats; i++) {
489             userDisabledHdrTypes[i] = source.readInt();
490         }
491     }
492 
493     @Override
writeToParcel(Parcel dest, int flags)494     public void writeToParcel(Parcel dest, int flags) {
495         dest.writeInt(layerStack);
496         dest.writeInt(this.flags);
497         dest.writeInt(type);
498         dest.writeInt(displayId);
499         dest.writeInt(displayGroupId);
500         dest.writeParcelable(address, flags);
501         dest.writeParcelable(deviceProductInfo, flags);
502         dest.writeString8(name);
503         dest.writeInt(appWidth);
504         dest.writeInt(appHeight);
505         dest.writeInt(smallestNominalAppWidth);
506         dest.writeInt(smallestNominalAppHeight);
507         dest.writeInt(largestNominalAppWidth);
508         dest.writeInt(largestNominalAppHeight);
509         dest.writeInt(logicalWidth);
510         dest.writeInt(logicalHeight);
511         DisplayCutout.ParcelableWrapper.writeCutoutToParcel(displayCutout, dest, flags);
512         dest.writeInt(rotation);
513         dest.writeInt(modeId);
514         dest.writeInt(defaultModeId);
515         dest.writeInt(supportedModes.length);
516         for (int i = 0; i < supportedModes.length; i++) {
517             supportedModes[i].writeToParcel(dest, flags);
518         }
519         dest.writeInt(colorMode);
520         dest.writeInt(supportedColorModes.length);
521         for (int i = 0; i < supportedColorModes.length; i++) {
522             dest.writeInt(supportedColorModes[i]);
523         }
524         dest.writeParcelable(hdrCapabilities, flags);
525         dest.writeBoolean(minimalPostProcessingSupported);
526         dest.writeInt(logicalDensityDpi);
527         dest.writeFloat(physicalXDpi);
528         dest.writeFloat(physicalYDpi);
529         dest.writeLong(appVsyncOffsetNanos);
530         dest.writeLong(presentationDeadlineNanos);
531         dest.writeInt(state);
532         dest.writeInt(ownerUid);
533         dest.writeString8(ownerPackageName);
534         dest.writeString8(uniqueId);
535         dest.writeInt(removeMode);
536         dest.writeFloat(refreshRateOverride);
537         dest.writeFloat(brightnessMinimum);
538         dest.writeFloat(brightnessMaximum);
539         dest.writeFloat(brightnessDefault);
540         dest.writeTypedObject(roundedCorners, flags);
541         dest.writeInt(userDisabledHdrTypes.length);
542         for (int i = 0; i < userDisabledHdrTypes.length; i++) {
543             dest.writeInt(userDisabledHdrTypes[i]);
544         }
545     }
546 
547     @Override
describeContents()548     public int describeContents() {
549         return 0;
550     }
551 
552     /**
553      * Returns the refresh rate the application would experience.
554      */
getRefreshRate()555     public float getRefreshRate() {
556         if (refreshRateOverride > 0) {
557             return refreshRateOverride;
558         }
559 
560         return getMode().getRefreshRate();
561     }
562 
getMode()563     public Display.Mode getMode() {
564         return findMode(modeId);
565     }
566 
getDefaultMode()567     public Display.Mode getDefaultMode() {
568         return findMode(defaultModeId);
569     }
570 
findMode(int id)571     private Display.Mode findMode(int id) {
572         for (int i = 0; i < supportedModes.length; i++) {
573             if (supportedModes[i].getModeId() == id) {
574                 return supportedModes[i];
575             }
576         }
577         throw new IllegalStateException("Unable to locate mode " + id);
578     }
579 
580     /**
581      * Returns the id of the "default" mode with the given refresh rate, or {@code 0} if no suitable
582      * mode could be found.
583      */
584     @Nullable
findDefaultModeByRefreshRate(float refreshRate)585     public Display.Mode findDefaultModeByRefreshRate(float refreshRate) {
586         Display.Mode[] modes = supportedModes;
587         Display.Mode defaultMode = getDefaultMode();
588         for (int i = 0; i < modes.length; i++) {
589             if (modes[i].matches(
590                     defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), refreshRate)) {
591                 return modes[i];
592             }
593         }
594         return null;
595     }
596 
597     /**
598      * Returns the list of supported refresh rates in the default mode.
599      */
getDefaultRefreshRates()600     public float[] getDefaultRefreshRates() {
601         Display.Mode[] modes = supportedModes;
602         ArraySet<Float> rates = new ArraySet<>();
603         Display.Mode defaultMode = getDefaultMode();
604         for (int i = 0; i < modes.length; i++) {
605             Display.Mode mode = modes[i];
606             if (mode.getPhysicalWidth() == defaultMode.getPhysicalWidth()
607                     && mode.getPhysicalHeight() == defaultMode.getPhysicalHeight()) {
608                 rates.add(mode.getRefreshRate());
609             }
610         }
611         float[] result = new float[rates.size()];
612         int i = 0;
613         for (Float rate : rates) {
614             result[i++] = rate;
615         }
616         return result;
617     }
618 
getAppMetrics(DisplayMetrics outMetrics)619     public void getAppMetrics(DisplayMetrics outMetrics) {
620         getAppMetrics(outMetrics, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
621     }
622 
getAppMetrics(DisplayMetrics outMetrics, DisplayAdjustments displayAdjustments)623     public void getAppMetrics(DisplayMetrics outMetrics, DisplayAdjustments displayAdjustments) {
624         getMetricsWithSize(outMetrics, displayAdjustments.getCompatibilityInfo(),
625                 displayAdjustments.getConfiguration(), appWidth, appHeight);
626     }
627 
getAppMetrics(DisplayMetrics outMetrics, CompatibilityInfo ci, Configuration configuration)628     public void getAppMetrics(DisplayMetrics outMetrics, CompatibilityInfo ci,
629             Configuration configuration) {
630         getMetricsWithSize(outMetrics, ci, configuration, appWidth, appHeight);
631     }
632 
633     /**
634      * Populates {@code outMetrics} with details of the logical display. Bounds are limited
635      * by the logical size of the display.
636      *
637      * @param outMetrics the {@link DisplayMetrics} to be populated
638      * @param compatInfo the {@link CompatibilityInfo} to be applied
639      * @param configuration the {@link Configuration}
640      */
getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo, Configuration configuration)641     public void getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
642             Configuration configuration) {
643         getMetricsWithSize(outMetrics, compatInfo, configuration, logicalWidth, logicalHeight);
644     }
645 
646     /**
647      * Similar to {@link #getLogicalMetrics}, but the limiting bounds are determined from
648      * {@link WindowConfiguration#getMaxBounds()}
649      */
getMaxBoundsMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo, Configuration configuration)650     public void getMaxBoundsMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
651             Configuration configuration) {
652         Rect bounds = configuration.windowConfiguration.getMaxBounds();
653         // Pass in null configuration to ensure width and height are not overridden to app bounds.
654         getMetricsWithSize(outMetrics, compatInfo, /* configuration= */ null,
655                 bounds.width(), bounds.height());
656     }
657 
getNaturalWidth()658     public int getNaturalWidth() {
659         return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ?
660                 logicalWidth : logicalHeight;
661     }
662 
getNaturalHeight()663     public int getNaturalHeight() {
664         return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ?
665                 logicalHeight : logicalWidth;
666     }
667 
isHdr()668     public boolean isHdr() {
669         int[] types = hdrCapabilities != null ? hdrCapabilities.getSupportedHdrTypes() : null;
670         return types != null && types.length > 0;
671     }
672 
isWideColorGamut()673     public boolean isWideColorGamut() {
674         for (int colorMode : supportedColorModes) {
675             if (colorMode == Display.COLOR_MODE_DCI_P3 || colorMode > Display.COLOR_MODE_SRGB) {
676                 return true;
677             }
678         }
679         return false;
680     }
681 
682     /**
683      * Returns true if the specified UID has access to this display.
684      */
hasAccess(int uid)685     public boolean hasAccess(int uid) {
686         return Display.hasAccess(uid, flags, ownerUid, displayId);
687     }
688 
getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfo compatInfo, Configuration configuration, int width, int height)689     private void getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
690             Configuration configuration, int width, int height) {
691         outMetrics.densityDpi = outMetrics.noncompatDensityDpi = logicalDensityDpi;
692         outMetrics.density = outMetrics.noncompatDensity =
693                 logicalDensityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
694         outMetrics.scaledDensity = outMetrics.noncompatScaledDensity = outMetrics.density;
695         outMetrics.xdpi = outMetrics.noncompatXdpi = physicalXDpi;
696         outMetrics.ydpi = outMetrics.noncompatYdpi = physicalYDpi;
697 
698         final Rect appBounds = configuration != null
699                 ? configuration.windowConfiguration.getAppBounds() : null;
700         width = appBounds != null ? appBounds.width() : width;
701         height = appBounds != null ? appBounds.height() : height;
702 
703         outMetrics.noncompatWidthPixels  = outMetrics.widthPixels = width;
704         outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height;
705 
706         if (!compatInfo.equals(CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO)) {
707             compatInfo.applyToDisplayMetrics(outMetrics);
708         }
709     }
710 
711     // For debugging purposes
712     @Override
toString()713     public String toString() {
714         StringBuilder sb = new StringBuilder();
715         sb.append("DisplayInfo{\"");
716         sb.append(name);
717         sb.append("\", displayId ");
718         sb.append(displayId);
719         sb.append("\", displayGroupId ");
720         sb.append(displayGroupId);
721         sb.append(flagsToString(flags));
722         sb.append(", real ");
723         sb.append(logicalWidth);
724         sb.append(" x ");
725         sb.append(logicalHeight);
726         sb.append(", largest app ");
727         sb.append(largestNominalAppWidth);
728         sb.append(" x ");
729         sb.append(largestNominalAppHeight);
730         sb.append(", smallest app ");
731         sb.append(smallestNominalAppWidth);
732         sb.append(" x ");
733         sb.append(smallestNominalAppHeight);
734         sb.append(", appVsyncOff ");
735         sb.append(appVsyncOffsetNanos);
736         sb.append(", presDeadline ");
737         sb.append(presentationDeadlineNanos);
738         sb.append(", mode ");
739         sb.append(modeId);
740         sb.append(", defaultMode ");
741         sb.append(defaultModeId);
742         sb.append(", modes ");
743         sb.append(Arrays.toString(supportedModes));
744         sb.append(", hdrCapabilities ");
745         sb.append(hdrCapabilities);
746         sb.append(", userDisabledHdrTypes ");
747         sb.append(Arrays.toString(userDisabledHdrTypes));
748         sb.append(", minimalPostProcessingSupported ");
749         sb.append(minimalPostProcessingSupported);
750         sb.append(", rotation ");
751         sb.append(rotation);
752         sb.append(", state ");
753         sb.append(Display.stateToString(state));
754 
755         if (Process.myUid() != Process.SYSTEM_UID) {
756             sb.append("}");
757             return sb.toString();
758         }
759 
760         sb.append(", type ");
761         sb.append(Display.typeToString(type));
762         sb.append(", uniqueId \"");
763         sb.append(uniqueId);
764         sb.append("\", app ");
765         sb.append(appWidth);
766         sb.append(" x ");
767         sb.append(appHeight);
768         sb.append(", density ");
769         sb.append(logicalDensityDpi);
770         sb.append(" (");
771         sb.append(physicalXDpi);
772         sb.append(" x ");
773         sb.append(physicalYDpi);
774         sb.append(") dpi, layerStack ");
775         sb.append(layerStack);
776         sb.append(", colorMode ");
777         sb.append(colorMode);
778         sb.append(", supportedColorModes ");
779         sb.append(Arrays.toString(supportedColorModes));
780         if (address != null) {
781             sb.append(", address ").append(address);
782         }
783         sb.append(", deviceProductInfo ");
784         sb.append(deviceProductInfo);
785         if (ownerUid != 0 || ownerPackageName != null) {
786             sb.append(", owner ").append(ownerPackageName);
787             sb.append(" (uid ").append(ownerUid).append(")");
788         }
789         sb.append(", removeMode ");
790         sb.append(removeMode);
791         sb.append(", refreshRateOverride ");
792         sb.append(refreshRateOverride);
793         sb.append(", brightnessMinimum ");
794         sb.append(brightnessMinimum);
795         sb.append(", brightnessMaximum ");
796         sb.append(brightnessMaximum);
797         sb.append(", brightnessDefault ");
798         sb.append(brightnessDefault);
799         sb.append("}");
800         return sb.toString();
801     }
802 
803     /**
804      * Write to a protocol buffer output stream.
805      * Protocol buffer message definition at {@link android.view.DisplayInfoProto}
806      *
807      * @param protoOutputStream Stream to write the Rect object to.
808      * @param fieldId           Field Id of the DisplayInfoProto as defined in the parent message
809      */
dumpDebug(ProtoOutputStream protoOutputStream, long fieldId)810     public void dumpDebug(ProtoOutputStream protoOutputStream, long fieldId) {
811         final long token = protoOutputStream.start(fieldId);
812         protoOutputStream.write(LOGICAL_WIDTH, logicalWidth);
813         protoOutputStream.write(LOGICAL_HEIGHT, logicalHeight);
814         protoOutputStream.write(APP_WIDTH, appWidth);
815         protoOutputStream.write(APP_HEIGHT, appHeight);
816         protoOutputStream.write(NAME, name);
817         protoOutputStream.write(FLAGS, flags);
818         protoOutputStream.end(token);
819     }
820 
flagsToString(int flags)821     private static String flagsToString(int flags) {
822         StringBuilder result = new StringBuilder();
823         if ((flags & Display.FLAG_SECURE) != 0) {
824             result.append(", FLAG_SECURE");
825         }
826         if ((flags & Display.FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
827             result.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS");
828         }
829         if ((flags & Display.FLAG_PRIVATE) != 0) {
830             result.append(", FLAG_PRIVATE");
831         }
832         if ((flags & Display.FLAG_PRESENTATION) != 0) {
833             result.append(", FLAG_PRESENTATION");
834         }
835         if ((flags & Display.FLAG_SCALING_DISABLED) != 0) {
836             result.append(", FLAG_SCALING_DISABLED");
837         }
838         if ((flags & Display.FLAG_ROUND) != 0) {
839             result.append(", FLAG_ROUND");
840         }
841         if ((flags & Display.FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD) != 0) {
842             result.append(", FLAG_CAN_SHOW_WITH_INSECURE_KEYGUARD");
843         }
844         if ((flags & Display.FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS) != 0) {
845             result.append(", FLAG_SHOULD_SHOW_SYSTEM_DECORATIONS");
846         }
847         if ((flags & Display.FLAG_TRUSTED) != 0) {
848             result.append(", FLAG_TRUSTED");
849         }
850         if ((flags & Display.FLAG_OWN_DISPLAY_GROUP) != 0) {
851             result.append(", FLAG_OWN_DISPLAY_GROUP");
852         }
853         return result.toString();
854     }
855 }
856