blob: 3aa779bc3df61ba5356ebccd04e3743e1a9d9428 [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 /**
61 * Display address, or null if none.
62 * Interpretation varies by display type.
63 */
Dominik Laskowskidb845962019-01-27 21:20:00 -080064 public DisplayAddress address;
Jeff Brown92130f62012-10-24 21:28:33 -070065
66 /**
Jeff Brown4ed8fe72012-08-30 18:18:29 -070067 * The human-readable name of the display.
68 */
69 public String name;
70
71 /**
Wale Ogunwale361ca212014-11-20 11:42:38 -080072 * Unique identifier for the display. Shouldn't be displayed to the user.
73 */
74 public String uniqueId;
75
76 /**
Jeff Brownfa25bf52012-07-23 19:26:30 -070077 * The width of the portion of the display that is available to applications, in pixels.
78 * Represents the size of the display minus any system decorations.
79 */
80 public int appWidth;
81
82 /**
83 * The height of the portion of the display that is available to applications, in pixels.
84 * Represents the size of the display minus any system decorations.
85 */
86 public int appHeight;
87
88 /**
89 * The smallest value of {@link #appWidth} that an application is likely to encounter,
90 * in pixels, excepting cases where the width may be even smaller due to the presence
91 * of a soft keyboard, for example.
92 */
93 public int smallestNominalAppWidth;
94
95 /**
96 * The smallest value of {@link #appHeight} that an application is likely to encounter,
97 * in pixels, excepting cases where the height may be even smaller due to the presence
98 * of a soft keyboard, for example.
99 */
100 public int smallestNominalAppHeight;
101
102 /**
103 * The largest value of {@link #appWidth} that an application is likely to encounter,
104 * in pixels, excepting cases where the width may be even larger due to system decorations
105 * such as the status bar being hidden, for example.
106 */
107 public int largestNominalAppWidth;
108
109 /**
110 * The largest value of {@link #appHeight} that an application is likely to encounter,
111 * in pixels, excepting cases where the height may be even larger due to system decorations
112 * such as the status bar being hidden, for example.
113 */
114 public int largestNominalAppHeight;
115
116 /**
117 * The logical width of the display, in pixels.
118 * Represents the usable size of the display which may be smaller than the
119 * physical size when the system is emulating a smaller display.
120 */
Mathew Inwooda570dee2018-08-17 14:56:00 +0100121 @UnsupportedAppUsage
Jeff Brownfa25bf52012-07-23 19:26:30 -0700122 public int logicalWidth;
123
124 /**
125 * The logical height of the display, in pixels.
126 * Represents the usable size of the display which may be smaller than the
127 * physical size when the system is emulating a smaller display.
128 */
Mathew Inwooda570dee2018-08-17 14:56:00 +0100129 @UnsupportedAppUsage
Jeff Brownfa25bf52012-07-23 19:26:30 -0700130 public int logicalHeight;
131
132 /**
Dianne Hackbornc652de82013-02-15 16:32:56 -0800133 * @hide
134 * Number of overscan pixels on the left side of the display.
135 */
136 public int overscanLeft;
137
138 /**
139 * @hide
140 * Number of overscan pixels on the top side of the display.
141 */
142 public int overscanTop;
143
144 /**
145 * @hide
146 * Number of overscan pixels on the right side of the display.
147 */
148 public int overscanRight;
149
150 /**
151 * @hide
152 * Number of overscan pixels on the bottom side of the display.
153 */
154 public int overscanBottom;
155
156 /**
Adrian Roos1cf585052018-01-03 18:43:27 +0100157 * The {@link DisplayCutout} if present, otherwise {@code null}.
158 *
159 * @hide
160 */
Sergey Vasilinets669ad672019-02-07 13:42:33 +0000161 // Remark on @UnsupportedAppUsage: Display.getCutout should be used instead
Adrian Roosa4904792018-05-31 19:48:39 +0200162 @Nullable
Sergey Vasilinets669ad672019-02-07 13:42:33 +0000163 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P)
Adrian Roos1cf585052018-01-03 18:43:27 +0100164 public DisplayCutout displayCutout;
165
166 /**
Jeff Brownfa25bf52012-07-23 19:26:30 -0700167 * The rotation of the display relative to its natural orientation.
168 * May be one of {@link android.view.Surface#ROTATION_0},
169 * {@link android.view.Surface#ROTATION_90}, {@link android.view.Surface#ROTATION_180},
170 * {@link android.view.Surface#ROTATION_270}.
171 * <p>
172 * The value of this field is indeterminate if the logical display is presented on
173 * more than one physical display.
174 * </p>
175 */
Tor Norbyed9273d62013-05-30 15:59:53 -0700176 @Surface.Rotation
Mathew Inwooda570dee2018-08-17 14:56:00 +0100177 @UnsupportedAppUsage
Jeff Brownfa25bf52012-07-23 19:26:30 -0700178 public int rotation;
179
180 /**
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700181 * The active display mode.
Jeff Brownfa25bf52012-07-23 19:26:30 -0700182 */
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700183 public int modeId;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700184
185 /**
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700186 * The default display mode.
Michael Wright3f145a22014-07-22 19:46:03 -0700187 */
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700188 public int defaultModeId;
189
190 /**
191 * The supported modes of this display.
192 */
193 public Display.Mode[] supportedModes = Display.Mode.EMPTY_ARRAY;
Michael Wright3f145a22014-07-22 19:46:03 -0700194
Michael Wright1c9977b2016-07-12 13:30:10 -0700195 /** The active color mode. */
196 public int colorMode;
Michael Wright58e829f2015-09-15 00:13:26 +0100197
Michael Wright1c9977b2016-07-12 13:30:10 -0700198 /** The list of supported color modes */
199 public int[] supportedColorModes = { Display.COLOR_MODE_DEFAULT };
Michael Wright58e829f2015-09-15 00:13:26 +0100200
Michael Wright9ff94c02016-03-30 18:05:40 -0700201 /** The display's HDR capabilities */
202 public Display.HdrCapabilities hdrCapabilities;
203
Michael Wright3f145a22014-07-22 19:46:03 -0700204 /**
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700205 * The logical display density which is the basis for density-independent
206 * pixels.
Jeff Brownfa25bf52012-07-23 19:26:30 -0700207 */
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700208 public int logicalDensityDpi;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700209
210 /**
211 * The exact physical pixels per inch of the screen in the X dimension.
212 * <p>
213 * The value of this field is indeterminate if the logical display is presented on
214 * more than one physical display.
215 * </p>
216 */
217 public float physicalXDpi;
218
219 /**
220 * The exact physical pixels per inch of the screen in the Y dimension.
221 * <p>
222 * The value of this field is indeterminate if the logical display is presented on
223 * more than one physical display.
224 * </p>
225 */
226 public float physicalYDpi;
227
Jeff Browna506a6e2013-06-04 00:02:38 -0700228 /**
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700229 * This is a positive value indicating the phase offset of the VSYNC events provided by
230 * Choreographer relative to the display refresh. For example, if Choreographer reports
231 * that the refresh occurred at time N, it actually occurred at (N - appVsyncOffsetNanos).
232 */
233 public long appVsyncOffsetNanos;
234
235 /**
236 * This is how far in advance a buffer must be queued for presentation at
237 * a given time. If you want a buffer to appear on the screen at
238 * time N, you must submit the buffer before (N - bufferDeadlineNanos).
239 */
240 public long presentationDeadlineNanos;
241
242 /**
Jeff Brown037c33e2014-04-09 00:31:55 -0700243 * The state of the display, such as {@link android.view.Display#STATE_ON}.
244 */
245 public int state;
246
247 /**
Jeff Browna506a6e2013-06-04 00:02:38 -0700248 * The UID of the application that owns this display, or zero if it is owned by the system.
249 * <p>
250 * If the display is private, then only the owner can use it.
251 * </p>
252 */
253 public int ownerUid;
254
255 /**
256 * The package name of the application that owns this display, or null if it is
257 * owned by the system.
258 * <p>
259 * If the display is private, then only the owner can use it.
260 * </p>
261 */
262 public String ownerPackageName;
263
Andrii Kulian250d6532017-02-08 23:30:45 -0800264 /**
265 * @hide
266 * Get current remove mode of the display - what actions should be performed with the display's
267 * content when it is removed.
268 *
269 * @see Display#getRemoveMode()
270 */
Chilun8753ad32018-10-09 15:56:45 +0800271 // TODO (b/114338689): Remove the flag and use IWindowManager#getRemoveContentMode
Andrii Kulian250d6532017-02-08 23:30:45 -0800272 public int removeMode = Display.REMOVE_MODE_MOVE_CONTENT_TO_PRIMARY;
273
Jeff Brownfa25bf52012-07-23 19:26:30 -0700274 public static final Creator<DisplayInfo> CREATOR = new Creator<DisplayInfo>() {
Jeff Brown92130f62012-10-24 21:28:33 -0700275 @Override
Jeff Brownfa25bf52012-07-23 19:26:30 -0700276 public DisplayInfo createFromParcel(Parcel source) {
277 return new DisplayInfo(source);
278 }
279
Jeff Brown92130f62012-10-24 21:28:33 -0700280 @Override
Jeff Brownfa25bf52012-07-23 19:26:30 -0700281 public DisplayInfo[] newArray(int size) {
282 return new DisplayInfo[size];
283 }
284 };
285
Sumir Kataria47ed9ee2019-02-06 13:34:28 -0800286 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 123769467)
Jeff Brownfa25bf52012-07-23 19:26:30 -0700287 public DisplayInfo() {
288 }
289
Jeff Brownbd6e1502012-08-28 03:27:37 -0700290 public DisplayInfo(DisplayInfo other) {
291 copyFrom(other);
292 }
293
Jeff Brownfa25bf52012-07-23 19:26:30 -0700294 private DisplayInfo(Parcel source) {
295 readFromParcel(source);
296 }
297
298 @Override
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700299 public boolean equals(Object o) {
300 return o instanceof DisplayInfo && equals((DisplayInfo)o);
301 }
302
303 public boolean equals(DisplayInfo other) {
304 return other != null
305 && layerStack == other.layerStack
Jeff Brown92130f62012-10-24 21:28:33 -0700306 && flags == other.flags
307 && type == other.type
Narayan Kamath607223f2018-02-19 14:09:02 +0000308 && Objects.equals(address, other.address)
309 && Objects.equals(uniqueId, other.uniqueId)
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700310 && appWidth == other.appWidth
311 && appHeight == other.appHeight
312 && smallestNominalAppWidth == other.smallestNominalAppWidth
313 && smallestNominalAppHeight == other.smallestNominalAppHeight
314 && largestNominalAppWidth == other.largestNominalAppWidth
315 && largestNominalAppHeight == other.largestNominalAppHeight
316 && logicalWidth == other.logicalWidth
317 && logicalHeight == other.logicalHeight
Dianne Hackbornc652de82013-02-15 16:32:56 -0800318 && overscanLeft == other.overscanLeft
319 && overscanTop == other.overscanTop
320 && overscanRight == other.overscanRight
321 && overscanBottom == other.overscanBottom
Narayan Kamath607223f2018-02-19 14:09:02 +0000322 && Objects.equals(displayCutout, other.displayCutout)
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700323 && rotation == other.rotation
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700324 && modeId == other.modeId
325 && defaultModeId == other.defaultModeId
Michael Wright1c9977b2016-07-12 13:30:10 -0700326 && colorMode == other.colorMode
Michael Wright16ae0422016-07-26 18:18:53 +0100327 && Arrays.equals(supportedColorModes, other.supportedColorModes)
Narayan Kamath607223f2018-02-19 14:09:02 +0000328 && Objects.equals(hdrCapabilities, other.hdrCapabilities)
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700329 && logicalDensityDpi == other.logicalDensityDpi
330 && physicalXDpi == other.physicalXDpi
Jeff Browna506a6e2013-06-04 00:02:38 -0700331 && physicalYDpi == other.physicalYDpi
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700332 && appVsyncOffsetNanos == other.appVsyncOffsetNanos
333 && presentationDeadlineNanos == other.presentationDeadlineNanos
Jeff Brown037c33e2014-04-09 00:31:55 -0700334 && state == other.state
Jeff Browna506a6e2013-06-04 00:02:38 -0700335 && ownerUid == other.ownerUid
Narayan Kamath607223f2018-02-19 14:09:02 +0000336 && Objects.equals(ownerPackageName, other.ownerPackageName)
Andrii Kulian250d6532017-02-08 23:30:45 -0800337 && removeMode == other.removeMode;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700338 }
339
340 @Override
341 public int hashCode() {
342 return 0; // don't care
Jeff Brownfa25bf52012-07-23 19:26:30 -0700343 }
344
345 public void copyFrom(DisplayInfo other) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700346 layerStack = other.layerStack;
Jeff Brownc5df37c2012-09-13 11:45:07 -0700347 flags = other.flags;
Jeff Brown92130f62012-10-24 21:28:33 -0700348 type = other.type;
349 address = other.address;
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;
Dianne Hackbornc652de82013-02-15 16:32:56 -0800360 overscanLeft = other.overscanLeft;
361 overscanTop = other.overscanTop;
362 overscanRight = other.overscanRight;
363 overscanBottom = other.overscanBottom;
Adrian Roos1cf585052018-01-03 18:43:27 +0100364 displayCutout = other.displayCutout;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700365 rotation = other.rotation;
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700366 modeId = other.modeId;
367 defaultModeId = other.defaultModeId;
368 supportedModes = Arrays.copyOf(other.supportedModes, other.supportedModes.length);
Michael Wright1c9977b2016-07-12 13:30:10 -0700369 colorMode = other.colorMode;
370 supportedColorModes = Arrays.copyOf(
371 other.supportedColorModes, other.supportedColorModes.length);
Michael Wright9ff94c02016-03-30 18:05:40 -0700372 hdrCapabilities = other.hdrCapabilities;
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700373 logicalDensityDpi = other.logicalDensityDpi;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700374 physicalXDpi = other.physicalXDpi;
375 physicalYDpi = other.physicalYDpi;
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700376 appVsyncOffsetNanos = other.appVsyncOffsetNanos;
377 presentationDeadlineNanos = other.presentationDeadlineNanos;
Jeff Brown037c33e2014-04-09 00:31:55 -0700378 state = other.state;
Jeff Browna506a6e2013-06-04 00:02:38 -0700379 ownerUid = other.ownerUid;
380 ownerPackageName = other.ownerPackageName;
Andrii Kulian250d6532017-02-08 23:30:45 -0800381 removeMode = other.removeMode;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700382 }
383
384 public void readFromParcel(Parcel source) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700385 layerStack = source.readInt();
Jeff Brownc5df37c2012-09-13 11:45:07 -0700386 flags = source.readInt();
Jeff Brown92130f62012-10-24 21:28:33 -0700387 type = source.readInt();
Dominik Laskowskidb845962019-01-27 21:20:00 -0800388 address = source.readParcelable(null);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700389 name = source.readString();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700390 appWidth = source.readInt();
391 appHeight = source.readInt();
392 smallestNominalAppWidth = source.readInt();
393 smallestNominalAppHeight = source.readInt();
394 largestNominalAppWidth = source.readInt();
395 largestNominalAppHeight = source.readInt();
396 logicalWidth = source.readInt();
397 logicalHeight = source.readInt();
Dianne Hackbornc652de82013-02-15 16:32:56 -0800398 overscanLeft = source.readInt();
399 overscanTop = source.readInt();
400 overscanRight = source.readInt();
401 overscanBottom = source.readInt();
Adrian Roos1cf585052018-01-03 18:43:27 +0100402 displayCutout = DisplayCutout.ParcelableWrapper.readCutoutFromParcel(source);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700403 rotation = source.readInt();
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700404 modeId = source.readInt();
405 defaultModeId = source.readInt();
406 int nModes = source.readInt();
407 supportedModes = new Display.Mode[nModes];
408 for (int i = 0; i < nModes; i++) {
409 supportedModes[i] = Display.Mode.CREATOR.createFromParcel(source);
410 }
Michael Wright1c9977b2016-07-12 13:30:10 -0700411 colorMode = source.readInt();
412 int nColorModes = source.readInt();
413 supportedColorModes = new int[nColorModes];
414 for (int i = 0; i < nColorModes; i++) {
415 supportedColorModes[i] = source.readInt();
Michael Wright58e829f2015-09-15 00:13:26 +0100416 }
Michael Wrightb0828902016-04-27 19:26:16 -0400417 hdrCapabilities = source.readParcelable(null);
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700418 logicalDensityDpi = source.readInt();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700419 physicalXDpi = source.readFloat();
420 physicalYDpi = source.readFloat();
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700421 appVsyncOffsetNanos = source.readLong();
422 presentationDeadlineNanos = source.readLong();
Jeff Brown037c33e2014-04-09 00:31:55 -0700423 state = source.readInt();
Jeff Browna506a6e2013-06-04 00:02:38 -0700424 ownerUid = source.readInt();
425 ownerPackageName = source.readString();
Wale Ogunwale361ca212014-11-20 11:42:38 -0800426 uniqueId = source.readString();
Andrii Kulian250d6532017-02-08 23:30:45 -0800427 removeMode = source.readInt();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700428 }
429
430 @Override
431 public void writeToParcel(Parcel dest, int flags) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700432 dest.writeInt(layerStack);
Jeff Brown3f2ba622012-10-04 14:57:44 -0700433 dest.writeInt(this.flags);
Jeff Brown92130f62012-10-24 21:28:33 -0700434 dest.writeInt(type);
Dominik Laskowskidb845962019-01-27 21:20:00 -0800435 dest.writeParcelable(address, flags);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700436 dest.writeString(name);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700437 dest.writeInt(appWidth);
438 dest.writeInt(appHeight);
439 dest.writeInt(smallestNominalAppWidth);
440 dest.writeInt(smallestNominalAppHeight);
441 dest.writeInt(largestNominalAppWidth);
442 dest.writeInt(largestNominalAppHeight);
443 dest.writeInt(logicalWidth);
444 dest.writeInt(logicalHeight);
Dianne Hackbornc652de82013-02-15 16:32:56 -0800445 dest.writeInt(overscanLeft);
446 dest.writeInt(overscanTop);
447 dest.writeInt(overscanRight);
448 dest.writeInt(overscanBottom);
Adrian Roos1cf585052018-01-03 18:43:27 +0100449 DisplayCutout.ParcelableWrapper.writeCutoutToParcel(displayCutout, dest, flags);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700450 dest.writeInt(rotation);
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700451 dest.writeInt(modeId);
452 dest.writeInt(defaultModeId);
453 dest.writeInt(supportedModes.length);
454 for (int i = 0; i < supportedModes.length; i++) {
455 supportedModes[i].writeToParcel(dest, flags);
456 }
Michael Wright1c9977b2016-07-12 13:30:10 -0700457 dest.writeInt(colorMode);
458 dest.writeInt(supportedColorModes.length);
459 for (int i = 0; i < supportedColorModes.length; i++) {
460 dest.writeInt(supportedColorModes[i]);
Michael Wright58e829f2015-09-15 00:13:26 +0100461 }
Michael Wrightb0828902016-04-27 19:26:16 -0400462 dest.writeParcelable(hdrCapabilities, flags);
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700463 dest.writeInt(logicalDensityDpi);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700464 dest.writeFloat(physicalXDpi);
465 dest.writeFloat(physicalYDpi);
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700466 dest.writeLong(appVsyncOffsetNanos);
467 dest.writeLong(presentationDeadlineNanos);
Jeff Brown037c33e2014-04-09 00:31:55 -0700468 dest.writeInt(state);
Jeff Browna506a6e2013-06-04 00:02:38 -0700469 dest.writeInt(ownerUid);
470 dest.writeString(ownerPackageName);
Wale Ogunwale361ca212014-11-20 11:42:38 -0800471 dest.writeString(uniqueId);
Andrii Kulian250d6532017-02-08 23:30:45 -0800472 dest.writeInt(removeMode);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700473 }
474
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700475 @Override
476 public int describeContents() {
477 return 0;
478 }
479
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700480 public Display.Mode getMode() {
481 return findMode(modeId);
482 }
483
484 public Display.Mode getDefaultMode() {
485 return findMode(defaultModeId);
486 }
487
488 private Display.Mode findMode(int id) {
489 for (int i = 0; i < supportedModes.length; i++) {
490 if (supportedModes[i].getModeId() == id) {
491 return supportedModes[i];
492 }
493 }
494 throw new IllegalStateException("Unable to locate mode " + id);
495 }
496
497 /**
498 * Returns the id of the "default" mode with the given refresh rate, or {@code 0} if no suitable
499 * mode could be found.
500 */
501 public int findDefaultModeByRefreshRate(float refreshRate) {
502 Display.Mode[] modes = supportedModes;
503 Display.Mode defaultMode = getDefaultMode();
504 for (int i = 0; i < modes.length; i++) {
505 if (modes[i].matches(
506 defaultMode.getPhysicalWidth(), defaultMode.getPhysicalHeight(), refreshRate)) {
507 return modes[i].getModeId();
508 }
509 }
510 return 0;
511 }
512
513 /**
514 * Returns the list of supported refresh rates in the default mode.
515 */
516 public float[] getDefaultRefreshRates() {
517 Display.Mode[] modes = supportedModes;
518 ArraySet<Float> rates = new ArraySet<>();
519 Display.Mode defaultMode = getDefaultMode();
520 for (int i = 0; i < modes.length; i++) {
521 Display.Mode mode = modes[i];
522 if (mode.getPhysicalWidth() == defaultMode.getPhysicalWidth()
523 && mode.getPhysicalHeight() == defaultMode.getPhysicalHeight()) {
524 rates.add(mode.getRefreshRate());
525 }
526 }
527 float[] result = new float[rates.size()];
528 int i = 0;
529 for (Float rate : rates) {
530 result[i++] = rate;
531 }
532 return result;
533 }
534
Craig Mautner48d0d182013-06-11 07:53:06 -0700535 public void getAppMetrics(DisplayMetrics outMetrics) {
536 getAppMetrics(outMetrics, CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO, null);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700537 }
538
Craig Mautner48d0d182013-06-11 07:53:06 -0700539 public void getAppMetrics(DisplayMetrics outMetrics, DisplayAdjustments displayAdjustments) {
540 getMetricsWithSize(outMetrics, displayAdjustments.getCompatibilityInfo(),
Wale Ogunwale7c726682015-02-06 17:34:28 -0800541 displayAdjustments.getConfiguration(), appWidth, appHeight);
Craig Mautner48d0d182013-06-11 07:53:06 -0700542 }
543
Wale Ogunwale7c726682015-02-06 17:34:28 -0800544 public void getAppMetrics(DisplayMetrics outMetrics, CompatibilityInfo ci,
545 Configuration configuration) {
546 getMetricsWithSize(outMetrics, ci, configuration, appWidth, appHeight);
Craig Mautner48d0d182013-06-11 07:53:06 -0700547 }
548
549 public void getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
Wale Ogunwale7c726682015-02-06 17:34:28 -0800550 Configuration configuration) {
551 getMetricsWithSize(outMetrics, compatInfo, configuration, logicalWidth, logicalHeight);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700552 }
553
Jeff Brown7f3994e2012-12-04 14:04:28 -0800554 public int getNaturalWidth() {
555 return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ?
556 logicalWidth : logicalHeight;
557 }
558
559 public int getNaturalHeight() {
560 return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ?
561 logicalHeight : logicalWidth;
562 }
563
Romain Guy408afbf2017-01-25 10:23:03 -0800564 public boolean isHdr() {
Andrii Kulian4acfd852017-01-26 19:43:13 -0800565 int[] types = hdrCapabilities != null ? hdrCapabilities.getSupportedHdrTypes() : null;
Romain Guy408afbf2017-01-25 10:23:03 -0800566 return types != null && types.length > 0;
567 }
568
569 public boolean isWideColorGamut() {
570 for (int colorMode : supportedColorModes) {
571 if (colorMode == Display.COLOR_MODE_DCI_P3 || colorMode > Display.COLOR_MODE_SRGB) {
572 return true;
573 }
574 }
575 return false;
576 }
577
Jeff Browna506a6e2013-06-04 00:02:38 -0700578 /**
579 * Returns true if the specified UID has access to this display.
580 */
581 public boolean hasAccess(int uid) {
582 return Display.hasAccess(uid, flags, ownerUid);
583 }
584
Craig Mautner48d0d182013-06-11 07:53:06 -0700585 private void getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfo compatInfo,
Wale Ogunwale7c726682015-02-06 17:34:28 -0800586 Configuration configuration, int width, int height) {
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700587 outMetrics.densityDpi = outMetrics.noncompatDensityDpi = logicalDensityDpi;
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700588 outMetrics.density = outMetrics.noncompatDensity =
589 logicalDensityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700590 outMetrics.scaledDensity = outMetrics.noncompatScaledDensity = outMetrics.density;
591 outMetrics.xdpi = outMetrics.noncompatXdpi = physicalXDpi;
592 outMetrics.ydpi = outMetrics.noncompatYdpi = physicalYDpi;
593
Wale Ogunwale822e5122017-07-26 06:02:24 -0700594 final Rect appBounds = configuration != null
595 ? configuration.windowConfiguration.getAppBounds() : null;
596 width = appBounds != null ? appBounds.width() : width;
597 height = appBounds != null ? appBounds.height() : height;
Wale Ogunwale7c726682015-02-06 17:34:28 -0800598
599 outMetrics.noncompatWidthPixels = outMetrics.widthPixels = width;
600 outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height;
601
Craig Mautner48d0d182013-06-11 07:53:06 -0700602 if (!compatInfo.equals(CompatibilityInfo.DEFAULT_COMPATIBILITY_INFO)) {
603 compatInfo.applyToDisplayMetrics(outMetrics);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700604 }
605 }
Jeff Brownbf5740e2012-08-19 23:20:02 -0700606
607 // For debugging purposes
608 @Override
609 public String toString() {
Dianne Hackbornc652de82013-02-15 16:32:56 -0800610 StringBuilder sb = new StringBuilder();
611 sb.append("DisplayInfo{\"");
612 sb.append(name);
Wale Ogunwale361ca212014-11-20 11:42:38 -0800613 sb.append("\", uniqueId \"");
614 sb.append(uniqueId);
Dianne Hackbornc652de82013-02-15 16:32:56 -0800615 sb.append("\", app ");
616 sb.append(appWidth);
617 sb.append(" x ");
618 sb.append(appHeight);
619 sb.append(", real ");
620 sb.append(logicalWidth);
621 sb.append(" x ");
622 sb.append(logicalHeight);
623 if (overscanLeft != 0 || overscanTop != 0 || overscanRight != 0 || overscanBottom != 0) {
624 sb.append(", overscan (");
625 sb.append(overscanLeft);
626 sb.append(",");
627 sb.append(overscanTop);
628 sb.append(",");
629 sb.append(overscanRight);
630 sb.append(",");
631 sb.append(overscanBottom);
632 sb.append(")");
633 }
634 sb.append(", largest app ");
635 sb.append(largestNominalAppWidth);
636 sb.append(" x ");
637 sb.append(largestNominalAppHeight);
638 sb.append(", smallest app ");
639 sb.append(smallestNominalAppWidth);
640 sb.append(" x ");
641 sb.append(smallestNominalAppHeight);
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700642 sb.append(", mode ");
643 sb.append(modeId);
644 sb.append(", defaultMode ");
645 sb.append(defaultModeId);
646 sb.append(", modes ");
647 sb.append(Arrays.toString(supportedModes));
Michael Wright1c9977b2016-07-12 13:30:10 -0700648 sb.append(", colorMode ");
649 sb.append(colorMode);
650 sb.append(", supportedColorModes ");
651 sb.append(Arrays.toString(supportedColorModes));
Michael Wright9ff94c02016-03-30 18:05:40 -0700652 sb.append(", hdrCapabilities ");
653 sb.append(hdrCapabilities);
Michael Wright3f145a22014-07-22 19:46:03 -0700654 sb.append(", rotation ");
Dianne Hackbornc652de82013-02-15 16:32:56 -0800655 sb.append(rotation);
656 sb.append(", density ");
657 sb.append(logicalDensityDpi);
658 sb.append(" (");
659 sb.append(physicalXDpi);
660 sb.append(" x ");
661 sb.append(physicalYDpi);
662 sb.append(") dpi, layerStack ");
663 sb.append(layerStack);
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700664 sb.append(", appVsyncOff ");
665 sb.append(appVsyncOffsetNanos);
666 sb.append(", presDeadline ");
667 sb.append(presentationDeadlineNanos);
Dianne Hackbornc652de82013-02-15 16:32:56 -0800668 sb.append(", type ");
669 sb.append(Display.typeToString(type));
Jeff Browna506a6e2013-06-04 00:02:38 -0700670 if (address != null) {
671 sb.append(", address ").append(address);
672 }
Jeff Brown037c33e2014-04-09 00:31:55 -0700673 sb.append(", state ");
674 sb.append(Display.stateToString(state));
Jeff Browna506a6e2013-06-04 00:02:38 -0700675 if (ownerUid != 0 || ownerPackageName != null) {
676 sb.append(", owner ").append(ownerPackageName);
677 sb.append(" (uid ").append(ownerUid).append(")");
678 }
Dianne Hackbornc652de82013-02-15 16:32:56 -0800679 sb.append(flagsToString(flags));
Andrii Kulian250d6532017-02-08 23:30:45 -0800680 sb.append(", removeMode ");
681 sb.append(removeMode);
Dianne Hackbornc652de82013-02-15 16:32:56 -0800682 sb.append("}");
683 return sb.toString();
Jeff Brownc5df37c2012-09-13 11:45:07 -0700684 }
685
Steven Timotiusaf03df62017-07-18 16:56:43 -0700686 /**
687 * Write to a protocol buffer output stream.
688 * Protocol buffer message definition at {@link android.view.DisplayInfoProto}
689 *
690 * @param protoOutputStream Stream to write the Rect object to.
691 * @param fieldId Field Id of the DisplayInfoProto as defined in the parent message
692 */
693 public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId) {
694 final long token = protoOutputStream.start(fieldId);
695 protoOutputStream.write(LOGICAL_WIDTH, logicalWidth);
696 protoOutputStream.write(LOGICAL_HEIGHT, logicalHeight);
697 protoOutputStream.write(APP_WIDTH, appWidth);
698 protoOutputStream.write(APP_HEIGHT, appHeight);
Andrii Kulian764e1042018-02-08 15:12:14 -0800699 protoOutputStream.write(NAME, name);
Steven Timotiusaf03df62017-07-18 16:56:43 -0700700 protoOutputStream.end(token);
701 }
702
Jeff Brownc5df37c2012-09-13 11:45:07 -0700703 private static String flagsToString(int flags) {
704 StringBuilder result = new StringBuilder();
Jeff Brownf0681b32012-10-23 17:35:57 -0700705 if ((flags & Display.FLAG_SECURE) != 0) {
706 result.append(", FLAG_SECURE");
707 }
Jeff Brown77aebfd2012-10-01 21:07:03 -0700708 if ((flags & Display.FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
709 result.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS");
Jeff Brownc5df37c2012-09-13 11:45:07 -0700710 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700711 if ((flags & Display.FLAG_PRIVATE) != 0) {
712 result.append(", FLAG_PRIVATE");
713 }
Jeff Brown7d00aff2013-08-02 19:03:49 -0700714 if ((flags & Display.FLAG_PRESENTATION) != 0) {
715 result.append(", FLAG_PRESENTATION");
716 }
Jeff Brownd46747a2015-04-15 19:02:36 -0700717 if ((flags & Display.FLAG_SCALING_DISABLED) != 0) {
718 result.append(", FLAG_SCALING_DISABLED");
719 }
Adam Powell49e7ff92015-05-14 16:18:53 -0700720 if ((flags & Display.FLAG_ROUND) != 0) {
721 result.append(", FLAG_ROUND");
722 }
Jeff Brownc5df37c2012-09-13 11:45:07 -0700723 return result.toString();
Jeff Brownbf5740e2012-08-19 23:20:02 -0700724 }
Jeff Brownfa25bf52012-07-23 19:26:30 -0700725}