blob: b813ddb63859e5a7fa29217549f255ec5ffb321e [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;
23
Jeff Brownfa25bf52012-07-23 19:26:30 -070024import android.content.res.CompatibilityInfo;
Wale Ogunwale7c726682015-02-06 17:34:28 -080025import android.content.res.Configuration;
Wale Ogunwale822e5122017-07-26 06:02:24 -070026import android.graphics.Rect;
Jeff Brownfa25bf52012-07-23 19:26:30 -070027import android.os.Parcel;
28import android.os.Parcelable;
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -070029import android.util.ArraySet;
Jeff Brownfa25bf52012-07-23 19:26:30 -070030import android.util.DisplayMetrics;
Steven Timotiusaf03df62017-07-18 16:56:43 -070031import android.util.proto.ProtoOutputStream;
Jeff Brownfa25bf52012-07-23 19:26:30 -070032
Jeff Brown4ed8fe72012-08-30 18:18:29 -070033import libcore.util.Objects;
34
Aurimas Liutikas67e2ae82016-10-11 18:17:42 -070035import java.util.Arrays;
36
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 /**
Jeff Brownfa25bf52012-07-23 19:26:30 -0700152 * The rotation of the display relative to its natural orientation.
153 * May be one of {@link android.view.Surface#ROTATION_0},
154 * {@link android.view.Surface#ROTATION_90}, {@link android.view.Surface#ROTATION_180},
155 * {@link android.view.Surface#ROTATION_270}.
156 * <p>
157 * The value of this field is indeterminate if the logical display is presented on
158 * more than one physical display.
159 * </p>
160 */
Tor Norbyed9273d62013-05-30 15:59:53 -0700161 @Surface.Rotation
Jeff Brownfa25bf52012-07-23 19:26:30 -0700162 public int rotation;
163
164 /**
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700165 * The active display mode.
Jeff Brownfa25bf52012-07-23 19:26:30 -0700166 */
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700167 public int modeId;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700168
169 /**
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700170 * The default display mode.
Michael Wright3f145a22014-07-22 19:46:03 -0700171 */
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700172 public int defaultModeId;
173
174 /**
175 * The supported modes of this display.
176 */
177 public Display.Mode[] supportedModes = Display.Mode.EMPTY_ARRAY;
Michael Wright3f145a22014-07-22 19:46:03 -0700178
Michael Wright1c9977b2016-07-12 13:30:10 -0700179 /** The active color mode. */
180 public int colorMode;
Michael Wright58e829f2015-09-15 00:13:26 +0100181
Michael Wright1c9977b2016-07-12 13:30:10 -0700182 /** The list of supported color modes */
183 public int[] supportedColorModes = { Display.COLOR_MODE_DEFAULT };
Michael Wright58e829f2015-09-15 00:13:26 +0100184
Michael Wright9ff94c02016-03-30 18:05:40 -0700185 /** The display's HDR capabilities */
186 public Display.HdrCapabilities hdrCapabilities;
187
Michael Wright3f145a22014-07-22 19:46:03 -0700188 /**
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700189 * The logical display density which is the basis for density-independent
190 * pixels.
Jeff Brownfa25bf52012-07-23 19:26:30 -0700191 */
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700192 public int logicalDensityDpi;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700193
194 /**
195 * The exact physical pixels per inch of the screen in the X dimension.
196 * <p>
197 * The value of this field is indeterminate if the logical display is presented on
198 * more than one physical display.
199 * </p>
200 */
201 public float physicalXDpi;
202
203 /**
204 * The exact physical pixels per inch of the screen in the Y dimension.
205 * <p>
206 * The value of this field is indeterminate if the logical display is presented on
207 * more than one physical display.
208 * </p>
209 */
210 public float physicalYDpi;
211
Jeff Browna506a6e2013-06-04 00:02:38 -0700212 /**
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700213 * This is a positive value indicating the phase offset of the VSYNC events provided by
214 * Choreographer relative to the display refresh. For example, if Choreographer reports
215 * that the refresh occurred at time N, it actually occurred at (N - appVsyncOffsetNanos).
216 */
217 public long appVsyncOffsetNanos;
218
219 /**
220 * This is how far in advance a buffer must be queued for presentation at
221 * a given time. If you want a buffer to appear on the screen at
222 * time N, you must submit the buffer before (N - bufferDeadlineNanos).
223 */
224 public long presentationDeadlineNanos;
225
226 /**
Jeff Brown037c33e2014-04-09 00:31:55 -0700227 * The state of the display, such as {@link android.view.Display#STATE_ON}.
228 */
229 public int state;
230
231 /**
Jeff Browna506a6e2013-06-04 00:02:38 -0700232 * The UID of the application that owns this display, or zero if it is owned by the system.
233 * <p>
234 * If the display is private, then only the owner can use it.
235 * </p>
236 */
237 public int ownerUid;
238
239 /**
240 * The package name of the application that owns this display, or null if it is
241 * owned by the system.
242 * <p>
243 * If the display is private, then only the owner can use it.
244 * </p>
245 */
246 public String ownerPackageName;
247
Andrii Kulian250d6532017-02-08 23:30:45 -0800248 /**
249 * @hide
250 * Get current remove mode of the display - what actions should be performed with the display's
251 * content when it is removed.
252 *
253 * @see Display#getRemoveMode()
254 */
255 public int removeMode = Display.REMOVE_MODE_MOVE_CONTENT_TO_PRIMARY;
256
Jeff Brownfa25bf52012-07-23 19:26:30 -0700257 public static final Creator<DisplayInfo> CREATOR = new Creator<DisplayInfo>() {
Jeff Brown92130f62012-10-24 21:28:33 -0700258 @Override
Jeff Brownfa25bf52012-07-23 19:26:30 -0700259 public DisplayInfo createFromParcel(Parcel source) {
260 return new DisplayInfo(source);
261 }
262
Jeff Brown92130f62012-10-24 21:28:33 -0700263 @Override
Jeff Brownfa25bf52012-07-23 19:26:30 -0700264 public DisplayInfo[] newArray(int size) {
265 return new DisplayInfo[size];
266 }
267 };
268
269 public DisplayInfo() {
270 }
271
Jeff Brownbd6e1502012-08-28 03:27:37 -0700272 public DisplayInfo(DisplayInfo other) {
273 copyFrom(other);
274 }
275
Jeff Brownfa25bf52012-07-23 19:26:30 -0700276 private DisplayInfo(Parcel source) {
277 readFromParcel(source);
278 }
279
280 @Override
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700281 public boolean equals(Object o) {
282 return o instanceof DisplayInfo && equals((DisplayInfo)o);
283 }
284
285 public boolean equals(DisplayInfo other) {
286 return other != null
287 && layerStack == other.layerStack
Jeff Brown92130f62012-10-24 21:28:33 -0700288 && flags == other.flags
289 && type == other.type
290 && Objects.equal(address, other.address)
Wale Ogunwale361ca212014-11-20 11:42:38 -0800291 && Objects.equal(uniqueId, other.uniqueId)
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700292 && appWidth == other.appWidth
293 && appHeight == other.appHeight
294 && smallestNominalAppWidth == other.smallestNominalAppWidth
295 && smallestNominalAppHeight == other.smallestNominalAppHeight
296 && largestNominalAppWidth == other.largestNominalAppWidth
297 && largestNominalAppHeight == other.largestNominalAppHeight
298 && logicalWidth == other.logicalWidth
299 && logicalHeight == other.logicalHeight
Dianne Hackbornc652de82013-02-15 16:32:56 -0800300 && overscanLeft == other.overscanLeft
301 && overscanTop == other.overscanTop
302 && overscanRight == other.overscanRight
303 && overscanBottom == other.overscanBottom
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700304 && rotation == other.rotation
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700305 && modeId == other.modeId
306 && defaultModeId == other.defaultModeId
Michael Wright1c9977b2016-07-12 13:30:10 -0700307 && colorMode == other.colorMode
Michael Wright16ae0422016-07-26 18:18:53 +0100308 && Arrays.equals(supportedColorModes, other.supportedColorModes)
Michael Wright9ff94c02016-03-30 18:05:40 -0700309 && Objects.equal(hdrCapabilities, other.hdrCapabilities)
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700310 && logicalDensityDpi == other.logicalDensityDpi
311 && physicalXDpi == other.physicalXDpi
Jeff Browna506a6e2013-06-04 00:02:38 -0700312 && physicalYDpi == other.physicalYDpi
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700313 && appVsyncOffsetNanos == other.appVsyncOffsetNanos
314 && presentationDeadlineNanos == other.presentationDeadlineNanos
Jeff Brown037c33e2014-04-09 00:31:55 -0700315 && state == other.state
Jeff Browna506a6e2013-06-04 00:02:38 -0700316 && ownerUid == other.ownerUid
Andrii Kulian250d6532017-02-08 23:30:45 -0800317 && Objects.equal(ownerPackageName, other.ownerPackageName)
318 && removeMode == other.removeMode;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700319 }
320
321 @Override
322 public int hashCode() {
323 return 0; // don't care
Jeff Brownfa25bf52012-07-23 19:26:30 -0700324 }
325
326 public void copyFrom(DisplayInfo other) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700327 layerStack = other.layerStack;
Jeff Brownc5df37c2012-09-13 11:45:07 -0700328 flags = other.flags;
Jeff Brown92130f62012-10-24 21:28:33 -0700329 type = other.type;
330 address = other.address;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700331 name = other.name;
Wale Ogunwale361ca212014-11-20 11:42:38 -0800332 uniqueId = other.uniqueId;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700333 appWidth = other.appWidth;
334 appHeight = other.appHeight;
335 smallestNominalAppWidth = other.smallestNominalAppWidth;
336 smallestNominalAppHeight = other.smallestNominalAppHeight;
337 largestNominalAppWidth = other.largestNominalAppWidth;
338 largestNominalAppHeight = other.largestNominalAppHeight;
339 logicalWidth = other.logicalWidth;
340 logicalHeight = other.logicalHeight;
Dianne Hackbornc652de82013-02-15 16:32:56 -0800341 overscanLeft = other.overscanLeft;
342 overscanTop = other.overscanTop;
343 overscanRight = other.overscanRight;
344 overscanBottom = other.overscanBottom;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700345 rotation = other.rotation;
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700346 modeId = other.modeId;
347 defaultModeId = other.defaultModeId;
348 supportedModes = Arrays.copyOf(other.supportedModes, other.supportedModes.length);
Michael Wright1c9977b2016-07-12 13:30:10 -0700349 colorMode = other.colorMode;
350 supportedColorModes = Arrays.copyOf(
351 other.supportedColorModes, other.supportedColorModes.length);
Michael Wright9ff94c02016-03-30 18:05:40 -0700352 hdrCapabilities = other.hdrCapabilities;
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700353 logicalDensityDpi = other.logicalDensityDpi;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700354 physicalXDpi = other.physicalXDpi;
355 physicalYDpi = other.physicalYDpi;
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700356 appVsyncOffsetNanos = other.appVsyncOffsetNanos;
357 presentationDeadlineNanos = other.presentationDeadlineNanos;
Jeff Brown037c33e2014-04-09 00:31:55 -0700358 state = other.state;
Jeff Browna506a6e2013-06-04 00:02:38 -0700359 ownerUid = other.ownerUid;
360 ownerPackageName = other.ownerPackageName;
Andrii Kulian250d6532017-02-08 23:30:45 -0800361 removeMode = other.removeMode;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700362 }
363
364 public void readFromParcel(Parcel source) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700365 layerStack = source.readInt();
Jeff Brownc5df37c2012-09-13 11:45:07 -0700366 flags = source.readInt();
Jeff Brown92130f62012-10-24 21:28:33 -0700367 type = source.readInt();
368 address = source.readString();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700369 name = source.readString();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700370 appWidth = source.readInt();
371 appHeight = source.readInt();
372 smallestNominalAppWidth = source.readInt();
373 smallestNominalAppHeight = source.readInt();
374 largestNominalAppWidth = source.readInt();
375 largestNominalAppHeight = source.readInt();
376 logicalWidth = source.readInt();
377 logicalHeight = source.readInt();
Dianne Hackbornc652de82013-02-15 16:32:56 -0800378 overscanLeft = source.readInt();
379 overscanTop = source.readInt();
380 overscanRight = source.readInt();
381 overscanBottom = source.readInt();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700382 rotation = source.readInt();
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700383 modeId = source.readInt();
384 defaultModeId = source.readInt();
385 int nModes = source.readInt();
386 supportedModes = new Display.Mode[nModes];
387 for (int i = 0; i < nModes; i++) {
388 supportedModes[i] = Display.Mode.CREATOR.createFromParcel(source);
389 }
Michael Wright1c9977b2016-07-12 13:30:10 -0700390 colorMode = source.readInt();
391 int nColorModes = source.readInt();
392 supportedColorModes = new int[nColorModes];
393 for (int i = 0; i < nColorModes; i++) {
394 supportedColorModes[i] = source.readInt();
Michael Wright58e829f2015-09-15 00:13:26 +0100395 }
Michael Wrightb0828902016-04-27 19:26:16 -0400396 hdrCapabilities = source.readParcelable(null);
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700397 logicalDensityDpi = source.readInt();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700398 physicalXDpi = source.readFloat();
399 physicalYDpi = source.readFloat();
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700400 appVsyncOffsetNanos = source.readLong();
401 presentationDeadlineNanos = source.readLong();
Jeff Brown037c33e2014-04-09 00:31:55 -0700402 state = source.readInt();
Jeff Browna506a6e2013-06-04 00:02:38 -0700403 ownerUid = source.readInt();
404 ownerPackageName = source.readString();
Wale Ogunwale361ca212014-11-20 11:42:38 -0800405 uniqueId = source.readString();
Andrii Kulian250d6532017-02-08 23:30:45 -0800406 removeMode = source.readInt();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700407 }
408
409 @Override
410 public void writeToParcel(Parcel dest, int flags) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700411 dest.writeInt(layerStack);
Jeff Brown3f2ba622012-10-04 14:57:44 -0700412 dest.writeInt(this.flags);
Jeff Brown92130f62012-10-24 21:28:33 -0700413 dest.writeInt(type);
414 dest.writeString(address);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700415 dest.writeString(name);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700416 dest.writeInt(appWidth);
417 dest.writeInt(appHeight);
418 dest.writeInt(smallestNominalAppWidth);
419 dest.writeInt(smallestNominalAppHeight);
420 dest.writeInt(largestNominalAppWidth);
421 dest.writeInt(largestNominalAppHeight);
422 dest.writeInt(logicalWidth);
423 dest.writeInt(logicalHeight);
Dianne Hackbornc652de82013-02-15 16:32:56 -0800424 dest.writeInt(overscanLeft);
425 dest.writeInt(overscanTop);
426 dest.writeInt(overscanRight);
427 dest.writeInt(overscanBottom);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700428 dest.writeInt(rotation);
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700429 dest.writeInt(modeId);
430 dest.writeInt(defaultModeId);
431 dest.writeInt(supportedModes.length);
432 for (int i = 0; i < supportedModes.length; i++) {
433 supportedModes[i].writeToParcel(dest, flags);
434 }
Michael Wright1c9977b2016-07-12 13:30:10 -0700435 dest.writeInt(colorMode);
436 dest.writeInt(supportedColorModes.length);
437 for (int i = 0; i < supportedColorModes.length; i++) {
438 dest.writeInt(supportedColorModes[i]);
Michael Wright58e829f2015-09-15 00:13:26 +0100439 }
Michael Wrightb0828902016-04-27 19:26:16 -0400440 dest.writeParcelable(hdrCapabilities, flags);
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700441 dest.writeInt(logicalDensityDpi);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700442 dest.writeFloat(physicalXDpi);
443 dest.writeFloat(physicalYDpi);
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700444 dest.writeLong(appVsyncOffsetNanos);
445 dest.writeLong(presentationDeadlineNanos);
Jeff Brown037c33e2014-04-09 00:31:55 -0700446 dest.writeInt(state);
Jeff Browna506a6e2013-06-04 00:02:38 -0700447 dest.writeInt(ownerUid);
448 dest.writeString(ownerPackageName);
Wale Ogunwale361ca212014-11-20 11:42:38 -0800449 dest.writeString(uniqueId);
Andrii Kulian250d6532017-02-08 23:30:45 -0800450 dest.writeInt(removeMode);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700451 }
452
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700453 @Override
454 public int describeContents() {
455 return 0;
456 }
457
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700458 public Display.Mode getMode() {
459 return findMode(modeId);
460 }
461
462 public Display.Mode getDefaultMode() {
463 return findMode(defaultModeId);
464 }
465
466 private Display.Mode findMode(int id) {
467 for (int i = 0; i < supportedModes.length; i++) {
468 if (supportedModes[i].getModeId() == id) {
469 return supportedModes[i];
470 }
471 }
472 throw new IllegalStateException("Unable to locate mode " + id);
473 }
474
475 /**
476 * Returns the id of the "default" mode with the given refresh rate, or {@code 0} if no suitable
477 * mode could be found.
478 */
479 public int findDefaultModeByRefreshRate(float refreshRate) {
480 Display.Mode[] modes = supportedModes;
481 Display.Mode defaultMode = getDefaultMode();
482 for (int i = 0; i < modes.length; i++) {
483 if (modes[i].matches(
484 defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), refreshRate)) {
485 return modes[i].getModeId();
486 }
487 }
488 return 0;
489 }
490
491 /**
492 * Returns the list of supported refresh rates in the default mode.
493 */
494 public float[] getDefaultRefreshRates() {
495 Display.Mode[] modes = supportedModes;
496 ArraySet<Float> rates = new ArraySet<>();
497 Display.Mode defaultMode = getDefaultMode();
498 for (int i = 0; i < modes.length; i++) {
499 Display.Mode mode = modes[i];
500 if (mode.getPhysicalWidth() == defaultMode.getPhysicalWidth()
501 && mode.getPhysicalHeight() == defaultMode.getPhysicalHeight()) {
502 rates.add(mode.getRefreshRate());
503 }
504 }
505 float[] result = new float[rates.size()];
506 int i = 0;
507 for (Float rate : rates) {
508 result[i++] = rate;
509 }
510 return result;
511 }
512
Craig Mautner48d0d182013-06-11 07:53:06 -0700513 public void getAppMetrics(DisplayMetrics outMetrics) {
514 getAppMetrics(outMetrics, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700515 }
516
Craig Mautner48d0d182013-06-11 07:53:06 -0700517 public void getAppMetrics(DisplayMetrics outMetrics, DisplayAdjustments displayAdjustments) {
518 getMetricsWithSize(outMetrics, displayAdjustments.getCompatibilityInfo(),
Wale Ogunwale7c726682015-02-06 17:34:28 -0800519 displayAdjustments.getConfiguration(), appWidth, appHeight);
Craig Mautner48d0d182013-06-11 07:53:06 -0700520 }
521
Wale Ogunwale7c726682015-02-06 17:34:28 -0800522 public void getAppMetrics(DisplayMetrics outMetrics, CompatibilityInfo ci,
523 Configuration configuration) {
524 getMetricsWithSize(outMetrics, ci, configuration, appWidth, appHeight);
Craig Mautner48d0d182013-06-11 07:53:06 -0700525 }
526
527 public void getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
Wale Ogunwale7c726682015-02-06 17:34:28 -0800528 Configuration configuration) {
529 getMetricsWithSize(outMetrics, compatInfo, configuration, logicalWidth, logicalHeight);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700530 }
531
Jeff Brown7f3994e2012-12-04 14:04:28 -0800532 public int getNaturalWidth() {
533 return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ?
534 logicalWidth : logicalHeight;
535 }
536
537 public int getNaturalHeight() {
538 return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ?
539 logicalHeight : logicalWidth;
540 }
541
Romain Guy408afbf2017-01-25 10:23:03 -0800542 public boolean isHdr() {
Andrii Kulian4acfd852017-01-26 19:43:13 -0800543 int[] types = hdrCapabilities != null ? hdrCapabilities.getSupportedHdrTypes() : null;
Romain Guy408afbf2017-01-25 10:23:03 -0800544 return types != null && types.length > 0;
545 }
546
547 public boolean isWideColorGamut() {
548 for (int colorMode : supportedColorModes) {
549 if (colorMode == Display.COLOR_MODE_DCI_P3 || colorMode > Display.COLOR_MODE_SRGB) {
550 return true;
551 }
552 }
553 return false;
554 }
555
Jeff Browna506a6e2013-06-04 00:02:38 -0700556 /**
557 * Returns true if the specified UID has access to this display.
558 */
559 public boolean hasAccess(int uid) {
560 return Display.hasAccess(uid, flags, ownerUid);
561 }
562
Craig Mautner48d0d182013-06-11 07:53:06 -0700563 private void getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
Wale Ogunwale7c726682015-02-06 17:34:28 -0800564 Configuration configuration, int width, int height) {
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700565 outMetrics.densityDpi = outMetrics.noncompatDensityDpi = logicalDensityDpi;
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700566 outMetrics.density = outMetrics.noncompatDensity =
567 logicalDensityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700568 outMetrics.scaledDensity = outMetrics.noncompatScaledDensity = outMetrics.density;
569 outMetrics.xdpi = outMetrics.noncompatXdpi = physicalXDpi;
570 outMetrics.ydpi = outMetrics.noncompatYdpi = physicalYDpi;
571
Wale Ogunwale822e5122017-07-26 06:02:24 -0700572 final Rect appBounds = configuration != null
573 ? configuration.windowConfiguration.getAppBounds() : null;
574 width = appBounds != null ? appBounds.width() : width;
575 height = appBounds != null ? appBounds.height() : height;
Wale Ogunwale7c726682015-02-06 17:34:28 -0800576
577 outMetrics.noncompatWidthPixels = outMetrics.widthPixels = width;
578 outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height;
579
Craig Mautner48d0d182013-06-11 07:53:06 -0700580 if (!compatInfo.equals(CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO)) {
581 compatInfo.applyToDisplayMetrics(outMetrics);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700582 }
583 }
Jeff Brownbf5740e2012-08-19 23:20:02 -0700584
585 // For debugging purposes
586 @Override
587 public String toString() {
Dianne Hackbornc652de82013-02-15 16:32:56 -0800588 StringBuilder sb = new StringBuilder();
589 sb.append("DisplayInfo{\"");
590 sb.append(name);
Wale Ogunwale361ca212014-11-20 11:42:38 -0800591 sb.append("\", uniqueId \"");
592 sb.append(uniqueId);
Dianne Hackbornc652de82013-02-15 16:32:56 -0800593 sb.append("\", app ");
594 sb.append(appWidth);
595 sb.append(" x ");
596 sb.append(appHeight);
597 sb.append(", real ");
598 sb.append(logicalWidth);
599 sb.append(" x ");
600 sb.append(logicalHeight);
601 if (overscanLeft != 0 || overscanTop != 0 || overscanRight != 0 || overscanBottom != 0) {
602 sb.append(", overscan (");
603 sb.append(overscanLeft);
604 sb.append(",");
605 sb.append(overscanTop);
606 sb.append(",");
607 sb.append(overscanRight);
608 sb.append(",");
609 sb.append(overscanBottom);
610 sb.append(")");
611 }
612 sb.append(", largest app ");
613 sb.append(largestNominalAppWidth);
614 sb.append(" x ");
615 sb.append(largestNominalAppHeight);
616 sb.append(", smallest app ");
617 sb.append(smallestNominalAppWidth);
618 sb.append(" x ");
619 sb.append(smallestNominalAppHeight);
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700620 sb.append(", mode ");
621 sb.append(modeId);
622 sb.append(", defaultMode ");
623 sb.append(defaultModeId);
624 sb.append(", modes ");
625 sb.append(Arrays.toString(supportedModes));
Michael Wright1c9977b2016-07-12 13:30:10 -0700626 sb.append(", colorMode ");
627 sb.append(colorMode);
628 sb.append(", supportedColorModes ");
629 sb.append(Arrays.toString(supportedColorModes));
Michael Wright9ff94c02016-03-30 18:05:40 -0700630 sb.append(", hdrCapabilities ");
631 sb.append(hdrCapabilities);
Michael Wright3f145a22014-07-22 19:46:03 -0700632 sb.append(", rotation ");
Dianne Hackbornc652de82013-02-15 16:32:56 -0800633 sb.append(rotation);
634 sb.append(", density ");
635 sb.append(logicalDensityDpi);
636 sb.append(" (");
637 sb.append(physicalXDpi);
638 sb.append(" x ");
639 sb.append(physicalYDpi);
640 sb.append(") dpi, layerStack ");
641 sb.append(layerStack);
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700642 sb.append(", appVsyncOff ");
643 sb.append(appVsyncOffsetNanos);
644 sb.append(", presDeadline ");
645 sb.append(presentationDeadlineNanos);
Dianne Hackbornc652de82013-02-15 16:32:56 -0800646 sb.append(", type ");
647 sb.append(Display.typeToString(type));
Jeff Browna506a6e2013-06-04 00:02:38 -0700648 if (address != null) {
649 sb.append(", address ").append(address);
650 }
Jeff Brown037c33e2014-04-09 00:31:55 -0700651 sb.append(", state ");
652 sb.append(Display.stateToString(state));
Jeff Browna506a6e2013-06-04 00:02:38 -0700653 if (ownerUid != 0 || ownerPackageName != null) {
654 sb.append(", owner ").append(ownerPackageName);
655 sb.append(" (uid ").append(ownerUid).append(")");
656 }
Dianne Hackbornc652de82013-02-15 16:32:56 -0800657 sb.append(flagsToString(flags));
Andrii Kulian250d6532017-02-08 23:30:45 -0800658 sb.append(", removeMode ");
659 sb.append(removeMode);
Dianne Hackbornc652de82013-02-15 16:32:56 -0800660 sb.append("}");
661 return sb.toString();
Jeff Brownc5df37c2012-09-13 11:45:07 -0700662 }
663
Steven Timotiusaf03df62017-07-18 16:56:43 -0700664 /**
665 * Write to a protocol buffer output stream.
666 * Protocol buffer message definition at {@link android.view.DisplayInfoProto}
667 *
668 * @param protoOutputStream Stream to write the Rect object to.
669 * @param fieldId Field Id of the DisplayInfoProto as defined in the parent message
670 */
671 public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId) {
672 final long token = protoOutputStream.start(fieldId);
673 protoOutputStream.write(LOGICAL_WIDTH, logicalWidth);
674 protoOutputStream.write(LOGICAL_HEIGHT, logicalHeight);
675 protoOutputStream.write(APP_WIDTH, appWidth);
676 protoOutputStream.write(APP_HEIGHT, appHeight);
677 protoOutputStream.end(token);
678 }
679
Jeff Brownc5df37c2012-09-13 11:45:07 -0700680 private static String flagsToString(int flags) {
681 StringBuilder result = new StringBuilder();
Jeff Brownf0681b32012-10-23 17:35:57 -0700682 if ((flags & Display.FLAG_SECURE) != 0) {
683 result.append(", FLAG_SECURE");
684 }
Jeff Brown77aebfd2012-10-01 21:07:03 -0700685 if ((flags & Display.FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
686 result.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS");
Jeff Brownc5df37c2012-09-13 11:45:07 -0700687 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700688 if ((flags & Display.FLAG_PRIVATE) != 0) {
689 result.append(", FLAG_PRIVATE");
690 }
Jeff Brown7d00aff2013-08-02 19:03:49 -0700691 if ((flags & Display.FLAG_PRESENTATION) != 0) {
692 result.append(", FLAG_PRESENTATION");
693 }
Jeff Brownd46747a2015-04-15 19:02:36 -0700694 if ((flags & Display.FLAG_SCALING_DISABLED) != 0) {
695 result.append(", FLAG_SCALING_DISABLED");
696 }
Adam Powell49e7ff92015-05-14 16:18:53 -0700697 if ((flags & Display.FLAG_ROUND) != 0) {
698 result.append(", FLAG_ROUND");
699 }
Jeff Brownc5df37c2012-09-13 11:45:07 -0700700 return result.toString();
Jeff Brownbf5740e2012-08-19 23:20:02 -0700701 }
Jeff Brownfa25bf52012-07-23 19:26:30 -0700702}