blob: 2efebf6457ab03bb6c1501e60cc73cb72f6aaecc [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
Adrian Roosa4904792018-05-31 19:48:39 +020025import android.annotation.Nullable;
Mathew Inwooda570dee2018-08-17 14:56:00 +010026import android.annotation.UnsupportedAppUsage;
Jeff Brownfa25bf52012-07-23 19:26:30 -070027import android.content.res.CompatibilityInfo;
Wale Ogunwale7c726682015-02-06 17:34:28 -080028import android.content.res.Configuration;
Wale Ogunwale822e5122017-07-26 06:02:24 -070029import android.graphics.Rect;
Sumir Kataria47ed9ee2019-02-06 13:34:28 -080030import android.os.Build;
Jeff Brownfa25bf52012-07-23 19:26:30 -070031import android.os.Parcel;
32import android.os.Parcelable;
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -070033import android.util.ArraySet;
Jeff Brownfa25bf52012-07-23 19:26:30 -070034import android.util.DisplayMetrics;
Steven Timotiusaf03df62017-07-18 16:56:43 -070035import android.util.proto.ProtoOutputStream;
Jeff Brownfa25bf52012-07-23 19:26:30 -070036
Aurimas Liutikas67e2ae82016-10-11 18:17:42 -070037import java.util.Arrays;
Narayan Kamath607223f2018-02-19 14:09:02 +000038import java.util.Objects;
Aurimas Liutikas67e2ae82016-10-11 18:17:42 -070039
Jeff Brownfa25bf52012-07-23 19:26:30 -070040/**
41 * Describes the characteristics of a particular logical display.
42 * @hide
43 */
44public final class DisplayInfo implements Parcelable {
45 /**
Jeff Brown4ed8fe72012-08-30 18:18:29 -070046 * The surface flinger layer stack associated with this logical display.
47 */
48 public int layerStack;
49
50 /**
Jeff Brownc5df37c2012-09-13 11:45:07 -070051 * Display flags.
52 */
53 public int flags;
54
55 /**
Jeff Brown92130f62012-10-24 21:28:33 -070056 * Display type.
57 */
58 public int type;
59
60 /**
lumarkec75b422019-01-07 15:58:38 +080061 * Logical display identifier.
62 */
63 public int displayId;
64
65 /**
Jeff Brown92130f62012-10-24 21:28:33 -070066 * Display address, or null if none.
67 * Interpretation varies by display type.
68 */
Dominik Laskowskidb845962019-01-27 21:20:00 -080069 public DisplayAddress address;
Jeff Brown92130f62012-10-24 21:28:33 -070070
71 /**
Jeff Brown4ed8fe72012-08-30 18:18:29 -070072 * The human-readable name of the display.
73 */
74 public String name;
75
76 /**
Wale Ogunwale361ca212014-11-20 11:42:38 -080077 * Unique identifier for the display. Shouldn't be displayed to the user.
78 */
79 public String uniqueId;
80
81 /**
Jeff Brownfa25bf52012-07-23 19:26:30 -070082 * The width of the portion of the display that is available to applications, in pixels.
83 * Represents the size of the display minus any system decorations.
84 */
85 public int appWidth;
86
87 /**
88 * The height of the portion of the display that is available to applications, in pixels.
89 * Represents the size of the display minus any system decorations.
90 */
91 public int appHeight;
92
93 /**
94 * The smallest value of {@link #appWidth} that an application is likely to encounter,
95 * in pixels, excepting cases where the width may be even smaller due to the presence
96 * of a soft keyboard, for example.
97 */
98 public int smallestNominalAppWidth;
99
100 /**
101 * The smallest value of {@link #appHeight} that an application is likely to encounter,
102 * in pixels, excepting cases where the height may be even smaller due to the presence
103 * of a soft keyboard, for example.
104 */
105 public int smallestNominalAppHeight;
106
107 /**
108 * The largest value of {@link #appWidth} that an application is likely to encounter,
109 * in pixels, excepting cases where the width may be even larger due to system decorations
110 * such as the status bar being hidden, for example.
111 */
112 public int largestNominalAppWidth;
113
114 /**
115 * The largest value of {@link #appHeight} that an application is likely to encounter,
116 * in pixels, excepting cases where the height may be even larger due to system decorations
117 * such as the status bar being hidden, for example.
118 */
119 public int largestNominalAppHeight;
120
121 /**
122 * The logical width of the display, in pixels.
123 * Represents the usable size of the display which may be smaller than the
124 * physical size when the system is emulating a smaller display.
125 */
Mathew Inwooda570dee2018-08-17 14:56:00 +0100126 @UnsupportedAppUsage
Jeff Brownfa25bf52012-07-23 19:26:30 -0700127 public int logicalWidth;
128
129 /**
130 * The logical height of the display, in pixels.
131 * Represents the usable size of the display which may be smaller than the
132 * physical size when the system is emulating a smaller display.
133 */
Mathew Inwooda570dee2018-08-17 14:56:00 +0100134 @UnsupportedAppUsage
Jeff Brownfa25bf52012-07-23 19:26:30 -0700135 public int logicalHeight;
136
137 /**
Dianne Hackbornc652de82013-02-15 16:32:56 -0800138 * @hide
139 * Number of overscan pixels on the left side of the display.
140 */
141 public int overscanLeft;
142
143 /**
144 * @hide
145 * Number of overscan pixels on the top side of the display.
146 */
147 public int overscanTop;
148
149 /**
150 * @hide
151 * Number of overscan pixels on the right side of the display.
152 */
153 public int overscanRight;
154
155 /**
156 * @hide
157 * Number of overscan pixels on the bottom side of the display.
158 */
159 public int overscanBottom;
160
161 /**
Adrian Roos1cf585052018-01-03 18:43:27 +0100162 * The {@link DisplayCutout} if present, otherwise {@code null}.
163 *
164 * @hide
165 */
Sergey Vasilinets669ad672019-02-07 13:42:33 +0000166 // Remark on @UnsupportedAppUsage: Display.getCutout should be used instead
Adrian Roosa4904792018-05-31 19:48:39 +0200167 @Nullable
Sergey Vasilinets669ad672019-02-07 13:42:33 +0000168 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
Adrian Roos1cf585052018-01-03 18:43:27 +0100169 public DisplayCutout displayCutout;
170
171 /**
Jeff Brownfa25bf52012-07-23 19:26:30 -0700172 * The rotation of the display relative to its natural orientation.
173 * May be one of {@link android.view.Surface#ROTATION_0},
174 * {@link android.view.Surface#ROTATION_90}, {@link android.view.Surface#ROTATION_180},
175 * {@link android.view.Surface#ROTATION_270}.
176 * <p>
177 * The value of this field is indeterminate if the logical display is presented on
178 * more than one physical display.
179 * </p>
180 */
Tor Norbyed9273d62013-05-30 15:59:53 -0700181 @Surface.Rotation
Mathew Inwooda570dee2018-08-17 14:56:00 +0100182 @UnsupportedAppUsage
Jeff Brownfa25bf52012-07-23 19:26:30 -0700183 public int rotation;
184
185 /**
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700186 * The active display mode.
Jeff Brownfa25bf52012-07-23 19:26:30 -0700187 */
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700188 public int modeId;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700189
190 /**
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700191 * The default display mode.
Michael Wright3f145a22014-07-22 19:46:03 -0700192 */
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700193 public int defaultModeId;
194
195 /**
196 * The supported modes of this display.
197 */
198 public Display.Mode[] supportedModes = Display.Mode.EMPTY_ARRAY;
Michael Wright3f145a22014-07-22 19:46:03 -0700199
Michael Wright1c9977b2016-07-12 13:30:10 -0700200 /** The active color mode. */
201 public int colorMode;
Michael Wright58e829f2015-09-15 00:13:26 +0100202
Michael Wright1c9977b2016-07-12 13:30:10 -0700203 /** The list of supported color modes */
204 public int[] supportedColorModes = { Display.COLOR_MODE_DEFAULT };
Michael Wright58e829f2015-09-15 00:13:26 +0100205
Michael Wright9ff94c02016-03-30 18:05:40 -0700206 /** The display's HDR capabilities */
207 public Display.HdrCapabilities hdrCapabilities;
208
Michael Wright3f145a22014-07-22 19:46:03 -0700209 /**
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700210 * The logical display density which is the basis for density-independent
211 * pixels.
Jeff Brownfa25bf52012-07-23 19:26:30 -0700212 */
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700213 public int logicalDensityDpi;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700214
215 /**
216 * The exact physical pixels per inch of the screen in the X dimension.
217 * <p>
218 * The value of this field is indeterminate if the logical display is presented on
219 * more than one physical display.
220 * </p>
221 */
222 public float physicalXDpi;
223
224 /**
225 * The exact physical pixels per inch of the screen in the Y dimension.
226 * <p>
227 * The value of this field is indeterminate if the logical display is presented on
228 * more than one physical display.
229 * </p>
230 */
231 public float physicalYDpi;
232
Jeff Browna506a6e2013-06-04 00:02:38 -0700233 /**
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700234 * This is a positive value indicating the phase offset of the VSYNC events provided by
235 * Choreographer relative to the display refresh. For example, if Choreographer reports
236 * that the refresh occurred at time N, it actually occurred at (N - appVsyncOffsetNanos).
237 */
238 public long appVsyncOffsetNanos;
239
240 /**
241 * This is how far in advance a buffer must be queued for presentation at
242 * a given time. If you want a buffer to appear on the screen at
243 * time N, you must submit the buffer before (N - bufferDeadlineNanos).
244 */
245 public long presentationDeadlineNanos;
246
247 /**
Jeff Brown037c33e2014-04-09 00:31:55 -0700248 * The state of the display, such as {@link android.view.Display#STATE_ON}.
249 */
250 public int state;
251
252 /**
Jeff Browna506a6e2013-06-04 00:02:38 -0700253 * The UID of the application that owns this display, or zero if it is owned by the system.
254 * <p>
255 * If the display is private, then only the owner can use it.
256 * </p>
257 */
258 public int ownerUid;
259
260 /**
261 * The package name of the application that owns this display, or null if it is
262 * owned by the system.
263 * <p>
264 * If the display is private, then only the owner can use it.
265 * </p>
266 */
267 public String ownerPackageName;
268
Andrii Kulian250d6532017-02-08 23:30:45 -0800269 /**
270 * @hide
271 * Get current remove mode of the display - what actions should be performed with the display's
272 * content when it is removed.
273 *
274 * @see Display#getRemoveMode()
275 */
Chilun8753ad32018-10-09 15:56:45 +0800276 // TODO (b/114338689): Remove the flag and use IWindowManager#getRemoveContentMode
Andrii Kulian250d6532017-02-08 23:30:45 -0800277 public int removeMode = Display.REMOVE_MODE_MOVE_CONTENT_TO_PRIMARY;
278
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700279 public static final @android.annotation.NonNull Creator<DisplayInfo> CREATOR = new Creator<DisplayInfo>() {
Jeff Brown92130f62012-10-24 21:28:33 -0700280 @Override
Jeff Brownfa25bf52012-07-23 19:26:30 -0700281 public DisplayInfo createFromParcel(Parcel source) {
282 return new DisplayInfo(source);
283 }
284
Jeff Brown92130f62012-10-24 21:28:33 -0700285 @Override
Jeff Brownfa25bf52012-07-23 19:26:30 -0700286 public DisplayInfo[] newArray(int size) {
287 return new DisplayInfo[size];
288 }
289 };
290
Sumir Kataria47ed9ee2019-02-06 13:34:28 -0800291 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769467)
Jeff Brownfa25bf52012-07-23 19:26:30 -0700292 public DisplayInfo() {
293 }
294
Jeff Brownbd6e1502012-08-28 03:27:37 -0700295 public DisplayInfo(DisplayInfo other) {
296 copyFrom(other);
297 }
298
Jeff Brownfa25bf52012-07-23 19:26:30 -0700299 private DisplayInfo(Parcel source) {
300 readFromParcel(source);
301 }
302
303 @Override
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700304 public boolean equals(Object o) {
305 return o instanceof DisplayInfo && equals((DisplayInfo)o);
306 }
307
308 public boolean equals(DisplayInfo other) {
309 return other != null
310 && layerStack == other.layerStack
Jeff Brown92130f62012-10-24 21:28:33 -0700311 && flags == other.flags
312 && type == other.type
lumarkec75b422019-01-07 15:58:38 +0800313 && displayId == other.displayId
Narayan Kamath607223f2018-02-19 14:09:02 +0000314 && Objects.equals(address, other.address)
315 && Objects.equals(uniqueId, other.uniqueId)
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700316 && appWidth == other.appWidth
317 && appHeight == other.appHeight
318 && smallestNominalAppWidth == other.smallestNominalAppWidth
319 && smallestNominalAppHeight == other.smallestNominalAppHeight
320 && largestNominalAppWidth == other.largestNominalAppWidth
321 && largestNominalAppHeight == other.largestNominalAppHeight
322 && logicalWidth == other.logicalWidth
323 && logicalHeight == other.logicalHeight
Dianne Hackbornc652de82013-02-15 16:32:56 -0800324 && overscanLeft == other.overscanLeft
325 && overscanTop == other.overscanTop
326 && overscanRight == other.overscanRight
327 && overscanBottom == other.overscanBottom
Narayan Kamath607223f2018-02-19 14:09:02 +0000328 && Objects.equals(displayCutout, other.displayCutout)
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700329 && rotation == other.rotation
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700330 && modeId == other.modeId
331 && defaultModeId == other.defaultModeId
Michael Wright1c9977b2016-07-12 13:30:10 -0700332 && colorMode == other.colorMode
Michael Wright16ae0422016-07-26 18:18:53 +0100333 && Arrays.equals(supportedColorModes, other.supportedColorModes)
Narayan Kamath607223f2018-02-19 14:09:02 +0000334 && Objects.equals(hdrCapabilities, other.hdrCapabilities)
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700335 && logicalDensityDpi == other.logicalDensityDpi
336 && physicalXDpi == other.physicalXDpi
Jeff Browna506a6e2013-06-04 00:02:38 -0700337 && physicalYDpi == other.physicalYDpi
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700338 && appVsyncOffsetNanos == other.appVsyncOffsetNanos
339 && presentationDeadlineNanos == other.presentationDeadlineNanos
Jeff Brown037c33e2014-04-09 00:31:55 -0700340 && state == other.state
Jeff Browna506a6e2013-06-04 00:02:38 -0700341 && ownerUid == other.ownerUid
Narayan Kamath607223f2018-02-19 14:09:02 +0000342 && Objects.equals(ownerPackageName, other.ownerPackageName)
Andrii Kulian250d6532017-02-08 23:30:45 -0800343 && removeMode == other.removeMode;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700344 }
345
346 @Override
347 public int hashCode() {
348 return 0; // don't care
Jeff Brownfa25bf52012-07-23 19:26:30 -0700349 }
350
351 public void copyFrom(DisplayInfo other) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700352 layerStack = other.layerStack;
Jeff Brownc5df37c2012-09-13 11:45:07 -0700353 flags = other.flags;
Jeff Brown92130f62012-10-24 21:28:33 -0700354 type = other.type;
lumarkec75b422019-01-07 15:58:38 +0800355 displayId = other.displayId;
Jeff Brown92130f62012-10-24 21:28:33 -0700356 address = other.address;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700357 name = other.name;
Wale Ogunwale361ca212014-11-20 11:42:38 -0800358 uniqueId = other.uniqueId;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700359 appWidth = other.appWidth;
360 appHeight = other.appHeight;
361 smallestNominalAppWidth = other.smallestNominalAppWidth;
362 smallestNominalAppHeight = other.smallestNominalAppHeight;
363 largestNominalAppWidth = other.largestNominalAppWidth;
364 largestNominalAppHeight = other.largestNominalAppHeight;
365 logicalWidth = other.logicalWidth;
366 logicalHeight = other.logicalHeight;
Dianne Hackbornc652de82013-02-15 16:32:56 -0800367 overscanLeft = other.overscanLeft;
368 overscanTop = other.overscanTop;
369 overscanRight = other.overscanRight;
370 overscanBottom = other.overscanBottom;
Adrian Roos1cf585052018-01-03 18:43:27 +0100371 displayCutout = other.displayCutout;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700372 rotation = other.rotation;
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700373 modeId = other.modeId;
374 defaultModeId = other.defaultModeId;
375 supportedModes = Arrays.copyOf(other.supportedModes, other.supportedModes.length);
Michael Wright1c9977b2016-07-12 13:30:10 -0700376 colorMode = other.colorMode;
377 supportedColorModes = Arrays.copyOf(
378 other.supportedColorModes, other.supportedColorModes.length);
Michael Wright9ff94c02016-03-30 18:05:40 -0700379 hdrCapabilities = other.hdrCapabilities;
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700380 logicalDensityDpi = other.logicalDensityDpi;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700381 physicalXDpi = other.physicalXDpi;
382 physicalYDpi = other.physicalYDpi;
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700383 appVsyncOffsetNanos = other.appVsyncOffsetNanos;
384 presentationDeadlineNanos = other.presentationDeadlineNanos;
Jeff Brown037c33e2014-04-09 00:31:55 -0700385 state = other.state;
Jeff Browna506a6e2013-06-04 00:02:38 -0700386 ownerUid = other.ownerUid;
387 ownerPackageName = other.ownerPackageName;
Andrii Kulian250d6532017-02-08 23:30:45 -0800388 removeMode = other.removeMode;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700389 }
390
391 public void readFromParcel(Parcel source) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700392 layerStack = source.readInt();
Jeff Brownc5df37c2012-09-13 11:45:07 -0700393 flags = source.readInt();
Jeff Brown92130f62012-10-24 21:28:33 -0700394 type = source.readInt();
lumarkec75b422019-01-07 15:58:38 +0800395 displayId = source.readInt();
Dominik Laskowskidb845962019-01-27 21:20:00 -0800396 address = source.readParcelable(null);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700397 name = source.readString();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700398 appWidth = source.readInt();
399 appHeight = source.readInt();
400 smallestNominalAppWidth = source.readInt();
401 smallestNominalAppHeight = source.readInt();
402 largestNominalAppWidth = source.readInt();
403 largestNominalAppHeight = source.readInt();
404 logicalWidth = source.readInt();
405 logicalHeight = source.readInt();
Dianne Hackbornc652de82013-02-15 16:32:56 -0800406 overscanLeft = source.readInt();
407 overscanTop = source.readInt();
408 overscanRight = source.readInt();
409 overscanBottom = source.readInt();
Adrian Roos1cf585052018-01-03 18:43:27 +0100410 displayCutout = DisplayCutout.ParcelableWrapper.readCutoutFromParcel(source);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700411 rotation = source.readInt();
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700412 modeId = source.readInt();
413 defaultModeId = source.readInt();
414 int nModes = source.readInt();
415 supportedModes = new Display.Mode[nModes];
416 for (int i = 0; i < nModes; i++) {
417 supportedModes[i] = Display.Mode.CREATOR.createFromParcel(source);
418 }
Michael Wright1c9977b2016-07-12 13:30:10 -0700419 colorMode = source.readInt();
420 int nColorModes = source.readInt();
421 supportedColorModes = new int[nColorModes];
422 for (int i = 0; i < nColorModes; i++) {
423 supportedColorModes[i] = source.readInt();
Michael Wright58e829f2015-09-15 00:13:26 +0100424 }
Michael Wrightb0828902016-04-27 19:26:16 -0400425 hdrCapabilities = source.readParcelable(null);
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700426 logicalDensityDpi = source.readInt();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700427 physicalXDpi = source.readFloat();
428 physicalYDpi = source.readFloat();
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700429 appVsyncOffsetNanos = source.readLong();
430 presentationDeadlineNanos = source.readLong();
Jeff Brown037c33e2014-04-09 00:31:55 -0700431 state = source.readInt();
Jeff Browna506a6e2013-06-04 00:02:38 -0700432 ownerUid = source.readInt();
433 ownerPackageName = source.readString();
Wale Ogunwale361ca212014-11-20 11:42:38 -0800434 uniqueId = source.readString();
Andrii Kulian250d6532017-02-08 23:30:45 -0800435 removeMode = source.readInt();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700436 }
437
438 @Override
439 public void writeToParcel(Parcel dest, int flags) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700440 dest.writeInt(layerStack);
Jeff Brown3f2ba622012-10-04 14:57:44 -0700441 dest.writeInt(this.flags);
Jeff Brown92130f62012-10-24 21:28:33 -0700442 dest.writeInt(type);
lumarkec75b422019-01-07 15:58:38 +0800443 dest.writeInt(displayId);
Dominik Laskowskidb845962019-01-27 21:20:00 -0800444 dest.writeParcelable(address, flags);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700445 dest.writeString(name);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700446 dest.writeInt(appWidth);
447 dest.writeInt(appHeight);
448 dest.writeInt(smallestNominalAppWidth);
449 dest.writeInt(smallestNominalAppHeight);
450 dest.writeInt(largestNominalAppWidth);
451 dest.writeInt(largestNominalAppHeight);
452 dest.writeInt(logicalWidth);
453 dest.writeInt(logicalHeight);
Dianne Hackbornc652de82013-02-15 16:32:56 -0800454 dest.writeInt(overscanLeft);
455 dest.writeInt(overscanTop);
456 dest.writeInt(overscanRight);
457 dest.writeInt(overscanBottom);
Adrian Roos1cf585052018-01-03 18:43:27 +0100458 DisplayCutout.ParcelableWrapper.writeCutoutToParcel(displayCutout, dest, flags);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700459 dest.writeInt(rotation);
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700460 dest.writeInt(modeId);
461 dest.writeInt(defaultModeId);
462 dest.writeInt(supportedModes.length);
463 for (int i = 0; i < supportedModes.length; i++) {
464 supportedModes[i].writeToParcel(dest, flags);
465 }
Michael Wright1c9977b2016-07-12 13:30:10 -0700466 dest.writeInt(colorMode);
467 dest.writeInt(supportedColorModes.length);
468 for (int i = 0; i < supportedColorModes.length; i++) {
469 dest.writeInt(supportedColorModes[i]);
Michael Wright58e829f2015-09-15 00:13:26 +0100470 }
Michael Wrightb0828902016-04-27 19:26:16 -0400471 dest.writeParcelable(hdrCapabilities, flags);
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700472 dest.writeInt(logicalDensityDpi);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700473 dest.writeFloat(physicalXDpi);
474 dest.writeFloat(physicalYDpi);
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700475 dest.writeLong(appVsyncOffsetNanos);
476 dest.writeLong(presentationDeadlineNanos);
Jeff Brown037c33e2014-04-09 00:31:55 -0700477 dest.writeInt(state);
Jeff Browna506a6e2013-06-04 00:02:38 -0700478 dest.writeInt(ownerUid);
479 dest.writeString(ownerPackageName);
Wale Ogunwale361ca212014-11-20 11:42:38 -0800480 dest.writeString(uniqueId);
Andrii Kulian250d6532017-02-08 23:30:45 -0800481 dest.writeInt(removeMode);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700482 }
483
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700484 @Override
485 public int describeContents() {
486 return 0;
487 }
488
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700489 public Display.Mode getMode() {
490 return findMode(modeId);
491 }
492
493 public Display.Mode getDefaultMode() {
494 return findMode(defaultModeId);
495 }
496
497 private Display.Mode findMode(int id) {
498 for (int i = 0; i < supportedModes.length; i++) {
499 if (supportedModes[i].getModeId() == id) {
500 return supportedModes[i];
501 }
502 }
503 throw new IllegalStateException("Unable to locate mode " + id);
504 }
505
506 /**
507 * Returns the id of the "default" mode with the given refresh rate, or {@code 0} if no suitable
508 * mode could be found.
509 */
510 public int findDefaultModeByRefreshRate(float refreshRate) {
511 Display.Mode[] modes = supportedModes;
512 Display.Mode defaultMode = getDefaultMode();
513 for (int i = 0; i < modes.length; i++) {
514 if (modes[i].matches(
515 defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), refreshRate)) {
516 return modes[i].getModeId();
517 }
518 }
519 return 0;
520 }
521
522 /**
523 * Returns the list of supported refresh rates in the default mode.
524 */
525 public float[] getDefaultRefreshRates() {
526 Display.Mode[] modes = supportedModes;
527 ArraySet<Float> rates = new ArraySet<>();
528 Display.Mode defaultMode = getDefaultMode();
529 for (int i = 0; i < modes.length; i++) {
530 Display.Mode mode = modes[i];
531 if (mode.getPhysicalWidth() == defaultMode.getPhysicalWidth()
532 && mode.getPhysicalHeight() == defaultMode.getPhysicalHeight()) {
533 rates.add(mode.getRefreshRate());
534 }
535 }
536 float[] result = new float[rates.size()];
537 int i = 0;
538 for (Float rate : rates) {
539 result[i++] = rate;
540 }
541 return result;
542 }
543
Craig Mautner48d0d182013-06-11 07:53:06 -0700544 public void getAppMetrics(DisplayMetrics outMetrics) {
545 getAppMetrics(outMetrics, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700546 }
547
Craig Mautner48d0d182013-06-11 07:53:06 -0700548 public void getAppMetrics(DisplayMetrics outMetrics, DisplayAdjustments displayAdjustments) {
549 getMetricsWithSize(outMetrics, displayAdjustments.getCompatibilityInfo(),
Wale Ogunwale7c726682015-02-06 17:34:28 -0800550 displayAdjustments.getConfiguration(), appWidth, appHeight);
Craig Mautner48d0d182013-06-11 07:53:06 -0700551 }
552
Wale Ogunwale7c726682015-02-06 17:34:28 -0800553 public void getAppMetrics(DisplayMetrics outMetrics, CompatibilityInfo ci,
554 Configuration configuration) {
555 getMetricsWithSize(outMetrics, ci, configuration, appWidth, appHeight);
Craig Mautner48d0d182013-06-11 07:53:06 -0700556 }
557
558 public void getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
Wale Ogunwale7c726682015-02-06 17:34:28 -0800559 Configuration configuration) {
560 getMetricsWithSize(outMetrics, compatInfo, configuration, logicalWidth, logicalHeight);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700561 }
562
Jeff Brown7f3994e2012-12-04 14:04:28 -0800563 public int getNaturalWidth() {
564 return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ?
565 logicalWidth : logicalHeight;
566 }
567
568 public int getNaturalHeight() {
569 return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ?
570 logicalHeight : logicalWidth;
571 }
572
Romain Guy408afbf2017-01-25 10:23:03 -0800573 public boolean isHdr() {
Andrii Kulian4acfd852017-01-26 19:43:13 -0800574 int[] types = hdrCapabilities != null ? hdrCapabilities.getSupportedHdrTypes() : null;
Romain Guy408afbf2017-01-25 10:23:03 -0800575 return types != null && types.length > 0;
576 }
577
578 public boolean isWideColorGamut() {
579 for (int colorMode : supportedColorModes) {
580 if (colorMode == Display.COLOR_MODE_DCI_P3 || colorMode > Display.COLOR_MODE_SRGB) {
581 return true;
582 }
583 }
584 return false;
585 }
586
Jeff Browna506a6e2013-06-04 00:02:38 -0700587 /**
588 * Returns true if the specified UID has access to this display.
589 */
590 public boolean hasAccess(int uid) {
lumarkec75b422019-01-07 15:58:38 +0800591 return Display.hasAccess(uid, flags, ownerUid, displayId);
Jeff Browna506a6e2013-06-04 00:02:38 -0700592 }
593
Craig Mautner48d0d182013-06-11 07:53:06 -0700594 private void getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
Wale Ogunwale7c726682015-02-06 17:34:28 -0800595 Configuration configuration, int width, int height) {
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700596 outMetrics.densityDpi = outMetrics.noncompatDensityDpi = logicalDensityDpi;
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700597 outMetrics.density = outMetrics.noncompatDensity =
598 logicalDensityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700599 outMetrics.scaledDensity = outMetrics.noncompatScaledDensity = outMetrics.density;
600 outMetrics.xdpi = outMetrics.noncompatXdpi = physicalXDpi;
601 outMetrics.ydpi = outMetrics.noncompatYdpi = physicalYDpi;
602
Wale Ogunwale822e5122017-07-26 06:02:24 -0700603 final Rect appBounds = configuration != null
604 ? configuration.windowConfiguration.getAppBounds() : null;
605 width = appBounds != null ? appBounds.width() : width;
606 height = appBounds != null ? appBounds.height() : height;
Wale Ogunwale7c726682015-02-06 17:34:28 -0800607
608 outMetrics.noncompatWidthPixels = outMetrics.widthPixels = width;
609 outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height;
610
Craig Mautner48d0d182013-06-11 07:53:06 -0700611 if (!compatInfo.equals(CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO)) {
612 compatInfo.applyToDisplayMetrics(outMetrics);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700613 }
614 }
Jeff Brownbf5740e2012-08-19 23:20:02 -0700615
616 // For debugging purposes
617 @Override
618 public String toString() {
Dianne Hackbornc652de82013-02-15 16:32:56 -0800619 StringBuilder sb = new StringBuilder();
620 sb.append("DisplayInfo{\"");
621 sb.append(name);
lumarkec75b422019-01-07 15:58:38 +0800622 sb.append(", displayId ");
623 sb.append(displayId);
Wale Ogunwale361ca212014-11-20 11:42:38 -0800624 sb.append("\", uniqueId \"");
625 sb.append(uniqueId);
Dianne Hackbornc652de82013-02-15 16:32:56 -0800626 sb.append("\", app ");
627 sb.append(appWidth);
628 sb.append(" x ");
629 sb.append(appHeight);
630 sb.append(", real ");
631 sb.append(logicalWidth);
632 sb.append(" x ");
633 sb.append(logicalHeight);
634 if (overscanLeft != 0 || overscanTop != 0 || overscanRight != 0 || overscanBottom != 0) {
635 sb.append(", overscan (");
636 sb.append(overscanLeft);
637 sb.append(",");
638 sb.append(overscanTop);
639 sb.append(",");
640 sb.append(overscanRight);
641 sb.append(",");
642 sb.append(overscanBottom);
643 sb.append(")");
644 }
645 sb.append(", largest app ");
646 sb.append(largestNominalAppWidth);
647 sb.append(" x ");
648 sb.append(largestNominalAppHeight);
649 sb.append(", smallest app ");
650 sb.append(smallestNominalAppWidth);
651 sb.append(" x ");
652 sb.append(smallestNominalAppHeight);
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700653 sb.append(", mode ");
654 sb.append(modeId);
655 sb.append(", defaultMode ");
656 sb.append(defaultModeId);
657 sb.append(", modes ");
658 sb.append(Arrays.toString(supportedModes));
Michael Wright1c9977b2016-07-12 13:30:10 -0700659 sb.append(", colorMode ");
660 sb.append(colorMode);
661 sb.append(", supportedColorModes ");
662 sb.append(Arrays.toString(supportedColorModes));
Michael Wright9ff94c02016-03-30 18:05:40 -0700663 sb.append(", hdrCapabilities ");
664 sb.append(hdrCapabilities);
Michael Wright3f145a22014-07-22 19:46:03 -0700665 sb.append(", rotation ");
Dianne Hackbornc652de82013-02-15 16:32:56 -0800666 sb.append(rotation);
667 sb.append(", density ");
668 sb.append(logicalDensityDpi);
669 sb.append(" (");
670 sb.append(physicalXDpi);
671 sb.append(" x ");
672 sb.append(physicalYDpi);
673 sb.append(") dpi, layerStack ");
674 sb.append(layerStack);
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700675 sb.append(", appVsyncOff ");
676 sb.append(appVsyncOffsetNanos);
677 sb.append(", presDeadline ");
678 sb.append(presentationDeadlineNanos);
Dianne Hackbornc652de82013-02-15 16:32:56 -0800679 sb.append(", type ");
680 sb.append(Display.typeToString(type));
Jeff Browna506a6e2013-06-04 00:02:38 -0700681 if (address != null) {
682 sb.append(", address ").append(address);
683 }
Jeff Brown037c33e2014-04-09 00:31:55 -0700684 sb.append(", state ");
685 sb.append(Display.stateToString(state));
Jeff Browna506a6e2013-06-04 00:02:38 -0700686 if (ownerUid != 0 || ownerPackageName != null) {
687 sb.append(", owner ").append(ownerPackageName);
688 sb.append(" (uid ").append(ownerUid).append(")");
689 }
Dianne Hackbornc652de82013-02-15 16:32:56 -0800690 sb.append(flagsToString(flags));
Andrii Kulian250d6532017-02-08 23:30:45 -0800691 sb.append(", removeMode ");
692 sb.append(removeMode);
Dianne Hackbornc652de82013-02-15 16:32:56 -0800693 sb.append("}");
694 return sb.toString();
Jeff Brownc5df37c2012-09-13 11:45:07 -0700695 }
696
Steven Timotiusaf03df62017-07-18 16:56:43 -0700697 /**
698 * Write to a protocol buffer output stream.
699 * Protocol buffer message definition at {@link android.view.DisplayInfoProto}
700 *
701 * @param protoOutputStream Stream to write the Rect object to.
702 * @param fieldId Field Id of the DisplayInfoProto as defined in the parent message
703 */
704 public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId) {
705 final long token = protoOutputStream.start(fieldId);
706 protoOutputStream.write(LOGICAL_WIDTH, logicalWidth);
707 protoOutputStream.write(LOGICAL_HEIGHT, logicalHeight);
708 protoOutputStream.write(APP_WIDTH, appWidth);
709 protoOutputStream.write(APP_HEIGHT, appHeight);
Andrii Kulian764e1042018-02-08 15:12:14 -0800710 protoOutputStream.write(NAME, name);
Steven Timotiusaf03df62017-07-18 16:56:43 -0700711 protoOutputStream.end(token);
712 }
713
Jeff Brownc5df37c2012-09-13 11:45:07 -0700714 private static String flagsToString(int flags) {
715 StringBuilder result = new StringBuilder();
Jeff Brownf0681b32012-10-23 17:35:57 -0700716 if ((flags & Display.FLAG_SECURE) != 0) {
717 result.append(", FLAG_SECURE");
718 }
Jeff Brown77aebfd2012-10-01 21:07:03 -0700719 if ((flags & Display.FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
720 result.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS");
Jeff Brownc5df37c2012-09-13 11:45:07 -0700721 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700722 if ((flags & Display.FLAG_PRIVATE) != 0) {
723 result.append(", FLAG_PRIVATE");
724 }
Jeff Brown7d00aff2013-08-02 19:03:49 -0700725 if ((flags & Display.FLAG_PRESENTATION) != 0) {
726 result.append(", FLAG_PRESENTATION");
727 }
Jeff Brownd46747a2015-04-15 19:02:36 -0700728 if ((flags & Display.FLAG_SCALING_DISABLED) != 0) {
729 result.append(", FLAG_SCALING_DISABLED");
730 }
Adam Powell49e7ff92015-05-14 16:18:53 -0700731 if ((flags & Display.FLAG_ROUND) != 0) {
732 result.append(", FLAG_ROUND");
733 }
Jeff Brownc5df37c2012-09-13 11:45:07 -0700734 return result.toString();
Jeff Brownbf5740e2012-08-19 23:20:02 -0700735 }
Jeff Brownfa25bf52012-07-23 19:26:30 -0700736}