blob: 305fd5c8b899449db7a0e9d2cc4ec8f05a4a9fde [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
19import android.content.res.CompatibilityInfo;
20import android.os.Parcel;
21import android.os.Parcelable;
22import android.util.DisplayMetrics;
23
Jeff Brown4ed8fe72012-08-30 18:18:29 -070024import libcore.util.Objects;
25
Jeff Brownfa25bf52012-07-23 19:26:30 -070026/**
27 * Describes the characteristics of a particular logical display.
28 * @hide
29 */
30public final class DisplayInfo implements Parcelable {
31 /**
Jeff Brown4ed8fe72012-08-30 18:18:29 -070032 * The surface flinger layer stack associated with this logical display.
33 */
34 public int layerStack;
35
36 /**
Jeff Brownc5df37c2012-09-13 11:45:07 -070037 * Display flags.
38 */
39 public int flags;
40
41 /**
Jeff Brown92130f62012-10-24 21:28:33 -070042 * Display type.
43 */
44 public int type;
45
46 /**
47 * Display address, or null if none.
48 * Interpretation varies by display type.
49 */
50 public String address;
51
52 /**
Jeff Brown4ed8fe72012-08-30 18:18:29 -070053 * The human-readable name of the display.
54 */
55 public String name;
56
57 /**
Jeff Brownfa25bf52012-07-23 19:26:30 -070058 * The width of the portion of the display that is available to applications, in pixels.
59 * Represents the size of the display minus any system decorations.
60 */
61 public int appWidth;
62
63 /**
64 * The height of the portion of the display that is available to applications, in pixels.
65 * Represents the size of the display minus any system decorations.
66 */
67 public int appHeight;
68
69 /**
70 * The smallest value of {@link #appWidth} that an application is likely to encounter,
71 * in pixels, excepting cases where the width may be even smaller due to the presence
72 * of a soft keyboard, for example.
73 */
74 public int smallestNominalAppWidth;
75
76 /**
77 * The smallest value of {@link #appHeight} that an application is likely to encounter,
78 * in pixels, excepting cases where the height may be even smaller due to the presence
79 * of a soft keyboard, for example.
80 */
81 public int smallestNominalAppHeight;
82
83 /**
84 * The largest value of {@link #appWidth} that an application is likely to encounter,
85 * in pixels, excepting cases where the width may be even larger due to system decorations
86 * such as the status bar being hidden, for example.
87 */
88 public int largestNominalAppWidth;
89
90 /**
91 * The largest value of {@link #appHeight} that an application is likely to encounter,
92 * in pixels, excepting cases where the height may be even larger due to system decorations
93 * such as the status bar being hidden, for example.
94 */
95 public int largestNominalAppHeight;
96
97 /**
98 * The logical width of the display, in pixels.
99 * Represents the usable size of the display which may be smaller than the
100 * physical size when the system is emulating a smaller display.
101 */
102 public int logicalWidth;
103
104 /**
105 * The logical height of the display, in pixels.
106 * Represents the usable size of the display which may be smaller than the
107 * physical size when the system is emulating a smaller display.
108 */
109 public int logicalHeight;
110
111 /**
112 * The rotation of the display relative to its natural orientation.
113 * May be one of {@link android.view.Surface#ROTATION_0},
114 * {@link android.view.Surface#ROTATION_90}, {@link android.view.Surface#ROTATION_180},
115 * {@link android.view.Surface#ROTATION_270}.
116 * <p>
117 * The value of this field is indeterminate if the logical display is presented on
118 * more than one physical display.
119 * </p>
120 */
121 public int rotation;
122
123 /**
124 * The refresh rate of this display in frames per second.
125 * <p>
126 * The value of this field is indeterminate if the logical display is presented on
127 * more than one physical display.
128 * </p>
129 */
130 public float refreshRate;
131
132 /**
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700133 * The logical display density which is the basis for density-independent
134 * pixels.
Jeff Brownfa25bf52012-07-23 19:26:30 -0700135 */
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700136 public int logicalDensityDpi;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700137
138 /**
139 * The exact physical pixels per inch of the screen in the X dimension.
140 * <p>
141 * The value of this field is indeterminate if the logical display is presented on
142 * more than one physical display.
143 * </p>
144 */
145 public float physicalXDpi;
146
147 /**
148 * The exact physical pixels per inch of the screen in the Y dimension.
149 * <p>
150 * The value of this field is indeterminate if the logical display is presented on
151 * more than one physical display.
152 * </p>
153 */
154 public float physicalYDpi;
155
156 public static final Creator<DisplayInfo> CREATOR = new Creator<DisplayInfo>() {
Jeff Brown92130f62012-10-24 21:28:33 -0700157 @Override
Jeff Brownfa25bf52012-07-23 19:26:30 -0700158 public DisplayInfo createFromParcel(Parcel source) {
159 return new DisplayInfo(source);
160 }
161
Jeff Brown92130f62012-10-24 21:28:33 -0700162 @Override
Jeff Brownfa25bf52012-07-23 19:26:30 -0700163 public DisplayInfo[] newArray(int size) {
164 return new DisplayInfo[size];
165 }
166 };
167
168 public DisplayInfo() {
169 }
170
Jeff Brownbd6e1502012-08-28 03:27:37 -0700171 public DisplayInfo(DisplayInfo other) {
172 copyFrom(other);
173 }
174
Jeff Brownfa25bf52012-07-23 19:26:30 -0700175 private DisplayInfo(Parcel source) {
176 readFromParcel(source);
177 }
178
179 @Override
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700180 public boolean equals(Object o) {
181 return o instanceof DisplayInfo && equals((DisplayInfo)o);
182 }
183
184 public boolean equals(DisplayInfo other) {
185 return other != null
186 && layerStack == other.layerStack
Jeff Brown92130f62012-10-24 21:28:33 -0700187 && flags == other.flags
188 && type == other.type
189 && Objects.equal(address, other.address)
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700190 && Objects.equal(name, other.name)
191 && appWidth == other.appWidth
192 && appHeight == other.appHeight
193 && smallestNominalAppWidth == other.smallestNominalAppWidth
194 && smallestNominalAppHeight == other.smallestNominalAppHeight
195 && largestNominalAppWidth == other.largestNominalAppWidth
196 && largestNominalAppHeight == other.largestNominalAppHeight
197 && logicalWidth == other.logicalWidth
198 && logicalHeight == other.logicalHeight
199 && rotation == other.rotation
200 && refreshRate == other.refreshRate
201 && logicalDensityDpi == other.logicalDensityDpi
202 && physicalXDpi == other.physicalXDpi
203 && physicalYDpi == other.physicalYDpi;
204 }
205
206 @Override
207 public int hashCode() {
208 return 0; // don't care
Jeff Brownfa25bf52012-07-23 19:26:30 -0700209 }
210
211 public void copyFrom(DisplayInfo other) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700212 layerStack = other.layerStack;
Jeff Brownc5df37c2012-09-13 11:45:07 -0700213 flags = other.flags;
Jeff Brown92130f62012-10-24 21:28:33 -0700214 type = other.type;
215 address = other.address;
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700216 name = other.name;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700217 appWidth = other.appWidth;
218 appHeight = other.appHeight;
219 smallestNominalAppWidth = other.smallestNominalAppWidth;
220 smallestNominalAppHeight = other.smallestNominalAppHeight;
221 largestNominalAppWidth = other.largestNominalAppWidth;
222 largestNominalAppHeight = other.largestNominalAppHeight;
223 logicalWidth = other.logicalWidth;
224 logicalHeight = other.logicalHeight;
225 rotation = other.rotation;
226 refreshRate = other.refreshRate;
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700227 logicalDensityDpi = other.logicalDensityDpi;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700228 physicalXDpi = other.physicalXDpi;
229 physicalYDpi = other.physicalYDpi;
230 }
231
232 public void readFromParcel(Parcel source) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700233 layerStack = source.readInt();
Jeff Brownc5df37c2012-09-13 11:45:07 -0700234 flags = source.readInt();
Jeff Brown92130f62012-10-24 21:28:33 -0700235 type = source.readInt();
236 address = source.readString();
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700237 name = source.readString();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700238 appWidth = source.readInt();
239 appHeight = source.readInt();
240 smallestNominalAppWidth = source.readInt();
241 smallestNominalAppHeight = source.readInt();
242 largestNominalAppWidth = source.readInt();
243 largestNominalAppHeight = source.readInt();
244 logicalWidth = source.readInt();
245 logicalHeight = source.readInt();
246 rotation = source.readInt();
247 refreshRate = source.readFloat();
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700248 logicalDensityDpi = source.readInt();
Jeff Brownfa25bf52012-07-23 19:26:30 -0700249 physicalXDpi = source.readFloat();
250 physicalYDpi = source.readFloat();
251 }
252
253 @Override
254 public void writeToParcel(Parcel dest, int flags) {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700255 dest.writeInt(layerStack);
Jeff Brown3f2ba622012-10-04 14:57:44 -0700256 dest.writeInt(this.flags);
Jeff Brown92130f62012-10-24 21:28:33 -0700257 dest.writeInt(type);
258 dest.writeString(address);
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700259 dest.writeString(name);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700260 dest.writeInt(appWidth);
261 dest.writeInt(appHeight);
262 dest.writeInt(smallestNominalAppWidth);
263 dest.writeInt(smallestNominalAppHeight);
264 dest.writeInt(largestNominalAppWidth);
265 dest.writeInt(largestNominalAppHeight);
266 dest.writeInt(logicalWidth);
267 dest.writeInt(logicalHeight);
268 dest.writeInt(rotation);
269 dest.writeFloat(refreshRate);
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700270 dest.writeInt(logicalDensityDpi);
Jeff Brownfa25bf52012-07-23 19:26:30 -0700271 dest.writeFloat(physicalXDpi);
272 dest.writeFloat(physicalYDpi);
273 }
274
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700275 @Override
276 public int describeContents() {
277 return 0;
278 }
279
Jeff Brownfa25bf52012-07-23 19:26:30 -0700280 public void getAppMetrics(DisplayMetrics outMetrics, CompatibilityInfoHolder cih) {
281 getMetricsWithSize(outMetrics, cih, appWidth, appHeight);
282 }
283
284 public void getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfoHolder cih) {
285 getMetricsWithSize(outMetrics, cih, logicalWidth, logicalHeight);
286 }
287
Jeff Brown7f3994e2012-12-04 14:04:28 -0800288 public int getNaturalWidth() {
289 return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ?
290 logicalWidth : logicalHeight;
291 }
292
293 public int getNaturalHeight() {
294 return rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180 ?
295 logicalHeight : logicalWidth;
296 }
297
Jeff Brownfa25bf52012-07-23 19:26:30 -0700298 private void getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfoHolder cih,
299 int width, int height) {
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700300 outMetrics.densityDpi = outMetrics.noncompatDensityDpi = logicalDensityDpi;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700301 outMetrics.noncompatWidthPixels = outMetrics.widthPixels = width;
302 outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height;
303
Dianne Hackborn908aecc2012-07-31 16:37:34 -0700304 outMetrics.density = outMetrics.noncompatDensity =
305 logicalDensityDpi * DisplayMetrics.DENSITY_DEFAULT_SCALE;
Jeff Brownfa25bf52012-07-23 19:26:30 -0700306 outMetrics.scaledDensity = outMetrics.noncompatScaledDensity = outMetrics.density;
307 outMetrics.xdpi = outMetrics.noncompatXdpi = physicalXDpi;
308 outMetrics.ydpi = outMetrics.noncompatYdpi = physicalYDpi;
309
310 if (cih != null) {
311 CompatibilityInfo ci = cih.getIfNeeded();
312 if (ci != null) {
313 ci.applyToDisplayMetrics(outMetrics);
314 }
315 }
316 }
Jeff Brownbf5740e2012-08-19 23:20:02 -0700317
318 // For debugging purposes
319 @Override
320 public String toString() {
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700321 return "DisplayInfo{\"" + name + "\", app " + appWidth + " x " + appHeight
Jeff Brownbf5740e2012-08-19 23:20:02 -0700322 + ", real " + logicalWidth + " x " + logicalHeight
323 + ", largest app " + largestNominalAppWidth + " x " + largestNominalAppHeight
324 + ", smallest app " + smallestNominalAppWidth + " x " + smallestNominalAppHeight
325 + ", " + refreshRate + " fps"
326 + ", rotation " + rotation
327 + ", density " + logicalDensityDpi
Jeff Brown4ed8fe72012-08-30 18:18:29 -0700328 + ", " + physicalXDpi + " x " + physicalYDpi + " dpi"
Jeff Brown92130f62012-10-24 21:28:33 -0700329 + ", layerStack " + layerStack
330 + ", type " + Display.typeToString(type)
331 + ", address " + address
332 + flagsToString(flags) + "}";
Jeff Brownc5df37c2012-09-13 11:45:07 -0700333 }
334
335 private static String flagsToString(int flags) {
336 StringBuilder result = new StringBuilder();
Jeff Brownf0681b32012-10-23 17:35:57 -0700337 if ((flags & Display.FLAG_SECURE) != 0) {
338 result.append(", FLAG_SECURE");
339 }
Jeff Brown77aebfd2012-10-01 21:07:03 -0700340 if ((flags & Display.FLAG_SUPPORTS_PROTECTED_BUFFERS) != 0) {
341 result.append(", FLAG_SUPPORTS_PROTECTED_BUFFERS");
Jeff Brownc5df37c2012-09-13 11:45:07 -0700342 }
343 return result.toString();
Jeff Brownbf5740e2012-08-19 23:20:02 -0700344 }
Jeff Brownfa25bf52012-07-23 19:26:30 -0700345}