blob: 2269012f1da52ea999f0c6cc9c731f0968ad6cb9 [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
Mathew Inwoode5ad5982018-08-17 15:07:52 +010025import android.annotation.UnsupportedAppUsage;
Jeff Brownfa25bf52012-07-23 19:26:30 -070026import android.content.res.CompatibilityInfo;
Wale Ogunwale7c726682015-02-06 17:34:28 -080027import android.content.res.Configuration;
Wale Ogunwale822e5122017-07-26 06:02:24 -070028import android.graphics.Rect;
Jeff Brownfa25bf52012-07-23 19:26:30 -070029import android.os.Parcel;
30import android.os.Parcelable;
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -070031import android.util.ArraySet;
Jeff Brownfa25bf52012-07-23 19:26:30 -070032import android.util.DisplayMetrics;
Steven Timotiusaf03df62017-07-18 16:56:43 -070033import android.util.proto.ProtoOutputStream;
Jeff Brownfa25bf52012-07-23 19:26:30 -070034
Aurimas Liutikas67e2ae82016-10-11 18:17:42 -070035import java.util.Arrays;
Narayan Kamath607223f2018-02-19 14:09:02 +000036import java.util.Objects;
Aurimas Liutikas67e2ae82016-10-11 18:17:42 -070037
Jeff Brownfa25bf52012-07-23 19:26:30 -070038/**
39 * Describes the characteristics of a particular logical display.
40 * @hide
41 */
42public final class DisplayInfo implements Parcelable {
43 /**
Jeff Brown4ed8fe72012-08-30 18:18:29 -070044 * The surface flinger layer stack associated with this logical display.
45 */
46 public int layerStack;
47
48 /**
Jeff Brownc5df37c2012-09-13 11:45:07 -070049 * Display flags.
50 */
51 public int flags;
52
53 /**
Jeff Brown92130f62012-10-24 21:28:33 -070054 * Display type.
55 */
56 public int type;
57
58 /**
59 * Display address, or null if none.
60 * Interpretation varies by display type.
61 */
62 public String address;
63
64 /**
Jeff Brown4ed8fe72012-08-30 18:18:29 -070065 * The human-readable name of the display.
66 */
67 public String name;
68
69 /**
Wale Ogunwale361ca212014-11-20 11:42:38 -080070 * Unique identifier for the display. Shouldn't be displayed to the user.
71 */
72 public String uniqueId;
73
74 /**
Jeff Brownfa25bf52012-07-23 19:26:30 -070075 * The width of the portion of the display that is available to applications, in pixels.
76 * Represents the size of the display minus any system decorations.
77 */
78 public int appWidth;
79
80 /**
81 * The height of the portion of the display that is available to applications, in pixels.
82 * Represents the size of the display minus any system decorations.
83 */
84 public int appHeight;
85
86 /**
87 * The smallest value of {@link #appWidth} that an application is likely to encounter,
88 * in pixels, excepting cases where the width may be even smaller due to the presence
89 * of a soft keyboard, for example.
90 */
91 public int smallestNominalAppWidth;
92
93 /**
94 * The smallest value of {@link #appHeight} that an application is likely to encounter,
95 * in pixels, excepting cases where the height may be even smaller due to the presence
96 * of a soft keyboard, for example.
97 */
98 public int smallestNominalAppHeight;
99
100 /**
101 * The largest value of {@link #appWidth} that an application is likely to encounter,
102 * in pixels, excepting cases where the width may be even larger due to system decorations
103 * such as the status bar being hidden, for example.
104 */
105 public int largestNominalAppWidth;
106
107 /**
108 * The largest value of {@link #appHeight} that an application is likely to encounter,
109 * in pixels, excepting cases where the height may be even larger due to system decorations
110 * such as the status bar being hidden, for example.
111 */
112 public int largestNominalAppHeight;
113
114 /**
115 * The logical width of the display, in pixels.
116 * Represents the usable size of the display which may be smaller than the
117 * physical size when the system is emulating a smaller display.
118 */
Mathew Inwoode5ad5982018-08-17 15:07:52 +0100119 @UnsupportedAppUsage
Jeff Brownfa25bf52012-07-23 19:26:30 -0700120 public int logicalWidth;
121
122 /**
123 * The logical height of the display, in pixels.
124 * Represents the usable size of the display which may be smaller than the
125 * physical size when the system is emulating a smaller display.
126 */
Mathew Inwoode5ad5982018-08-17 15:07:52 +0100127 @UnsupportedAppUsage
Jeff Brownfa25bf52012-07-23 19:26:30 -0700128 public int logicalHeight;
129
130 /**
Dianne Hackbornc652de82013-02-15 16:32:56 -0800131 * @hide
132 * Number of overscan pixels on the left side of the display.
133 */
134 public int overscanLeft;
135
136 /**
137 * @hide
138 * Number of overscan pixels on the top side of the display.
139 */
140 public int overscanTop;
141
142 /**
143 * @hide
144 * Number of overscan pixels on the right side of the display.
145 */
146 public int overscanRight;
147
148 /**
149 * @hide
150 * Number of overscan pixels on the bottom side of the display.
151 */
152 public int overscanBottom;
153
154 /**
Adrian Roos1cf585052018-01-03 18:43:27 +0100155 * The {@link DisplayCutout} if present, otherwise {@code null}.
156 *
157 * @hide
158 */
Mathew Inwoode5ad5982018-08-17 15:07:52 +0100159 @UnsupportedAppUsage
Adrian Roos1cf585052018-01-03 18:43:27 +0100160 public DisplayCutout displayCutout;
161
162 /**
Jeff Brownfa25bf52012-07-23 19:26:30 -0700163 * The rotation of the display relative to its natural orientation.
164 * May be one of {@link android.view.Surface#ROTATION_0},
165 * {@link android.view.Surface#ROTATION_90}, {@link android.view.Surface#ROTATION_180},
166 * {@link android.view.Surface#ROTATION_270}.
167 * <p>
168 * The value of this field is indeterminate if the logical display is presented on
169 * more than one physical display.
170 * </p>
171 */
Tor Norbyed9273d62013-05-30 15:59:53 -0700172 @Surface.Rotation
Mathew Inwoode5ad5982018-08-17 15:07:52 +0100173 @UnsupportedAppUsage
Jeff Brownfa25bf52012-07-23 19:26:30 -0700174 public int rotation;
175
176 /**
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700177 * The active display mode.
Jeff Brownfa25bf52012-07-23 19:26:30 -0700178 */
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700179 public int modeId;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700180
181 /**
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700182 * The default display mode.
Michael Wright3f145a22014-07-22 19:46:03 -0700183 */
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700184 public int defaultModeId;
185
186 /**
187 * The supported modes of this display.
188 */
189 public Display.Mode[] supportedModes = Display.Mode.EMPTY_ARRAY;
Michael Wright3f145a22014-07-22 19:46:03 -0700190
Michael Wright1c9977b2016-07-12 13:30:10 -0700191 /** The active color mode. */
192 public int colorMode;
Michael Wright58e829f2015-09-15 00:13:26 +0100193
Michael Wright1c9977b2016-07-12 13:30:10 -0700194 /** The list of supported color modes */
195 public int[] supportedColorModes = { Display.COLOR_MODE_DEFAULT };
Michael Wright58e829f2015-09-15 00:13:26 +0100196
Michael Wright9ff94c02016-03-30 18:05:40 -0700197 /** The display's HDR capabilities */
198 public Display.HdrCapabilities hdrCapabilities;
199
Michael Wright3f145a22014-07-22 19:46:03 -0700200 /**
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700201 * The logical display density which is the basis for density-independent
202 * pixels.
Jeff Brownfa25bf52012-07-23 19:26:30 -0700203 */
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700204 public int logicalDensityDpi;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700205
206 /**
207 * The exact physical pixels per inch of the screen in the X dimension.
208 * <p>
209 * The value of this field is indeterminate if the logical display is presented on
210 * more than one physical display.
211 * </p>
212 */
213 public float physicalXDpi;
214
215 /**
216 * The exact physical pixels per inch of the screen in the Y 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 physicalYDpi;
223
Jeff Browna506a6e2013-06-04 00:02:38 -0700224 /**
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700225 * This is a positive value indicating the phase offset of the VSYNC events provided by
226 * Choreographer relative to the display refresh. For example, if Choreographer reports
227 * that the refresh occurred at time N, it actually occurred at (N - appVsyncOffsetNanos).
228 */
229 public long appVsyncOffsetNanos;
230
231 /**
232 * This is how far in advance a buffer must be queued for presentation at
233 * a given time. If you want a buffer to appear on the screen at
234 * time N, you must submit the buffer before (N - bufferDeadlineNanos).
235 */
236 public long presentationDeadlineNanos;
237
238 /**
Jeff Brown037c33e2014-04-09 00:31:55 -0700239 * The state of the display, such as {@link android.view.Display#STATE_ON}.
240 */
241 public int state;
242
243 /**
Jeff Browna506a6e2013-06-04 00:02:38 -0700244 * The UID of the application that owns this display, or zero if it is owned by the system.
245 * <p>
246 * If the display is private, then only the owner can use it.
247 * </p>
248 */
249 public int ownerUid;
250
251 /**
252 * The package name of the application that owns this display, or null if it is
253 * owned by the system.
254 * <p>
255 * If the display is private, then only the owner can use it.
256 * </p>
257 */
258 public String ownerPackageName;
259
Andrii Kulian250d6532017-02-08 23:30:45 -0800260 /**
261 * @hide
262 * Get current remove mode of the display - what actions should be performed with the display's
263 * content when it is removed.
264 *
265 * @see Display#getRemoveMode()
266 */
267 public int removeMode = Display.REMOVE_MODE_MOVE_CONTENT_TO_PRIMARY;
268
Jeff Brownfa25bf52012-07-23 19:26:30 -0700269 public static final Creator<DisplayInfo> CREATOR = new Creator<DisplayInfo>() {
Jeff Brown92130f62012-10-24 21:28:33 -0700270 @Override
Jeff Brownfa25bf52012-07-23 19:26:30 -0700271 public DisplayInfo createFromParcel(Parcel source) {
272 return new DisplayInfo(source);
273 }
274
Jeff Brown92130f62012-10-24 21:28:33 -0700275 @Override
Jeff Brownfa25bf52012-07-23 19:26:30 -0700276 public DisplayInfo[] newArray(int size) {
277 return new DisplayInfo[size];
278 }
279 };
280
Mathew Inwoode5ad5982018-08-17 15:07:52 +0100281 @UnsupportedAppUsage
Jeff Brownfa25bf52012-07-23 19:26:30 -0700282 public DisplayInfo() {
283 }
284
Jeff Brownbd6e1502012-08-28 03:27:37 -0700285 public DisplayInfo(DisplayInfo other) {
286 copyFrom(other);
287 }
288
Jeff Brownfa25bf52012-07-23 19:26:30 -0700289 private DisplayInfo(Parcel source) {
290 readFromParcel(source);
291 }
292
293 @Override
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700294 public boolean equals(Object o) {
295 return o instanceof DisplayInfo && equals((DisplayInfo)o);
296 }
297
298 public boolean equals(DisplayInfo other) {
299 return other != null
300 && layerStack == other.layerStack
Jeff Brown92130f62012-10-24 21:28:33 -0700301 && flags == other.flags
302 && type == other.type
Narayan Kamath607223f2018-02-19 14:09:02 +0000303 && Objects.equals(address, other.address)
304 && Objects.equals(uniqueId, other.uniqueId)
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700305 && appWidth == other.appWidth
306 && appHeight == other.appHeight
307 && smallestNominalAppWidth == other.smallestNominalAppWidth
308 && smallestNominalAppHeight == other.smallestNominalAppHeight
309 && largestNominalAppWidth == other.largestNominalAppWidth
310 && largestNominalAppHeight == other.largestNominalAppHeight
311 && logicalWidth == other.logicalWidth
312 && logicalHeight == other.logicalHeight
Dianne Hackbornc652de82013-02-15 16:32:56 -0800313 && overscanLeft == other.overscanLeft
314 && overscanTop == other.overscanTop
315 && overscanRight == other.overscanRight
316 && overscanBottom == other.overscanBottom
Narayan Kamath607223f2018-02-19 14:09:02 +0000317 && Objects.equals(displayCutout, other.displayCutout)
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700318 && rotation == other.rotation
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700319 && modeId == other.modeId
320 && defaultModeId == other.defaultModeId
Michael Wright1c9977b2016-07-12 13:30:10 -0700321 && colorMode == other.colorMode
Michael Wright16ae0422016-07-26 18:18:53 +0100322 && Arrays.equals(supportedColorModes, other.supportedColorModes)
Narayan Kamath607223f2018-02-19 14:09:02 +0000323 && Objects.equals(hdrCapabilities, other.hdrCapabilities)
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700324 && logicalDensityDpi == other.logicalDensityDpi
325 && physicalXDpi == other.physicalXDpi
Jeff Browna506a6e2013-06-04 00:02:38 -0700326 && physicalYDpi == other.physicalYDpi
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700327 && appVsyncOffsetNanos == other.appVsyncOffsetNanos
328 && presentationDeadlineNanos == other.presentationDeadlineNanos
Jeff Brown037c33e2014-04-09 00:31:55 -0700329 && state == other.state
Jeff Browna506a6e2013-06-04 00:02:38 -0700330 && ownerUid == other.ownerUid
Narayan Kamath607223f2018-02-19 14:09:02 +0000331 && Objects.equals(ownerPackageName, other.ownerPackageName)
Andrii Kulian250d6532017-02-08 23:30:45 -0800332 && removeMode == other.removeMode;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700333 }
334
335 @Override
336 public int hashCode() {
337 return 0; // don't care
Jeff Brownfa25bf52012-07-23 19:26:30 -0700338 }
339
340 public void copyFrom(DisplayInfo other) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700341 layerStack = other.layerStack;
Jeff Brownc5df37c2012-09-13 11:45:07 -0700342 flags = other.flags;
Jeff Brown92130f62012-10-24 21:28:33 -0700343 type = other.type;
344 address = other.address;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700345 name = other.name;
Wale Ogunwale361ca212014-11-20 11:42:38 -0800346 uniqueId = other.uniqueId;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700347 appWidth = other.appWidth;
348 appHeight = other.appHeight;
349 smallestNominalAppWidth = other.smallestNominalAppWidth;
350 smallestNominalAppHeight = other.smallestNominalAppHeight;
351 largestNominalAppWidth = other.largestNominalAppWidth;
352 largestNominalAppHeight = other.largestNominalAppHeight;
353 logicalWidth = other.logicalWidth;
354 logicalHeight = other.logicalHeight;
Dianne Hackbornc652de82013-02-15 16:32:56 -0800355 overscanLeft = other.overscanLeft;
356 overscanTop = other.overscanTop;
357 overscanRight = other.overscanRight;
358 overscanBottom = other.overscanBottom;
Adrian Roos1cf585052018-01-03 18:43:27 +0100359 displayCutout = other.displayCutout;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700360 rotation = other.rotation;
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700361 modeId = other.modeId;
362 defaultModeId = other.defaultModeId;
363 supportedModes = Arrays.copyOf(other.supportedModes, other.supportedModes.length);
Michael Wright1c9977b2016-07-12 13:30:10 -0700364 colorMode = other.colorMode;
365 supportedColorModes = Arrays.copyOf(
366 other.supportedColorModes, other.supportedColorModes.length);
Michael Wright9ff94c02016-03-30 18:05:40 -0700367 hdrCapabilities = other.hdrCapabilities;
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700368 logicalDensityDpi = other.logicalDensityDpi;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700369 physicalXDpi = other.physicalXDpi;
370 physicalYDpi = other.physicalYDpi;
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700371 appVsyncOffsetNanos = other.appVsyncOffsetNanos;
372 presentationDeadlineNanos = other.presentationDeadlineNanos;
Jeff Brown037c33e2014-04-09 00:31:55 -0700373 state = other.state;
Jeff Browna506a6e2013-06-04 00:02:38 -0700374 ownerUid = other.ownerUid;
375 ownerPackageName = other.ownerPackageName;
Andrii Kulian250d6532017-02-08 23:30:45 -0800376 removeMode = other.removeMode;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700377 }
378
379 public void readFromParcel(Parcel source) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700380 layerStack = source.readInt();
Jeff Brownc5df37c2012-09-13 11:45:07 -0700381 flags = source.readInt();
Jeff Brown92130f62012-10-24 21:28:33 -0700382 type = source.readInt();
383 address = source.readString();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700384 name = source.readString();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700385 appWidth = source.readInt();
386 appHeight = source.readInt();
387 smallestNominalAppWidth = source.readInt();
388 smallestNominalAppHeight = source.readInt();
389 largestNominalAppWidth = source.readInt();
390 largestNominalAppHeight = source.readInt();
391 logicalWidth = source.readInt();
392 logicalHeight = source.readInt();
Dianne Hackbornc652de82013-02-15 16:32:56 -0800393 overscanLeft = source.readInt();
394 overscanTop = source.readInt();
395 overscanRight = source.readInt();
396 overscanBottom = 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);
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700413 logicalDensityDpi = source.readInt();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700414 physicalXDpi = source.readFloat();
415 physicalYDpi = source.readFloat();
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700416 appVsyncOffsetNanos = source.readLong();
417 presentationDeadlineNanos = source.readLong();
Jeff Brown037c33e2014-04-09 00:31:55 -0700418 state = source.readInt();
Jeff Browna506a6e2013-06-04 00:02:38 -0700419 ownerUid = source.readInt();
420 ownerPackageName = source.readString();
Wale Ogunwale361ca212014-11-20 11:42:38 -0800421 uniqueId = source.readString();
Andrii Kulian250d6532017-02-08 23:30:45 -0800422 removeMode = source.readInt();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700423 }
424
425 @Override
426 public void writeToParcel(Parcel dest, int flags) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700427 dest.writeInt(layerStack);
Jeff Brown3f2ba622012-10-04 14:57:44 -0700428 dest.writeInt(this.flags);
Jeff Brown92130f62012-10-24 21:28:33 -0700429 dest.writeInt(type);
430 dest.writeString(address);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700431 dest.writeString(name);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700432 dest.writeInt(appWidth);
433 dest.writeInt(appHeight);
434 dest.writeInt(smallestNominalAppWidth);
435 dest.writeInt(smallestNominalAppHeight);
436 dest.writeInt(largestNominalAppWidth);
437 dest.writeInt(largestNominalAppHeight);
438 dest.writeInt(logicalWidth);
439 dest.writeInt(logicalHeight);
Dianne Hackbornc652de82013-02-15 16:32:56 -0800440 dest.writeInt(overscanLeft);
441 dest.writeInt(overscanTop);
442 dest.writeInt(overscanRight);
443 dest.writeInt(overscanBottom);
Adrian Roos1cf585052018-01-03 18:43:27 +0100444 DisplayCutout.ParcelableWrapper.writeCutoutToParcel(displayCutout, dest, flags);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700445 dest.writeInt(rotation);
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700446 dest.writeInt(modeId);
447 dest.writeInt(defaultModeId);
448 dest.writeInt(supportedModes.length);
449 for (int i = 0; i < supportedModes.length; i++) {
450 supportedModes[i].writeToParcel(dest, flags);
451 }
Michael Wright1c9977b2016-07-12 13:30:10 -0700452 dest.writeInt(colorMode);
453 dest.writeInt(supportedColorModes.length);
454 for (int i = 0; i < supportedColorModes.length; i++) {
455 dest.writeInt(supportedColorModes[i]);
Michael Wright58e829f2015-09-15 00:13:26 +0100456 }
Michael Wrightb0828902016-04-27 19:26:16 -0400457 dest.writeParcelable(hdrCapabilities, flags);
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) {
577 return Display.hasAccess(uid, flags, ownerUid);
578 }
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);
Wale Ogunwale361ca212014-11-20 11:42:38 -0800608 sb.append("\", uniqueId \"");
609 sb.append(uniqueId);
Dianne Hackbornc652de82013-02-15 16:32:56 -0800610 sb.append("\", app ");
611 sb.append(appWidth);
612 sb.append(" x ");
613 sb.append(appHeight);
614 sb.append(", real ");
615 sb.append(logicalWidth);
616 sb.append(" x ");
617 sb.append(logicalHeight);
618 if (overscanLeft != 0 || overscanTop != 0 || overscanRight != 0 || overscanBottom != 0) {
619 sb.append(", overscan (");
620 sb.append(overscanLeft);
621 sb.append(",");
622 sb.append(overscanTop);
623 sb.append(",");
624 sb.append(overscanRight);
625 sb.append(",");
626 sb.append(overscanBottom);
627 sb.append(")");
628 }
629 sb.append(", largest app ");
630 sb.append(largestNominalAppWidth);
631 sb.append(" x ");
632 sb.append(largestNominalAppHeight);
633 sb.append(", smallest app ");
634 sb.append(smallestNominalAppWidth);
635 sb.append(" x ");
636 sb.append(smallestNominalAppHeight);
P.Y. Laligandb3b9eb32015-05-11 15:02:07 -0700637 sb.append(", mode ");
638 sb.append(modeId);
639 sb.append(", defaultMode ");
640 sb.append(defaultModeId);
641 sb.append(", modes ");
642 sb.append(Arrays.toString(supportedModes));
Michael Wright1c9977b2016-07-12 13:30:10 -0700643 sb.append(", colorMode ");
644 sb.append(colorMode);
645 sb.append(", supportedColorModes ");
646 sb.append(Arrays.toString(supportedColorModes));
Michael Wright9ff94c02016-03-30 18:05:40 -0700647 sb.append(", hdrCapabilities ");
648 sb.append(hdrCapabilities);
Michael Wright3f145a22014-07-22 19:46:03 -0700649 sb.append(", rotation ");
Dianne Hackbornc652de82013-02-15 16:32:56 -0800650 sb.append(rotation);
651 sb.append(", density ");
652 sb.append(logicalDensityDpi);
653 sb.append(" (");
654 sb.append(physicalXDpi);
655 sb.append(" x ");
656 sb.append(physicalYDpi);
657 sb.append(") dpi, layerStack ");
658 sb.append(layerStack);
Andy McFaddene8b1aeb2014-06-13 14:05:40 -0700659 sb.append(", appVsyncOff ");
660 sb.append(appVsyncOffsetNanos);
661 sb.append(", presDeadline ");
662 sb.append(presentationDeadlineNanos);
Dianne Hackbornc652de82013-02-15 16:32:56 -0800663 sb.append(", type ");
664 sb.append(Display.typeToString(type));
Jeff Browna506a6e2013-06-04 00:02:38 -0700665 if (address != null) {
666 sb.append(", address ").append(address);
667 }
Jeff Brown037c33e2014-04-09 00:31:55 -0700668 sb.append(", state ");
669 sb.append(Display.stateToString(state));
Jeff Browna506a6e2013-06-04 00:02:38 -0700670 if (ownerUid != 0 || ownerPackageName != null) {
671 sb.append(", owner ").append(ownerPackageName);
672 sb.append(" (uid ").append(ownerUid).append(")");
673 }
Dianne Hackbornc652de82013-02-15 16:32:56 -0800674 sb.append(flagsToString(flags));
Andrii Kulian250d6532017-02-08 23:30:45 -0800675 sb.append(", removeMode ");
676 sb.append(removeMode);
Dianne Hackbornc652de82013-02-15 16:32:56 -0800677 sb.append("}");
678 return sb.toString();
Jeff Brownc5df37c2012-09-13 11:45:07 -0700679 }
680
Steven Timotiusaf03df62017-07-18 16:56:43 -0700681 /**
682 * Write to a protocol buffer output stream.
683 * Protocol buffer message definition at {@link android.view.DisplayInfoProto}
684 *
685 * @param protoOutputStream Stream to write the Rect object to.
686 * @param fieldId Field Id of the DisplayInfoProto as defined in the parent message
687 */
688 public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId) {
689 final long token = protoOutputStream.start(fieldId);
690 protoOutputStream.write(LOGICAL_WIDTH, logicalWidth);
691 protoOutputStream.write(LOGICAL_HEIGHT, logicalHeight);
692 protoOutputStream.write(APP_WIDTH, appWidth);
693 protoOutputStream.write(APP_HEIGHT, appHeight);
Andrii Kulian764e1042018-02-08 15:12:14 -0800694 protoOutputStream.write(NAME, name);
Steven Timotiusaf03df62017-07-18 16:56:43 -0700695 protoOutputStream.end(token);
696 }
697
Jeff Brownc5df37c2012-09-13 11:45:07 -0700698 private static String flagsToString(int flags) {
699 StringBuilder result = new StringBuilder();
Jeff Brownf0681b32012-10-23 17:35:57 -0700700 if ((flags & Display.FLAG_SECURE) != 0) {
701 result.append(", FLAG_SECURE");
702 }
Jeff Brown77aebfd2012-10-01 21:07:03 -0700703 if ((flags & Display.FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
704 result.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS");
Jeff Brownc5df37c2012-09-13 11:45:07 -0700705 }
Jeff Browna506a6e2013-06-04 00:02:38 -0700706 if ((flags & Display.FLAG_PRIVATE) != 0) {
707 result.append(", FLAG_PRIVATE");
708 }
Jeff Brown7d00aff2013-08-02 19:03:49 -0700709 if ((flags & Display.FLAG_PRESENTATION) != 0) {
710 result.append(", FLAG_PRESENTATION");
711 }
Jeff Brownd46747a2015-04-15 19:02:36 -0700712 if ((flags & Display.FLAG_SCALING_DISABLED) != 0) {
713 result.append(", FLAG_SCALING_DISABLED");
714 }
Adam Powell49e7ff92015-05-14 16:18:53 -0700715 if ((flags & Display.FLAG_ROUND) != 0) {
716 result.append(", FLAG_ROUND");
717 }
Jeff Brownc5df37c2012-09-13 11:45:07 -0700718 return result.toString();
Jeff Brownbf5740e2012-08-19 23:20:02 -0700719 }
Jeff Brownfa25bf52012-07-23 19:26:30 -0700720}