blob: 913e5924c6a6dd88657a04cbf7862742e2628804 [file] [log] [blame]
Jeff Brownfa25bf52012-07-23 19:26:30 -07001/*
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
17package android.view;
18
Steven Timotiusaf03df62017-07-18 16:56:43 -070019import static android.view.DisplayInfoProto.APP_HEIGHT;
20import static android.view.DisplayInfoProto.APP_WIDTH;
21import static android.view.DisplayInfoProto.LOGICAL_HEIGHT;
22import static android.view.DisplayInfoProto.LOGICAL_WIDTH;
Andrii Kulian764e1042018-02-08 15:12:14 -080023import static android.view.DisplayInfoProto.NAME;
Steven Timotiusaf03df62017-07-18 16:56:43 -070024
Jeff Brownfa25bf52012-07-23 19:26:30 -070025import android.content.res.CompatibilityInfo;
Wale Ogunwale7c726682015-02-06 17:34:28 -080026import android.content.res.Configuration;
Wale Ogunwale822e5122017-07-26 06:02:24 -070027import android.graphics.Rect;
Jeff Brownfa25bf52012-07-23 19:26:30 -070028import android.os.Parcel;
29import android.os.Parcelable;
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -070030import android.util.ArraySet;
Jeff Brownfa25bf52012-07-23 19:26:30 -070031import android.util.DisplayMetrics;
Steven Timotiusaf03df62017-07-18 16:56:43 -070032import android.util.proto.ProtoOutputStream;
Jeff Brownfa25bf52012-07-23 19:26:30 -070033
Aurimas Liutikas67e2ae82016-10-11 18:17:42 -070034import java.util.Arrays;
Narayan Kamath607223f2018-02-19 14:09:02 +000035import java.util.Objects;
Aurimas Liutikas67e2ae82016-10-11 18:17:42 -070036
Jeff Brownfa25bf52012-07-23 19:26:30 -070037/**
38 * Describes the characteristics of a particular logical display.
39 * @hide
40 */
41public final class DisplayInfo implements Parcelable {
42 /**
Jeff Brown4ed8fe72012-08-30 18:18:29 -070043 * The surface flinger layer stack associated with this logical display.
44 */
45 public int layerStack;
46
47 /**
Jeff Brownc5df37c2012-09-13 11:45:07 -070048 * Display flags.
49 */
50 public int flags;
51
52 /**
Jeff Brown92130f62012-10-24 21:28:33 -070053 * Display type.
54 */
55 public int type;
56
57 /**
58 * Display address, or null if none.
59 * Interpretation varies by display type.
60 */
61 public String address;
62
63 /**
Jeff Brown4ed8fe72012-08-30 18:18:29 -070064 * The human-readable name of the display.
65 */
66 public String name;
67
68 /**
Wale Ogunwale361ca212014-11-20 11:42:38 -080069 * Unique identifier for the display. Shouldn't be displayed to the user.
70 */
71 public String uniqueId;
72
73 /**
Jeff Brownfa25bf52012-07-23 19:26:30 -070074 * The width of the portion of the display that is available to applications, in pixels.
75 * Represents the size of the display minus any system decorations.
76 */
77 public int appWidth;
78
79 /**
80 * The height of the portion of the display that is available to applications, in pixels.
81 * Represents the size of the display minus any system decorations.
82 */
83 public int appHeight;
84
85 /**
86 * The smallest value of {@link #appWidth} that an application is likely to encounter,
87 * in pixels, excepting cases where the width may be even smaller due to the presence
88 * of a soft keyboard, for example.
89 */
90 public int smallestNominalAppWidth;
91
92 /**
93 * The smallest value of {@link #appHeight} that an application is likely to encounter,
94 * in pixels, excepting cases where the height may be even smaller due to the presence
95 * of a soft keyboard, for example.
96 */
97 public int smallestNominalAppHeight;
98
99 /**
100 * The largest value of {@link #appWidth} that an application is likely to encounter,
101 * in pixels, excepting cases where the width may be even larger due to system decorations
102 * such as the status bar being hidden, for example.
103 */
104 public int largestNominalAppWidth;
105
106 /**
107 * The largest value of {@link #appHeight} that an application is likely to encounter,
108 * in pixels, excepting cases where the height may be even larger due to system decorations
109 * such as the status bar being hidden, for example.
110 */
111 public int largestNominalAppHeight;
112
113 /**
114 * The logical width 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 logicalWidth;
119
120 /**
121 * The logical height of the display, in pixels.
122 * Represents the usable size of the display which may be smaller than the
123 * physical size when the system is emulating a smaller display.
124 */
125 public int logicalHeight;
126
127 /**
Dianne Hackbornc652de82013-02-15 16:32:56 -0800128 * @hide
129 * Number of overscan pixels on the left side of the display.
130 */
131 public int overscanLeft;
132
133 /**
134 * @hide
135 * Number of overscan pixels on the top side of the display.
136 */
137 public int overscanTop;
138
139 /**
140 * @hide
141 * Number of overscan pixels on the right side of the display.
142 */
143 public int overscanRight;
144
145 /**
146 * @hide
147 * Number of overscan pixels on the bottom side of the display.
148 */
149 public int overscanBottom;
150
151 /**
Adrian Roos1cf585052018-01-03 18:43:27 +0100152 * The {@link DisplayCutout} if present, otherwise {@code null}.
153 *
154 * @hide
155 */
156 public DisplayCutout displayCutout;
157
158 /**
Jeff Brownfa25bf52012-07-23 19:26:30 -0700159 * The rotation of the display relative to its natural orientation.
160 * May be one of {@link android.view.Surface#ROTATION_0},
161 * {@link android.view.Surface#ROTATION_90}, {@link android.view.Surface#ROTATION_180},
162 * {@link android.view.Surface#ROTATION_270}.
163 * <p>
164 * The value of this field is indeterminate if the logical display is presented on
165 * more than one physical display.
166 * </p>
167 */
Tor Norbyed9273d62013-05-30 15:59:53 -0700168 @Surface.Rotation
Jeff Brownfa25bf52012-07-23 19:26:30 -0700169 public int rotation;
170
171 /**
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700172 * The active display mode.
Jeff Brownfa25bf52012-07-23 19:26:30 -0700173 */
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700174 public int modeId;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700175
176 /**
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700177 * The default display mode.
Michael Wright3f145a22014-07-22 19:46:03 -0700178 */
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700179 public int defaultModeId;
180
181 /**
182 * The supported modes of this display.
183 */
184 public Display.Mode[] supportedModes = Display.Mode.EMPTY_ARRAY;
Michael Wright3f145a22014-07-22 19:46:03 -0700185
Michael Wright1c9977b2016-07-12 13:30:10 -0700186 /** The active color mode. */
187 public int colorMode;
Michael Wright58e829f2015-09-15 00:13:26 +0100188
Michael Wright1c9977b2016-07-12 13:30:10 -0700189 /** The list of supported color modes */
190 public int[] supportedColorModes = { Display.COLOR_MODE_DEFAULT };
Michael Wright58e829f2015-09-15 00:13:26 +0100191
Michael Wright9ff94c02016-03-30 18:05:40 -0700192 /** The display's HDR capabilities */
193 public Display.HdrCapabilities hdrCapabilities;
194
Michael Wright3f145a22014-07-22 19:46:03 -0700195 /**
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700196 * The logical display density which is the basis for density-independent
197 * pixels.
Jeff Brownfa25bf52012-07-23 19:26:30 -0700198 */
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700199 public int logicalDensityDpi;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700200
201 /**
202 * The exact physical pixels per inch of the screen in the X dimension.
203 * <p>
204 * The value of this field is indeterminate if the logical display is presented on
205 * more than one physical display.
206 * </p>
207 */
208 public float physicalXDpi;
209
210 /**
211 * The exact physical pixels per inch of the screen in the Y dimension.
212 * <p>
213 * The value of this field is indeterminate if the logical display is presented on
214 * more than one physical display.
215 * </p>
216 */
217 public float physicalYDpi;
218
Jeff Browna506a6e2013-06-04 00:02:38 -0700219 /**
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700220 * This is a positive value indicating the phase offset of the VSYNC events provided by
221 * Choreographer relative to the display refresh. For example, if Choreographer reports
222 * that the refresh occurred at time N, it actually occurred at (N - appVsyncOffsetNanos).
223 */
224 public long appVsyncOffsetNanos;
225
226 /**
227 * This is how far in advance a buffer must be queued for presentation at
228 * a given time. If you want a buffer to appear on the screen at
229 * time N, you must submit the buffer before (N - bufferDeadlineNanos).
230 */
231 public long presentationDeadlineNanos;
232
233 /**
Jeff Brown037c33e2014-04-09 00:31:55 -0700234 * The state of the display, such as {@link android.view.Display#STATE_ON}.
235 */
236 public int state;
237
238 /**
Jeff Browna506a6e2013-06-04 00:02:38 -0700239 * The UID of the application that owns this display, or zero if it is owned by the system.
240 * <p>
241 * If the display is private, then only the owner can use it.
242 * </p>
243 */
244 public int ownerUid;
245
246 /**
247 * The package name of the application that owns this display, or null if it is
248 * owned by the system.
249 * <p>
250 * If the display is private, then only the owner can use it.
251 * </p>
252 */
253 public String ownerPackageName;
254
Andrii Kulian250d6532017-02-08 23:30:45 -0800255 /**
256 * @hide
257 * Get current remove mode of the display - what actions should be performed with the display's
258 * content when it is removed.
259 *
260 * @see Display#getRemoveMode()
261 */
262 public int removeMode = Display.REMOVE_MODE_MOVE_CONTENT_TO_PRIMARY;
263
Jeff Brownfa25bf52012-07-23 19:26:30 -0700264 public static final Creator<DisplayInfo> CREATOR = new Creator<DisplayInfo>() {
Jeff Brown92130f62012-10-24 21:28:33 -0700265 @Override
Jeff Brownfa25bf52012-07-23 19:26:30 -0700266 public DisplayInfo createFromParcel(Parcel source) {
267 return new DisplayInfo(source);
268 }
269
Jeff Brown92130f62012-10-24 21:28:33 -0700270 @Override
Jeff Brownfa25bf52012-07-23 19:26:30 -0700271 public DisplayInfo[] newArray(int size) {
272 return new DisplayInfo[size];
273 }
274 };
275
276 public DisplayInfo() {
277 }
278
Jeff Brownbd6e1502012-08-28 03:27:37 -0700279 public DisplayInfo(DisplayInfo other) {
280 copyFrom(other);
281 }
282
Jeff Brownfa25bf52012-07-23 19:26:30 -0700283 private DisplayInfo(Parcel source) {
284 readFromParcel(source);
285 }
286
287 @Override
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700288 public boolean equals(Object o) {
289 return o instanceof DisplayInfo && equals((DisplayInfo)o);
290 }
291
292 public boolean equals(DisplayInfo other) {
293 return other != null
294 && layerStack == other.layerStack
Jeff Brown92130f62012-10-24 21:28:33 -0700295 && flags == other.flags
296 && type == other.type
Narayan Kamath607223f2018-02-19 14:09:02 +0000297 && Objects.equals(address, other.address)
298 && Objects.equals(uniqueId, other.uniqueId)
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700299 && appWidth == other.appWidth
300 && appHeight == other.appHeight
301 && smallestNominalAppWidth == other.smallestNominalAppWidth
302 && smallestNominalAppHeight == other.smallestNominalAppHeight
303 && largestNominalAppWidth == other.largestNominalAppWidth
304 && largestNominalAppHeight == other.largestNominalAppHeight
305 && logicalWidth == other.logicalWidth
306 && logicalHeight == other.logicalHeight
Dianne Hackbornc652de82013-02-15 16:32:56 -0800307 && overscanLeft == other.overscanLeft
308 && overscanTop == other.overscanTop
309 && overscanRight == other.overscanRight
310 && overscanBottom == other.overscanBottom
Narayan Kamath607223f2018-02-19 14:09:02 +0000311 && Objects.equals(displayCutout, other.displayCutout)
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700312 && rotation == other.rotation
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700313 && modeId == other.modeId
314 && defaultModeId == other.defaultModeId
Michael Wright1c9977b2016-07-12 13:30:10 -0700315 && colorMode == other.colorMode
Michael Wright16ae0422016-07-26 18:18:53 +0100316 && Arrays.equals(supportedColorModes, other.supportedColorModes)
Narayan Kamath607223f2018-02-19 14:09:02 +0000317 && Objects.equals(hdrCapabilities, other.hdrCapabilities)
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700318 && logicalDensityDpi == other.logicalDensityDpi
319 && physicalXDpi == other.physicalXDpi
Jeff Browna506a6e2013-06-04 00:02:38 -0700320 && physicalYDpi == other.physicalYDpi
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700321 && appVsyncOffsetNanos == other.appVsyncOffsetNanos
322 && presentationDeadlineNanos == other.presentationDeadlineNanos
Jeff Brown037c33e2014-04-09 00:31:55 -0700323 && state == other.state
Jeff Browna506a6e2013-06-04 00:02:38 -0700324 && ownerUid == other.ownerUid
Narayan Kamath607223f2018-02-19 14:09:02 +0000325 && Objects.equals(ownerPackageName, other.ownerPackageName)
Andrii Kulian250d6532017-02-08 23:30:45 -0800326 && removeMode == other.removeMode;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700327 }
328
329 @Override
330 public int hashCode() {
331 return 0; // don't care
Jeff Brownfa25bf52012-07-23 19:26:30 -0700332 }
333
334 public void copyFrom(DisplayInfo other) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700335 layerStack = other.layerStack;
Jeff Brownc5df37c2012-09-13 11:45:07 -0700336 flags = other.flags;
Jeff Brown92130f62012-10-24 21:28:33 -0700337 type = other.type;
338 address = other.address;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700339 name = other.name;
Wale Ogunwale361ca212014-11-20 11:42:38 -0800340 uniqueId = other.uniqueId;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700341 appWidth = other.appWidth;
342 appHeight = other.appHeight;
343 smallestNominalAppWidth = other.smallestNominalAppWidth;
344 smallestNominalAppHeight = other.smallestNominalAppHeight;
345 largestNominalAppWidth = other.largestNominalAppWidth;
346 largestNominalAppHeight = other.largestNominalAppHeight;
347 logicalWidth = other.logicalWidth;
348 logicalHeight = other.logicalHeight;
Dianne Hackbornc652de82013-02-15 16:32:56 -0800349 overscanLeft = other.overscanLeft;
350 overscanTop = other.overscanTop;
351 overscanRight = other.overscanRight;
352 overscanBottom = other.overscanBottom;
Adrian Roos1cf585052018-01-03 18:43:27 +0100353 displayCutout = other.displayCutout;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700354 rotation = other.rotation;
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700355 modeId = other.modeId;
356 defaultModeId = other.defaultModeId;
357 supportedModes = Arrays.copyOf(other.supportedModes, other.supportedModes.length);
Michael Wright1c9977b2016-07-12 13:30:10 -0700358 colorMode = other.colorMode;
359 supportedColorModes = Arrays.copyOf(
360 other.supportedColorModes, other.supportedColorModes.length);
Michael Wright9ff94c02016-03-30 18:05:40 -0700361 hdrCapabilities = other.hdrCapabilities;
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700362 logicalDensityDpi = other.logicalDensityDpi;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700363 physicalXDpi = other.physicalXDpi;
364 physicalYDpi = other.physicalYDpi;
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700365 appVsyncOffsetNanos = other.appVsyncOffsetNanos;
366 presentationDeadlineNanos = other.presentationDeadlineNanos;
Jeff Brown037c33e2014-04-09 00:31:55 -0700367 state = other.state;
Jeff Browna506a6e2013-06-04 00:02:38 -0700368 ownerUid = other.ownerUid;
369 ownerPackageName = other.ownerPackageName;
Andrii Kulian250d6532017-02-08 23:30:45 -0800370 removeMode = other.removeMode;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700371 }
372
373 public void readFromParcel(Parcel source) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700374 layerStack = source.readInt();
Jeff Brownc5df37c2012-09-13 11:45:07 -0700375 flags = source.readInt();
Jeff Brown92130f62012-10-24 21:28:33 -0700376 type = source.readInt();
377 address = source.readString();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700378 name = source.readString();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700379 appWidth = source.readInt();
380 appHeight = source.readInt();
381 smallestNominalAppWidth = source.readInt();
382 smallestNominalAppHeight = source.readInt();
383 largestNominalAppWidth = source.readInt();
384 largestNominalAppHeight = source.readInt();
385 logicalWidth = source.readInt();
386 logicalHeight = source.readInt();
Dianne Hackbornc652de82013-02-15 16:32:56 -0800387 overscanLeft = source.readInt();
388 overscanTop = source.readInt();
389 overscanRight = source.readInt();
390 overscanBottom = source.readInt();
Adrian Roos1cf585052018-01-03 18:43:27 +0100391 displayCutout = DisplayCutout.ParcelableWrapper.readCutoutFromParcel(source);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700392 rotation = source.readInt();
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700393 modeId = source.readInt();
394 defaultModeId = source.readInt();
395 int nModes = source.readInt();
396 supportedModes = new Display.Mode[nModes];
397 for (int i = 0; i < nModes; i++) {
398 supportedModes[i] = Display.Mode.CREATOR.createFromParcel(source);
399 }
Michael Wright1c9977b2016-07-12 13:30:10 -0700400 colorMode = source.readInt();
401 int nColorModes = source.readInt();
402 supportedColorModes = new int[nColorModes];
403 for (int i = 0; i < nColorModes; i++) {
404 supportedColorModes[i] = source.readInt();
Michael Wright58e829f2015-09-15 00:13:26 +0100405 }
Michael Wrightb0828902016-04-27 19:26:16 -0400406 hdrCapabilities = source.readParcelable(null);
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700407 logicalDensityDpi = source.readInt();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700408 physicalXDpi = source.readFloat();
409 physicalYDpi = source.readFloat();
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700410 appVsyncOffsetNanos = source.readLong();
411 presentationDeadlineNanos = source.readLong();
Jeff Brown037c33e2014-04-09 00:31:55 -0700412 state = source.readInt();
Jeff Browna506a6e2013-06-04 00:02:38 -0700413 ownerUid = source.readInt();
414 ownerPackageName = source.readString();
Wale Ogunwale361ca212014-11-20 11:42:38 -0800415 uniqueId = source.readString();
Andrii Kulian250d6532017-02-08 23:30:45 -0800416 removeMode = source.readInt();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700417 }
418
419 @Override
420 public void writeToParcel(Parcel dest, int flags) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700421 dest.writeInt(layerStack);
Jeff Brown3f2ba622012-10-04 14:57:44 -0700422 dest.writeInt(this.flags);
Jeff Brown92130f62012-10-24 21:28:33 -0700423 dest.writeInt(type);
424 dest.writeString(address);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700425 dest.writeString(name);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700426 dest.writeInt(appWidth);
427 dest.writeInt(appHeight);
428 dest.writeInt(smallestNominalAppWidth);
429 dest.writeInt(smallestNominalAppHeight);
430 dest.writeInt(largestNominalAppWidth);
431 dest.writeInt(largestNominalAppHeight);
432 dest.writeInt(logicalWidth);
433 dest.writeInt(logicalHeight);
Dianne Hackbornc652de82013-02-15 16:32:56 -0800434 dest.writeInt(overscanLeft);
435 dest.writeInt(overscanTop);
436 dest.writeInt(overscanRight);
437 dest.writeInt(overscanBottom);
Adrian Roos1cf585052018-01-03 18:43:27 +0100438 DisplayCutout.ParcelableWrapper.writeCutoutToParcel(displayCutout, dest, flags);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700439 dest.writeInt(rotation);
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700440 dest.writeInt(modeId);
441 dest.writeInt(defaultModeId);
442 dest.writeInt(supportedModes.length);
443 for (int i = 0; i < supportedModes.length; i++) {
444 supportedModes[i].writeToParcel(dest, flags);
445 }
Michael Wright1c9977b2016-07-12 13:30:10 -0700446 dest.writeInt(colorMode);
447 dest.writeInt(supportedColorModes.length);
448 for (int i = 0; i < supportedColorModes.length; i++) {
449 dest.writeInt(supportedColorModes[i]);
Michael Wright58e829f2015-09-15 00:13:26 +0100450 }
Michael Wrightb0828902016-04-27 19:26:16 -0400451 dest.writeParcelable(hdrCapabilities, flags);
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700452 dest.writeInt(logicalDensityDpi);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700453 dest.writeFloat(physicalXDpi);
454 dest.writeFloat(physicalYDpi);
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700455 dest.writeLong(appVsyncOffsetNanos);
456 dest.writeLong(presentationDeadlineNanos);
Jeff Brown037c33e2014-04-09 00:31:55 -0700457 dest.writeInt(state);
Jeff Browna506a6e2013-06-04 00:02:38 -0700458 dest.writeInt(ownerUid);
459 dest.writeString(ownerPackageName);
Wale Ogunwale361ca212014-11-20 11:42:38 -0800460 dest.writeString(uniqueId);
Andrii Kulian250d6532017-02-08 23:30:45 -0800461 dest.writeInt(removeMode);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700462 }
463
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700464 @Override
465 public int describeContents() {
466 return 0;
467 }
468
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700469 public Display.Mode getMode() {
470 return findMode(modeId);
471 }
472
473 public Display.Mode getDefaultMode() {
474 return findMode(defaultModeId);
475 }
476
477 private Display.Mode findMode(int id) {
478 for (int i = 0; i < supportedModes.length; i++) {
479 if (supportedModes[i].getModeId() == id) {
480 return supportedModes[i];
481 }
482 }
483 throw new IllegalStateException("Unable to locate mode " + id);
484 }
485
486 /**
487 * Returns the id of the "default" mode with the given refresh rate, or {@code 0} if no suitable
488 * mode could be found.
489 */
490 public int findDefaultModeByRefreshRate(float refreshRate) {
491 Display.Mode[] modes = supportedModes;
492 Display.Mode defaultMode = getDefaultMode();
493 for (int i = 0; i < modes.length; i++) {
494 if (modes[i].matches(
495 defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), refreshRate)) {
496 return modes[i].getModeId();
497 }
498 }
499 return 0;
500 }
501
502 /**
503 * Returns the list of supported refresh rates in the default mode.
504 */
505 public float[] getDefaultRefreshRates() {
506 Display.Mode[] modes = supportedModes;
507 ArraySet<Float> rates = new ArraySet<>();
508 Display.Mode defaultMode = getDefaultMode();
509 for (int i = 0; i < modes.length; i++) {
510 Display.Mode mode = modes[i];
511 if (mode.getPhysicalWidth() == defaultMode.getPhysicalWidth()
512 && mode.getPhysicalHeight() == defaultMode.getPhysicalHeight()) {
513 rates.add(mode.getRefreshRate());
514 }
515 }
516 float[] result = new float[rates.size()];
517 int i = 0;
518 for (Float rate : rates) {
519 result[i++] = rate;
520 }
521 return result;
522 }
523
Craig Mautner48d0d182013-06-11 07:53:06 -0700524 public void getAppMetrics(DisplayMetrics outMetrics) {
525 getAppMetrics(outMetrics, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700526 }
527
Craig Mautner48d0d182013-06-11 07:53:06 -0700528 public void getAppMetrics(DisplayMetrics outMetrics, DisplayAdjustments displayAdjustments) {
529 getMetricsWithSize(outMetrics, displayAdjustments.getCompatibilityInfo(),
Wale Ogunwale7c726682015-02-06 17:34:28 -0800530 displayAdjustments.getConfiguration(), appWidth, appHeight);
Craig Mautner48d0d182013-06-11 07:53:06 -0700531 }
532
Wale Ogunwale7c726682015-02-06 17:34:28 -0800533 public void getAppMetrics(DisplayMetrics outMetrics, CompatibilityInfo ci,
534 Configuration configuration) {
535 getMetricsWithSize(outMetrics, ci, configuration, appWidth, appHeight);
Craig Mautner48d0d182013-06-11 07:53:06 -0700536 }
537
538 public void getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
Wale Ogunwale7c726682015-02-06 17:34:28 -0800539 Configuration configuration) {
540 getMetricsWithSize(outMetrics, compatInfo, configuration, logicalWidth, logicalHeight);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700541 }
542
Jeff Brown7f3994e2012-12-04 14:04:28 -0800543 public int getNaturalWidth() {
544 return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ?
545 logicalWidth : logicalHeight;
546 }
547
548 public int getNaturalHeight() {
549 return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ?
550 logicalHeight : logicalWidth;
551 }
552
Romain Guy408afbf2017-01-25 10:23:03 -0800553 public boolean isHdr() {
Andrii Kulian4acfd852017-01-26 19:43:13 -0800554 int[] types = hdrCapabilities != null ? hdrCapabilities.getSupportedHdrTypes() : null;
Romain Guy408afbf2017-01-25 10:23:03 -0800555 return types != null && types.length > 0;
556 }
557
558 public boolean isWideColorGamut() {
559 for (int colorMode : supportedColorModes) {
560 if (colorMode == Display.COLOR_MODE_DCI_P3 || colorMode > Display.COLOR_MODE_SRGB) {
561 return true;
562 }
563 }
564 return false;
565 }
566
Jeff Browna506a6e2013-06-04 00:02:38 -0700567 /**
568 * Returns true if the specified UID has access to this display.
569 */
570 public boolean hasAccess(int uid) {
571 return Display.hasAccess(uid, flags, ownerUid);
572 }
573
Craig Mautner48d0d182013-06-11 07:53:06 -0700574 private void getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
Wale Ogunwale7c726682015-02-06 17:34:28 -0800575 Configuration configuration, int width, int height) {
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700576 outMetrics.densityDpi = outMetrics.noncompatDensityDpi = logicalDensityDpi;
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700577 outMetrics.density = outMetrics.noncompatDensity =
578 logicalDensityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700579 outMetrics.scaledDensity = outMetrics.noncompatScaledDensity = outMetrics.density;
580 outMetrics.xdpi = outMetrics.noncompatXdpi = physicalXDpi;
581 outMetrics.ydpi = outMetrics.noncompatYdpi = physicalYDpi;
582
Wale Ogunwale822e5122017-07-26 06:02:24 -0700583 final Rect appBounds = configuration != null
584 ? configuration.windowConfiguration.getAppBounds() : null;
585 width = appBounds != null ? appBounds.width() : width;
586 height = appBounds != null ? appBounds.height() : height;
Wale Ogunwale7c726682015-02-06 17:34:28 -0800587
588 outMetrics.noncompatWidthPixels = outMetrics.widthPixels = width;
589 outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height;
590
Craig Mautner48d0d182013-06-11 07:53:06 -0700591 if (!compatInfo.equals(CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO)) {
592 compatInfo.applyToDisplayMetrics(outMetrics);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700593 }
594 }
Jeff Brownbf5740e2012-08-19 23:20:02 -0700595
596 // For debugging purposes
597 @Override
598 public String toString() {
Dianne Hackbornc652de82013-02-15 16:32:56 -0800599 StringBuilder sb = new StringBuilder();
600 sb.append("DisplayInfo{\"");
601 sb.append(name);
Wale Ogunwale361ca212014-11-20 11:42:38 -0800602 sb.append("\", uniqueId \"");
603 sb.append(uniqueId);
Dianne Hackbornc652de82013-02-15 16:32:56 -0800604 sb.append("\", app ");
605 sb.append(appWidth);
606 sb.append(" x ");
607 sb.append(appHeight);
608 sb.append(", real ");
609 sb.append(logicalWidth);
610 sb.append(" x ");
611 sb.append(logicalHeight);
612 if (overscanLeft != 0 || overscanTop != 0 || overscanRight != 0 || overscanBottom != 0) {
613 sb.append(", overscan (");
614 sb.append(overscanLeft);
615 sb.append(",");
616 sb.append(overscanTop);
617 sb.append(",");
618 sb.append(overscanRight);
619 sb.append(",");
620 sb.append(overscanBottom);
621 sb.append(")");
622 }
623 sb.append(", largest app ");
624 sb.append(largestNominalAppWidth);
625 sb.append(" x ");
626 sb.append(largestNominalAppHeight);
627 sb.append(", smallest app ");
628 sb.append(smallestNominalAppWidth);
629 sb.append(" x ");
630 sb.append(smallestNominalAppHeight);
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700631 sb.append(", mode ");
632 sb.append(modeId);
633 sb.append(", defaultMode ");
634 sb.append(defaultModeId);
635 sb.append(", modes ");
636 sb.append(Arrays.toString(supportedModes));
Michael Wright1c9977b2016-07-12 13:30:10 -0700637 sb.append(", colorMode ");
638 sb.append(colorMode);
639 sb.append(", supportedColorModes ");
640 sb.append(Arrays.toString(supportedColorModes));
Michael Wright9ff94c02016-03-30 18:05:40 -0700641 sb.append(", hdrCapabilities ");
642 sb.append(hdrCapabilities);
Michael Wright3f145a22014-07-22 19:46:03 -0700643 sb.append(", rotation ");
Dianne Hackbornc652de82013-02-15 16:32:56 -0800644 sb.append(rotation);
645 sb.append(", density ");
646 sb.append(logicalDensityDpi);
647 sb.append(" (");
648 sb.append(physicalXDpi);
649 sb.append(" x ");
650 sb.append(physicalYDpi);
651 sb.append(") dpi, layerStack ");
652 sb.append(layerStack);
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700653 sb.append(", appVsyncOff ");
654 sb.append(appVsyncOffsetNanos);
655 sb.append(", presDeadline ");
656 sb.append(presentationDeadlineNanos);
Dianne Hackbornc652de82013-02-15 16:32:56 -0800657 sb.append(", type ");
658 sb.append(Display.typeToString(type));
Jeff Browna506a6e2013-06-04 00:02:38 -0700659 if (address != null) {
660 sb.append(", address ").append(address);
661 }
Jeff Brown037c33e2014-04-09 00:31:55 -0700662 sb.append(", state ");
663 sb.append(Display.stateToString(state));
Jeff Browna506a6e2013-06-04 00:02:38 -0700664 if (ownerUid != 0 || ownerPackageName != null) {
665 sb.append(", owner ").append(ownerPackageName);
666 sb.append(" (uid ").append(ownerUid).append(")");
667 }
Dianne Hackbornc652de82013-02-15 16:32:56 -0800668 sb.append(flagsToString(flags));
Andrii Kulian250d6532017-02-08 23:30:45 -0800669 sb.append(", removeMode ");
670 sb.append(removeMode);
Dianne Hackbornc652de82013-02-15 16:32:56 -0800671 sb.append("}");
672 return sb.toString();
Jeff Brownc5df37c2012-09-13 11:45:07 -0700673 }
674
Steven Timotiusaf03df62017-07-18 16:56:43 -0700675 /**
676 * Write to a protocol buffer output stream.
677 * Protocol buffer message definition at {@link android.view.DisplayInfoProto}
678 *
679 * @param protoOutputStream Stream to write the Rect object to.
680 * @param fieldId Field Id of the DisplayInfoProto as defined in the parent message
681 */
682 public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId) {
683 final long token = protoOutputStream.start(fieldId);
684 protoOutputStream.write(LOGICAL_WIDTH, logicalWidth);
685 protoOutputStream.write(LOGICAL_HEIGHT, logicalHeight);
686 protoOutputStream.write(APP_WIDTH, appWidth);
687 protoOutputStream.write(APP_HEIGHT, appHeight);
Andrii Kulian764e1042018-02-08 15:12:14 -0800688 protoOutputStream.write(NAME, name);
Steven Timotiusaf03df62017-07-18 16:56:43 -0700689 protoOutputStream.end(token);
690 }
691
Jeff Brownc5df37c2012-09-13 11:45:07 -0700692 private static String flagsToString(int flags) {
693 StringBuilder result = new StringBuilder();
Jeff Brownf0681b32012-10-23 17:35:57 -0700694 if ((flags & Display.FLAG_SECURE) != 0) {
695 result.append(", FLAG_SECURE");
696 }
Jeff Brown77aebfd2012-10-01 21:07:03 -0700697 if ((flags & Display.FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
698 result.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS");
Jeff Brownc5df37c2012-09-13 11:45:07 -0700699 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700700 if ((flags & Display.FLAG_PRIVATE) != 0) {
701 result.append(", FLAG_PRIVATE");
702 }
Jeff Brown7d00aff2013-08-02 19:03:49 -0700703 if ((flags & Display.FLAG_PRESENTATION) != 0) {
704 result.append(", FLAG_PRESENTATION");
705 }
Jeff Brownd46747a2015-04-15 19:02:36 -0700706 if ((flags & Display.FLAG_SCALING_DISABLED) != 0) {
707 result.append(", FLAG_SCALING_DISABLED");
708 }
Adam Powell49e7ff92015-05-14 16:18:53 -0700709 if ((flags & Display.FLAG_ROUND) != 0) {
710 result.append(", FLAG_ROUND");
711 }
Jeff Brownc5df37c2012-09-13 11:45:07 -0700712 return result.toString();
Jeff Brownbf5740e2012-08-19 23:20:02 -0700713 }
Jeff Brownfa25bf52012-07-23 19:26:30 -0700714}