blob: c0d61d47397128cb0d04d8bd38777d7ac51d1c6c [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;
Yan Zhu39b0e9a2019-07-22 11:23:13 -070021import static android.view.DisplayInfoProto.FLAGS;
Steven Timotiusaf03df62017-07-18 16:56:43 -070022import static android.view.DisplayInfoProto.LOGICAL_HEIGHT;
23import static android.view.DisplayInfoProto.LOGICAL_WIDTH;
Andrii Kulian764e1042018-02-08 15:12:14 -080024import static android.view.DisplayInfoProto.NAME;
Steven Timotiusaf03df62017-07-18 16:56:43 -070025
Adrian Roosa4904792018-05-31 19:48:39 +020026import android.annotation.Nullable;
Artur Satayevad9254c2019-12-10 17:47:54 +000027import android.compat.annotation.UnsupportedAppUsage;
Jeff Brownfa25bf52012-07-23 19:26:30 -070028import android.content.res.CompatibilityInfo;
Wale Ogunwale7c726682015-02-06 17:34:28 -080029import android.content.res.Configuration;
Wale Ogunwale822e5122017-07-26 06:02:24 -070030import android.graphics.Rect;
Marin Shalamanov98af1592019-10-08 10:48:08 +020031import android.hardware.display.DeviceProductInfo;
Sumir Kataria47ed9ee2019-02-06 13:34:28 -080032import android.os.Build;
Jeff Brownfa25bf52012-07-23 19:26:30 -070033import android.os.Parcel;
34import android.os.Parcelable;
Dominik Laskowski1039ea502020-02-28 15:27:12 -080035import android.os.Process;
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -070036import android.util.ArraySet;
Jeff Brownfa25bf52012-07-23 19:26:30 -070037import android.util.DisplayMetrics;
Steven Timotiusaf03df62017-07-18 16:56:43 -070038import android.util.proto.ProtoOutputStream;
Jeff Brownfa25bf52012-07-23 19:26:30 -070039
Aurimas Liutikas67e2ae82016-10-11 18:17:42 -070040import java.util.Arrays;
Narayan Kamath607223f2018-02-19 14:09:02 +000041import java.util.Objects;
Aurimas Liutikas67e2ae82016-10-11 18:17:42 -070042
Jeff Brownfa25bf52012-07-23 19:26:30 -070043/**
44 * Describes the characteristics of a particular logical display.
45 * @hide
46 */
47public final class DisplayInfo implements Parcelable {
48 /**
Jeff Brown4ed8fe72012-08-30 18:18:29 -070049 * The surface flinger layer stack associated with this logical display.
50 */
51 public int layerStack;
52
53 /**
Jeff Brownc5df37c2012-09-13 11:45:07 -070054 * Display flags.
55 */
56 public int flags;
57
58 /**
Jeff Brown92130f62012-10-24 21:28:33 -070059 * Display type.
60 */
61 public int type;
62
63 /**
lumarkec75b422019-01-07 15:58:38 +080064 * Logical display identifier.
65 */
66 public int displayId;
67
68 /**
Jeff Brown92130f62012-10-24 21:28:33 -070069 * Display address, or null if none.
70 * Interpretation varies by display type.
71 */
Dominik Laskowskidb845962019-01-27 21:20:00 -080072 public DisplayAddress address;
Jeff Brown92130f62012-10-24 21:28:33 -070073
74 /**
Marin Shalamanov98af1592019-10-08 10:48:08 +020075 * Product-specific information about the display or the directly connected device on the
76 * display chain. For example, if the display is transitively connected, this field may contain
77 * product information about the intermediate device.
78 */
79 public DeviceProductInfo deviceProductInfo;
80
81 /**
Jeff Brown4ed8fe72012-08-30 18:18:29 -070082 * The human-readable name of the display.
83 */
84 public String name;
85
86 /**
Wale Ogunwale361ca212014-11-20 11:42:38 -080087 * Unique identifier for the display. Shouldn't be displayed to the user.
88 */
89 public String uniqueId;
90
91 /**
Jeff Brownfa25bf52012-07-23 19:26:30 -070092 * The width of the portion of the display that is available to applications, in pixels.
93 * Represents the size of the display minus any system decorations.
94 */
95 public int appWidth;
96
97 /**
98 * The height of the portion of the display that is available to applications, in pixels.
99 * Represents the size of the display minus any system decorations.
100 */
101 public int appHeight;
102
103 /**
104 * The smallest value of {@link #appWidth} that an application is likely to encounter,
105 * in pixels, excepting cases where the width may be even smaller due to the presence
106 * of a soft keyboard, for example.
107 */
108 public int smallestNominalAppWidth;
109
110 /**
111 * The smallest value of {@link #appHeight} that an application is likely to encounter,
112 * in pixels, excepting cases where the height may be even smaller due to the presence
113 * of a soft keyboard, for example.
114 */
115 public int smallestNominalAppHeight;
116
117 /**
118 * The largest value of {@link #appWidth} that an application is likely to encounter,
119 * in pixels, excepting cases where the width may be even larger due to system decorations
120 * such as the status bar being hidden, for example.
121 */
122 public int largestNominalAppWidth;
123
124 /**
125 * The largest value of {@link #appHeight} that an application is likely to encounter,
126 * in pixels, excepting cases where the height may be even larger due to system decorations
127 * such as the status bar being hidden, for example.
128 */
129 public int largestNominalAppHeight;
130
131 /**
132 * The logical width of the display, in pixels.
133 * Represents the usable size of the display which may be smaller than the
134 * physical size when the system is emulating a smaller display.
135 */
Mathew Inwooda570dee2018-08-17 14:56:00 +0100136 @UnsupportedAppUsage
Jeff Brownfa25bf52012-07-23 19:26:30 -0700137 public int logicalWidth;
138
139 /**
140 * The logical height of the display, in pixels.
141 * Represents the usable size of the display which may be smaller than the
142 * physical size when the system is emulating a smaller display.
143 */
Mathew Inwooda570dee2018-08-17 14:56:00 +0100144 @UnsupportedAppUsage
Jeff Brownfa25bf52012-07-23 19:26:30 -0700145 public int logicalHeight;
146
147 /**
Adrian Roos1cf585052018-01-03 18:43:27 +0100148 * The {@link DisplayCutout} if present, otherwise {@code null}.
149 *
150 * @hide
151 */
Sergey Vasilinets669ad672019-02-07 13:42:33 +0000152 // Remark on @UnsupportedAppUsage: Display.getCutout should be used instead
Adrian Roosa4904792018-05-31 19:48:39 +0200153 @Nullable
Sergey Vasilinets669ad672019-02-07 13:42:33 +0000154 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
Adrian Roos1cf585052018-01-03 18:43:27 +0100155 public DisplayCutout displayCutout;
156
157 /**
Jeff Brownfa25bf52012-07-23 19:26:30 -0700158 * The rotation of the display relative to its natural orientation.
159 * May be one of {@link android.view.Surface#ROTATION_0},
160 * {@link android.view.Surface#ROTATION_90}, {@link android.view.Surface#ROTATION_180},
161 * {@link android.view.Surface#ROTATION_270}.
162 * <p>
163 * The value of this field is indeterminate if the logical display is presented on
164 * more than one physical display.
165 * </p>
166 */
Tor Norbyed9273d62013-05-30 15:59:53 -0700167 @Surface.Rotation
Mathew Inwooda570dee2018-08-17 14:56:00 +0100168 @UnsupportedAppUsage
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 /**
Galia Peycheva056b3ee2019-06-26 14:05:12 +0200196 * Indicates whether the display can be switched into a mode with minimal post
197 * processing.
198 *
199 * @see android.view.Display#isMinimalPostProcessingSupported
200 */
201 public boolean minimalPostProcessingSupported;
202
203 /**
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700204 * The logical display density which is the basis for density-independent
205 * pixels.
Jeff Brownfa25bf52012-07-23 19:26:30 -0700206 */
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700207 public int logicalDensityDpi;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700208
209 /**
210 * The exact physical pixels per inch of the screen in the X dimension.
211 * <p>
212 * The value of this field is indeterminate if the logical display is presented on
213 * more than one physical display.
214 * </p>
215 */
216 public float physicalXDpi;
217
218 /**
219 * The exact physical pixels per inch of the screen in the Y dimension.
220 * <p>
221 * The value of this field is indeterminate if the logical display is presented on
222 * more than one physical display.
223 * </p>
224 */
225 public float physicalYDpi;
226
Jeff Browna506a6e2013-06-04 00:02:38 -0700227 /**
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700228 * This is a positive value indicating the phase offset of the VSYNC events provided by
229 * Choreographer relative to the display refresh. For example, if Choreographer reports
230 * that the refresh occurred at time N, it actually occurred at (N - appVsyncOffsetNanos).
231 */
232 public long appVsyncOffsetNanos;
233
234 /**
235 * This is how far in advance a buffer must be queued for presentation at
236 * a given time. If you want a buffer to appear on the screen at
237 * time N, you must submit the buffer before (N - bufferDeadlineNanos).
238 */
239 public long presentationDeadlineNanos;
240
241 /**
Jeff Brown037c33e2014-04-09 00:31:55 -0700242 * The state of the display, such as {@link android.view.Display#STATE_ON}.
243 */
244 public int state;
245
246 /**
Jeff Browna506a6e2013-06-04 00:02:38 -0700247 * The UID of the application that owns this display, or zero if it is owned by the system.
248 * <p>
249 * If the display is private, then only the owner can use it.
250 * </p>
251 */
252 public int ownerUid;
253
254 /**
255 * The package name of the application that owns this display, or null if it is
256 * owned by the system.
257 * <p>
258 * If the display is private, then only the owner can use it.
259 * </p>
260 */
261 public String ownerPackageName;
262
Andrii Kulian250d6532017-02-08 23:30:45 -0800263 /**
264 * @hide
265 * Get current remove mode of the display - what actions should be performed with the display's
266 * content when it is removed.
267 *
268 * @see Display#getRemoveMode()
269 */
Chilun8753ad32018-10-09 15:56:45 +0800270 // TODO (b/114338689): Remove the flag and use IWindowManager#getRemoveContentMode
Andrii Kulian250d6532017-02-08 23:30:45 -0800271 public int removeMode = Display.REMOVE_MODE_MOVE_CONTENT_TO_PRIMARY;
272
Jeff Sharkey9e8f83d2019-02-28 12:06:45 -0700273 public static final @android.annotation.NonNull Creator<DisplayInfo> CREATOR = new Creator<DisplayInfo>() {
Jeff Brown92130f62012-10-24 21:28:33 -0700274 @Override
Jeff Brownfa25bf52012-07-23 19:26:30 -0700275 public DisplayInfo createFromParcel(Parcel source) {
276 return new DisplayInfo(source);
277 }
278
Jeff Brown92130f62012-10-24 21:28:33 -0700279 @Override
Jeff Brownfa25bf52012-07-23 19:26:30 -0700280 public DisplayInfo[] newArray(int size) {
281 return new DisplayInfo[size];
282 }
283 };
284
Sumir Kataria47ed9ee2019-02-06 13:34:28 -0800285 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769467)
Jeff Brownfa25bf52012-07-23 19:26:30 -0700286 public DisplayInfo() {
287 }
288
Jeff Brownbd6e1502012-08-28 03:27:37 -0700289 public DisplayInfo(DisplayInfo other) {
290 copyFrom(other);
291 }
292
Jeff Brownfa25bf52012-07-23 19:26:30 -0700293 private DisplayInfo(Parcel source) {
294 readFromParcel(source);
295 }
296
297 @Override
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700298 public boolean equals(Object o) {
299 return o instanceof DisplayInfo && equals((DisplayInfo)o);
300 }
301
302 public boolean equals(DisplayInfo other) {
303 return other != null
304 && layerStack == other.layerStack
Jeff Brown92130f62012-10-24 21:28:33 -0700305 && flags == other.flags
306 && type == other.type
lumarkec75b422019-01-07 15:58:38 +0800307 && displayId == other.displayId
Narayan Kamath607223f2018-02-19 14:09:02 +0000308 && Objects.equals(address, other.address)
Marin Shalamanov98af1592019-10-08 10:48:08 +0200309 && Objects.equals(deviceProductInfo, other.deviceProductInfo)
Narayan Kamath607223f2018-02-19 14:09:02 +0000310 && Objects.equals(uniqueId, other.uniqueId)
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700311 && appWidth == other.appWidth
312 && appHeight == other.appHeight
313 && smallestNominalAppWidth == other.smallestNominalAppWidth
314 && smallestNominalAppHeight == other.smallestNominalAppHeight
315 && largestNominalAppWidth == other.largestNominalAppWidth
316 && largestNominalAppHeight == other.largestNominalAppHeight
317 && logicalWidth == other.logicalWidth
318 && logicalHeight == other.logicalHeight
Narayan Kamath607223f2018-02-19 14:09:02 +0000319 && Objects.equals(displayCutout, other.displayCutout)
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700320 && rotation == other.rotation
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700321 && modeId == other.modeId
322 && defaultModeId == other.defaultModeId
Michael Wright1c9977b2016-07-12 13:30:10 -0700323 && colorMode == other.colorMode
Michael Wright16ae0422016-07-26 18:18:53 +0100324 && Arrays.equals(supportedColorModes, other.supportedColorModes)
Narayan Kamath607223f2018-02-19 14:09:02 +0000325 && Objects.equals(hdrCapabilities, other.hdrCapabilities)
Galia Peycheva056b3ee2019-06-26 14:05:12 +0200326 && minimalPostProcessingSupported == other.minimalPostProcessingSupported
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700327 && logicalDensityDpi == other.logicalDensityDpi
328 && physicalXDpi == other.physicalXDpi
Jeff Browna506a6e2013-06-04 00:02:38 -0700329 && physicalYDpi == other.physicalYDpi
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700330 && appVsyncOffsetNanos == other.appVsyncOffsetNanos
331 && presentationDeadlineNanos == other.presentationDeadlineNanos
Jeff Brown037c33e2014-04-09 00:31:55 -0700332 && state == other.state
Jeff Browna506a6e2013-06-04 00:02:38 -0700333 && ownerUid == other.ownerUid
Narayan Kamath607223f2018-02-19 14:09:02 +0000334 && Objects.equals(ownerPackageName, other.ownerPackageName)
Andrii Kulian250d6532017-02-08 23:30:45 -0800335 && removeMode == other.removeMode;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700336 }
337
338 @Override
339 public int hashCode() {
340 return 0; // don't care
Jeff Brownfa25bf52012-07-23 19:26:30 -0700341 }
342
343 public void copyFrom(DisplayInfo other) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700344 layerStack = other.layerStack;
Jeff Brownc5df37c2012-09-13 11:45:07 -0700345 flags = other.flags;
Jeff Brown92130f62012-10-24 21:28:33 -0700346 type = other.type;
lumarkec75b422019-01-07 15:58:38 +0800347 displayId = other.displayId;
Jeff Brown92130f62012-10-24 21:28:33 -0700348 address = other.address;
Marin Shalamanov98af1592019-10-08 10:48:08 +0200349 deviceProductInfo = other.deviceProductInfo;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700350 name = other.name;
Wale Ogunwale361ca212014-11-20 11:42:38 -0800351 uniqueId = other.uniqueId;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700352 appWidth = other.appWidth;
353 appHeight = other.appHeight;
354 smallestNominalAppWidth = other.smallestNominalAppWidth;
355 smallestNominalAppHeight = other.smallestNominalAppHeight;
356 largestNominalAppWidth = other.largestNominalAppWidth;
357 largestNominalAppHeight = other.largestNominalAppHeight;
358 logicalWidth = other.logicalWidth;
359 logicalHeight = other.logicalHeight;
Adrian Roos1cf585052018-01-03 18:43:27 +0100360 displayCutout = other.displayCutout;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700361 rotation = other.rotation;
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700362 modeId = other.modeId;
363 defaultModeId = other.defaultModeId;
364 supportedModes = Arrays.copyOf(other.supportedModes, other.supportedModes.length);
Michael Wright1c9977b2016-07-12 13:30:10 -0700365 colorMode = other.colorMode;
366 supportedColorModes = Arrays.copyOf(
367 other.supportedColorModes, other.supportedColorModes.length);
Michael Wright9ff94c02016-03-30 18:05:40 -0700368 hdrCapabilities = other.hdrCapabilities;
Galia Peycheva056b3ee2019-06-26 14:05:12 +0200369 minimalPostProcessingSupported = other.minimalPostProcessingSupported;
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700370 logicalDensityDpi = other.logicalDensityDpi;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700371 physicalXDpi = other.physicalXDpi;
372 physicalYDpi = other.physicalYDpi;
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700373 appVsyncOffsetNanos = other.appVsyncOffsetNanos;
374 presentationDeadlineNanos = other.presentationDeadlineNanos;
Jeff Brown037c33e2014-04-09 00:31:55 -0700375 state = other.state;
Jeff Browna506a6e2013-06-04 00:02:38 -0700376 ownerUid = other.ownerUid;
377 ownerPackageName = other.ownerPackageName;
Andrii Kulian250d6532017-02-08 23:30:45 -0800378 removeMode = other.removeMode;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700379 }
380
381 public void readFromParcel(Parcel source) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700382 layerStack = source.readInt();
Jeff Brownc5df37c2012-09-13 11:45:07 -0700383 flags = source.readInt();
Jeff Brown92130f62012-10-24 21:28:33 -0700384 type = source.readInt();
lumarkec75b422019-01-07 15:58:38 +0800385 displayId = source.readInt();
Dominik Laskowskidb845962019-01-27 21:20:00 -0800386 address = source.readParcelable(null);
Marin Shalamanov98af1592019-10-08 10:48:08 +0200387 deviceProductInfo = source.readParcelable(null);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700388 name = source.readString();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700389 appWidth = source.readInt();
390 appHeight = source.readInt();
391 smallestNominalAppWidth = source.readInt();
392 smallestNominalAppHeight = source.readInt();
393 largestNominalAppWidth = source.readInt();
394 largestNominalAppHeight = source.readInt();
395 logicalWidth = source.readInt();
396 logicalHeight = source.readInt();
Adrian Roos1cf585052018-01-03 18:43:27 +0100397 displayCutout = DisplayCutout.ParcelableWrapper.readCutoutFromParcel(source);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700398 rotation = source.readInt();
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700399 modeId = source.readInt();
400 defaultModeId = source.readInt();
401 int nModes = source.readInt();
402 supportedModes = new Display.Mode[nModes];
403 for (int i = 0; i < nModes; i++) {
404 supportedModes[i] = Display.Mode.CREATOR.createFromParcel(source);
405 }
Michael Wright1c9977b2016-07-12 13:30:10 -0700406 colorMode = source.readInt();
407 int nColorModes = source.readInt();
408 supportedColorModes = new int[nColorModes];
409 for (int i = 0; i < nColorModes; i++) {
410 supportedColorModes[i] = source.readInt();
Michael Wright58e829f2015-09-15 00:13:26 +0100411 }
Michael Wrightb0828902016-04-27 19:26:16 -0400412 hdrCapabilities = source.readParcelable(null);
Galia Peycheva056b3ee2019-06-26 14:05:12 +0200413 minimalPostProcessingSupported = source.readBoolean();
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700414 logicalDensityDpi = source.readInt();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700415 physicalXDpi = source.readFloat();
416 physicalYDpi = source.readFloat();
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700417 appVsyncOffsetNanos = source.readLong();
418 presentationDeadlineNanos = source.readLong();
Jeff Brown037c33e2014-04-09 00:31:55 -0700419 state = source.readInt();
Jeff Browna506a6e2013-06-04 00:02:38 -0700420 ownerUid = source.readInt();
421 ownerPackageName = source.readString();
Wale Ogunwale361ca212014-11-20 11:42:38 -0800422 uniqueId = source.readString();
Andrii Kulian250d6532017-02-08 23:30:45 -0800423 removeMode = source.readInt();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700424 }
425
426 @Override
427 public void writeToParcel(Parcel dest, int flags) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700428 dest.writeInt(layerStack);
Jeff Brown3f2ba622012-10-04 14:57:44 -0700429 dest.writeInt(this.flags);
Jeff Brown92130f62012-10-24 21:28:33 -0700430 dest.writeInt(type);
lumarkec75b422019-01-07 15:58:38 +0800431 dest.writeInt(displayId);
Dominik Laskowskidb845962019-01-27 21:20:00 -0800432 dest.writeParcelable(address, flags);
Marin Shalamanov98af1592019-10-08 10:48:08 +0200433 dest.writeParcelable(deviceProductInfo, flags);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700434 dest.writeString(name);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700435 dest.writeInt(appWidth);
436 dest.writeInt(appHeight);
437 dest.writeInt(smallestNominalAppWidth);
438 dest.writeInt(smallestNominalAppHeight);
439 dest.writeInt(largestNominalAppWidth);
440 dest.writeInt(largestNominalAppHeight);
441 dest.writeInt(logicalWidth);
442 dest.writeInt(logicalHeight);
Adrian Roos1cf585052018-01-03 18:43:27 +0100443 DisplayCutout.ParcelableWrapper.writeCutoutToParcel(displayCutout, dest, flags);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700444 dest.writeInt(rotation);
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700445 dest.writeInt(modeId);
446 dest.writeInt(defaultModeId);
447 dest.writeInt(supportedModes.length);
448 for (int i = 0; i < supportedModes.length; i++) {
449 supportedModes[i].writeToParcel(dest, flags);
450 }
Michael Wright1c9977b2016-07-12 13:30:10 -0700451 dest.writeInt(colorMode);
452 dest.writeInt(supportedColorModes.length);
453 for (int i = 0; i < supportedColorModes.length; i++) {
454 dest.writeInt(supportedColorModes[i]);
Michael Wright58e829f2015-09-15 00:13:26 +0100455 }
Michael Wrightb0828902016-04-27 19:26:16 -0400456 dest.writeParcelable(hdrCapabilities, flags);
Galia Peycheva056b3ee2019-06-26 14:05:12 +0200457 dest.writeBoolean(minimalPostProcessingSupported);
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700458 dest.writeInt(logicalDensityDpi);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700459 dest.writeFloat(physicalXDpi);
460 dest.writeFloat(physicalYDpi);
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700461 dest.writeLong(appVsyncOffsetNanos);
462 dest.writeLong(presentationDeadlineNanos);
Jeff Brown037c33e2014-04-09 00:31:55 -0700463 dest.writeInt(state);
Jeff Browna506a6e2013-06-04 00:02:38 -0700464 dest.writeInt(ownerUid);
465 dest.writeString(ownerPackageName);
Wale Ogunwale361ca212014-11-20 11:42:38 -0800466 dest.writeString(uniqueId);
Andrii Kulian250d6532017-02-08 23:30:45 -0800467 dest.writeInt(removeMode);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700468 }
469
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700470 @Override
471 public int describeContents() {
472 return 0;
473 }
474
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700475 public Display.Mode getMode() {
476 return findMode(modeId);
477 }
478
479 public Display.Mode getDefaultMode() {
480 return findMode(defaultModeId);
481 }
482
483 private Display.Mode findMode(int id) {
484 for (int i = 0; i < supportedModes.length; i++) {
485 if (supportedModes[i].getModeId() == id) {
486 return supportedModes[i];
487 }
488 }
489 throw new IllegalStateException("Unable to locate mode " + id);
490 }
491
492 /**
493 * Returns the id of the "default" mode with the given refresh rate, or {@code 0} if no suitable
494 * mode could be found.
495 */
496 public int findDefaultModeByRefreshRate(float refreshRate) {
497 Display.Mode[] modes = supportedModes;
498 Display.Mode defaultMode = getDefaultMode();
499 for (int i = 0; i < modes.length; i++) {
500 if (modes[i].matches(
501 defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), refreshRate)) {
502 return modes[i].getModeId();
503 }
504 }
505 return 0;
506 }
507
508 /**
509 * Returns the list of supported refresh rates in the default mode.
510 */
511 public float[] getDefaultRefreshRates() {
512 Display.Mode[] modes = supportedModes;
513 ArraySet<Float> rates = new ArraySet<>();
514 Display.Mode defaultMode = getDefaultMode();
515 for (int i = 0; i < modes.length; i++) {
516 Display.Mode mode = modes[i];
517 if (mode.getPhysicalWidth() == defaultMode.getPhysicalWidth()
518 && mode.getPhysicalHeight() == defaultMode.getPhysicalHeight()) {
519 rates.add(mode.getRefreshRate());
520 }
521 }
522 float[] result = new float[rates.size()];
523 int i = 0;
524 for (Float rate : rates) {
525 result[i++] = rate;
526 }
527 return result;
528 }
529
Craig Mautner48d0d182013-06-11 07:53:06 -0700530 public void getAppMetrics(DisplayMetrics outMetrics) {
531 getAppMetrics(outMetrics, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700532 }
533
Craig Mautner48d0d182013-06-11 07:53:06 -0700534 public void getAppMetrics(DisplayMetrics outMetrics, DisplayAdjustments displayAdjustments) {
535 getMetricsWithSize(outMetrics, displayAdjustments.getCompatibilityInfo(),
Wale Ogunwale7c726682015-02-06 17:34:28 -0800536 displayAdjustments.getConfiguration(), appWidth, appHeight);
Craig Mautner48d0d182013-06-11 07:53:06 -0700537 }
538
Wale Ogunwale7c726682015-02-06 17:34:28 -0800539 public void getAppMetrics(DisplayMetrics outMetrics, CompatibilityInfo ci,
540 Configuration configuration) {
541 getMetricsWithSize(outMetrics, ci, configuration, appWidth, appHeight);
Craig Mautner48d0d182013-06-11 07:53:06 -0700542 }
543
544 public void getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
Wale Ogunwale7c726682015-02-06 17:34:28 -0800545 Configuration configuration) {
546 getMetricsWithSize(outMetrics, compatInfo, configuration, logicalWidth, logicalHeight);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700547 }
548
Jeff Brown7f3994e2012-12-04 14:04:28 -0800549 public int getNaturalWidth() {
550 return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ?
551 logicalWidth : logicalHeight;
552 }
553
554 public int getNaturalHeight() {
555 return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ?
556 logicalHeight : logicalWidth;
557 }
558
Romain Guy408afbf2017-01-25 10:23:03 -0800559 public boolean isHdr() {
Andrii Kulian4acfd852017-01-26 19:43:13 -0800560 int[] types = hdrCapabilities != null ? hdrCapabilities.getSupportedHdrTypes() : null;
Romain Guy408afbf2017-01-25 10:23:03 -0800561 return types != null && types.length > 0;
562 }
563
564 public boolean isWideColorGamut() {
565 for (int colorMode : supportedColorModes) {
566 if (colorMode == Display.COLOR_MODE_DCI_P3 || colorMode > Display.COLOR_MODE_SRGB) {
567 return true;
568 }
569 }
570 return false;
571 }
572
Jeff Browna506a6e2013-06-04 00:02:38 -0700573 /**
574 * Returns true if the specified UID has access to this display.
575 */
576 public boolean hasAccess(int uid) {
lumarkec75b422019-01-07 15:58:38 +0800577 return Display.hasAccess(uid, flags, ownerUid, displayId);
Jeff Browna506a6e2013-06-04 00:02:38 -0700578 }
579
Craig Mautner48d0d182013-06-11 07:53:06 -0700580 private void getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
Wale Ogunwale7c726682015-02-06 17:34:28 -0800581 Configuration configuration, int width, int height) {
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700582 outMetrics.densityDpi = outMetrics.noncompatDensityDpi = logicalDensityDpi;
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700583 outMetrics.density = outMetrics.noncompatDensity =
584 logicalDensityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700585 outMetrics.scaledDensity = outMetrics.noncompatScaledDensity = outMetrics.density;
586 outMetrics.xdpi = outMetrics.noncompatXdpi = physicalXDpi;
587 outMetrics.ydpi = outMetrics.noncompatYdpi = physicalYDpi;
588
Wale Ogunwale822e5122017-07-26 06:02:24 -0700589 final Rect appBounds = configuration != null
590 ? configuration.windowConfiguration.getAppBounds() : null;
591 width = appBounds != null ? appBounds.width() : width;
592 height = appBounds != null ? appBounds.height() : height;
Wale Ogunwale7c726682015-02-06 17:34:28 -0800593
594 outMetrics.noncompatWidthPixels = outMetrics.widthPixels = width;
595 outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height;
596
Craig Mautner48d0d182013-06-11 07:53:06 -0700597 if (!compatInfo.equals(CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO)) {
598 compatInfo.applyToDisplayMetrics(outMetrics);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700599 }
600 }
Jeff Brownbf5740e2012-08-19 23:20:02 -0700601
602 // For debugging purposes
603 @Override
604 public String toString() {
Dianne Hackbornc652de82013-02-15 16:32:56 -0800605 StringBuilder sb = new StringBuilder();
606 sb.append("DisplayInfo{\"");
607 sb.append(name);
Dominik Laskowski1039ea502020-02-28 15:27:12 -0800608 sb.append("\", displayId ");
lumarkec75b422019-01-07 15:58:38 +0800609 sb.append(displayId);
Dominik Laskowski1039ea502020-02-28 15:27:12 -0800610 sb.append(flagsToString(flags));
Dianne Hackbornc652de82013-02-15 16:32:56 -0800611 sb.append(", real ");
612 sb.append(logicalWidth);
613 sb.append(" x ");
614 sb.append(logicalHeight);
Dianne Hackbornc652de82013-02-15 16:32:56 -0800615 sb.append(", largest app ");
616 sb.append(largestNominalAppWidth);
617 sb.append(" x ");
618 sb.append(largestNominalAppHeight);
619 sb.append(", smallest app ");
620 sb.append(smallestNominalAppWidth);
621 sb.append(" x ");
622 sb.append(smallestNominalAppHeight);
Dominik Laskowski1039ea502020-02-28 15:27:12 -0800623 sb.append(", appVsyncOff ");
624 sb.append(appVsyncOffsetNanos);
625 sb.append(", presDeadline ");
626 sb.append(presentationDeadlineNanos);
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700627 sb.append(", mode ");
628 sb.append(modeId);
629 sb.append(", defaultMode ");
630 sb.append(defaultModeId);
631 sb.append(", modes ");
632 sb.append(Arrays.toString(supportedModes));
Michael Wright9ff94c02016-03-30 18:05:40 -0700633 sb.append(", hdrCapabilities ");
634 sb.append(hdrCapabilities);
Galia Peycheva35f900a2020-01-09 14:31:05 +0100635 sb.append(", minimalPostProcessingSupported ");
636 sb.append(minimalPostProcessingSupported);
Michael Wright3f145a22014-07-22 19:46:03 -0700637 sb.append(", rotation ");
Dianne Hackbornc652de82013-02-15 16:32:56 -0800638 sb.append(rotation);
Dominik Laskowski1039ea502020-02-28 15:27:12 -0800639 sb.append(", state ");
640 sb.append(Display.stateToString(state));
641
642 if (Process.myUid() != Process.SYSTEM_UID) {
643 sb.append("}");
644 return sb.toString();
645 }
646
647 sb.append(", type ");
648 sb.append(Display.typeToString(type));
649 sb.append(", uniqueId \"");
650 sb.append(uniqueId);
651 sb.append("\", app ");
652 sb.append(appWidth);
653 sb.append(" x ");
654 sb.append(appHeight);
Dianne Hackbornc652de82013-02-15 16:32:56 -0800655 sb.append(", density ");
656 sb.append(logicalDensityDpi);
657 sb.append(" (");
658 sb.append(physicalXDpi);
659 sb.append(" x ");
660 sb.append(physicalYDpi);
661 sb.append(") dpi, layerStack ");
662 sb.append(layerStack);
Dominik Laskowski1039ea502020-02-28 15:27:12 -0800663 sb.append(", colorMode ");
664 sb.append(colorMode);
665 sb.append(", supportedColorModes ");
666 sb.append(Arrays.toString(supportedColorModes));
Jeff Browna506a6e2013-06-04 00:02:38 -0700667 if (address != null) {
668 sb.append(", address ").append(address);
669 }
Marin Shalamanov98af1592019-10-08 10:48:08 +0200670 sb.append(", deviceProductInfo ");
671 sb.append(deviceProductInfo);
Jeff Browna506a6e2013-06-04 00:02:38 -0700672 if (ownerUid != 0 || ownerPackageName != null) {
673 sb.append(", owner ").append(ownerPackageName);
674 sb.append(" (uid ").append(ownerUid).append(")");
675 }
Andrii Kulian250d6532017-02-08 23:30:45 -0800676 sb.append(", removeMode ");
677 sb.append(removeMode);
Dianne Hackbornc652de82013-02-15 16:32:56 -0800678 sb.append("}");
679 return sb.toString();
Jeff Brownc5df37c2012-09-13 11:45:07 -0700680 }
681
Steven Timotiusaf03df62017-07-18 16:56:43 -0700682 /**
683 * Write to a protocol buffer output stream.
684 * Protocol buffer message definition at {@link android.view.DisplayInfoProto}
685 *
686 * @param protoOutputStream Stream to write the Rect object to.
687 * @param fieldId Field Id of the DisplayInfoProto as defined in the parent message
688 */
Jeffrey Huangcb782852019-12-05 11:28:11 -0800689 public void dumpDebug(ProtoOutputStream protoOutputStream, long fieldId) {
Steven Timotiusaf03df62017-07-18 16:56:43 -0700690 final long token = protoOutputStream.start(fieldId);
691 protoOutputStream.write(LOGICAL_WIDTH, logicalWidth);
692 protoOutputStream.write(LOGICAL_HEIGHT, logicalHeight);
693 protoOutputStream.write(APP_WIDTH, appWidth);
694 protoOutputStream.write(APP_HEIGHT, appHeight);
Andrii Kulian764e1042018-02-08 15:12:14 -0800695 protoOutputStream.write(NAME, name);
Yan Zhu39b0e9a2019-07-22 11:23:13 -0700696 protoOutputStream.write(FLAGS, flags);
Steven Timotiusaf03df62017-07-18 16:56:43 -0700697 protoOutputStream.end(token);
698 }
699
Jeff Brownc5df37c2012-09-13 11:45:07 -0700700 private static String flagsToString(int flags) {
701 StringBuilder result = new StringBuilder();
Jeff Brownf0681b32012-10-23 17:35:57 -0700702 if ((flags & Display.FLAG_SECURE) != 0) {
703 result.append(", FLAG_SECURE");
704 }
Jeff Brown77aebfd2012-10-01 21:07:03 -0700705 if ((flags & Display.FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
706 result.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS");
Jeff Brownc5df37c2012-09-13 11:45:07 -0700707 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700708 if ((flags & Display.FLAG_PRIVATE) != 0) {
709 result.append(", FLAG_PRIVATE");
710 }
Jeff Brown7d00aff2013-08-02 19:03:49 -0700711 if ((flags & Display.FLAG_PRESENTATION) != 0) {
712 result.append(", FLAG_PRESENTATION");
713 }
Jeff Brownd46747a2015-04-15 19:02:36 -0700714 if ((flags & Display.FLAG_SCALING_DISABLED) != 0) {
715 result.append(", FLAG_SCALING_DISABLED");
716 }
Adam Powell49e7ff92015-05-14 16:18:53 -0700717 if ((flags & Display.FLAG_ROUND) != 0) {
718 result.append(", FLAG_ROUND");
719 }
Jeff Brownc5df37c2012-09-13 11:45:07 -0700720 return result.toString();
Jeff Brownbf5740e2012-08-19 23:20:02 -0700721 }
Jeff Brownfa25bf52012-07-23 19:26:30 -0700722}