blob: 46e4d6ed5cce3671d1c98bdc4181560fdf08d855 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2006 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
Dianne Hackborn5be8de32011-05-24 18:11:57 -070019import android.content.res.CompatibilityInfo;
Jeff Brownfa25bf52012-07-23 19:26:30 -070020import android.graphics.PixelFormat;
Dianne Hackbornac8dea12011-04-20 18:18:51 -070021import android.graphics.Point;
22import android.graphics.Rect;
Jeff Brownfa25bf52012-07-23 19:26:30 -070023import android.hardware.display.DisplayManager;
Dianne Hackbornac8dea12011-04-20 18:18:51 -070024import android.os.RemoteException;
Dianne Hackbornac8dea12011-04-20 18:18:51 -070025import android.os.SystemClock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080026import android.util.DisplayMetrics;
Jeff Brownfa25bf52012-07-23 19:26:30 -070027import android.util.Log;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028
Jeff Brownbc68a592011-07-25 12:58:12 -070029/**
Jeff Brownfa25bf52012-07-23 19:26:30 -070030 * Provides information about the size and density of a logical display.
31 * <p>
32 * The display area is described in two different ways.
33 * <ul>
34 * <li>The application display area specifies the part of the display that may contain
35 * an application window, excluding the system decorations. The application display area may
36 * be smaller than the real display area because the system subtracts the space needed
37 * for decor elements such as the status bar. Use the following methods to query the
38 * application display area: {@link #getSize}, {@link #getRectSize} and {@link #getMetrics}.</li>
39 * <li>The real display area specifies the part of the display that contains content
40 * including the system decorations. Even so, the real display area may be smaller than the
41 * physical size of the display if the window manager is emulating a smaller display
42 * using (adb shell am display-size). Use the following methods to query the
43 * real display area: {@link #getRealSize}, {@link #getRealMetrics}.</li>
44 * </ul>
45 * </p><p>
46 * A logical display does not necessarily represent a particular physical display device
47 * such as the built-in screen or an external monitor. The contents of a logical
48 * display may be presented on one or more physical displays according to the devices
49 * that are currently attached and whether mirroring has been enabled.
50 * </p>
Jeff Brownbc68a592011-07-25 12:58:12 -070051 */
Jeff Brownfa25bf52012-07-23 19:26:30 -070052public final class Display {
53 private static final String TAG = "Display";
54
55 private final int mDisplayId;
56 private final CompatibilityInfoHolder mCompatibilityInfo;
57 private final DisplayInfo mDisplayInfo = new DisplayInfo();
58
59 // Temporary display metrics structure used for compatibility mode.
60 private final DisplayMetrics mTempMetrics = new DisplayMetrics();
61
62 // We cache the app width and height properties briefly between calls
63 // to getHeight() and getWidth() to ensure that applications perceive
64 // consistent results when the size changes (most of the time).
65 // Applications should now be using getSize() instead.
66 private static final int CACHED_APP_SIZE_DURATION_MILLIS = 20;
67 private long mLastCachedAppSizeUpdate;
68 private int mCachedAppWidthCompat;
69 private int mCachedAppHeightCompat;
Dianne Hackborn5fd21692011-06-07 14:09:47 -070070
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071 /**
Jeff Brownbc68a592011-07-25 12:58:12 -070072 * The default Display id.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080073 */
74 public static final int DEFAULT_DISPLAY = 0;
75
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076 /**
Jeff Brownfa25bf52012-07-23 19:26:30 -070077 * Internal method to create a display.
78 * Applications should use {@link android.view.WindowManager#getDefaultDisplay()}
79 * to get a display object for the default display.
80 *
81 * @hide
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082 */
Jeff Brownfa25bf52012-07-23 19:26:30 -070083 public Display(int displayId, CompatibilityInfoHolder compatibilityInfo) {
84 mDisplayId = displayId;
85 mCompatibilityInfo = compatibilityInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086 }
Dianne Hackborn5fd21692011-06-07 14:09:47 -070087
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088 /**
Jeff Brownfa25bf52012-07-23 19:26:30 -070089 * Gets the display id.
90 * <p>
91 * Each logical display has a unique id.
92 * The default display has id {@link #DEFAULT_DISPLAY}.
93 * </p>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080094 */
95 public int getDisplayId() {
Jeff Brownfa25bf52012-07-23 19:26:30 -070096 return mDisplayId;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097 }
98
99 /**
Jeff Brownbc68a592011-07-25 12:58:12 -0700100 * Gets the size of the display, in pixels.
101 * <p>
102 * Note that this value should <em>not</em> be used for computing layouts,
103 * since a device will typically have screen decoration (such as a status bar)
Dianne Hackborn5cb70b52010-02-25 17:01:14 -0800104 * along the edges of the display that reduce the amount of application
Jeff Brownbc68a592011-07-25 12:58:12 -0700105 * space available from the size returned here. Layouts should instead use
106 * the window size.
107 * </p><p>
108 * The size is adjusted based on the current rotation of the display.
109 * </p><p>
110 * The size returned by this method does not necessarily represent the
111 * actual raw size (native resolution) of the display. The returned size may
Jeff Brownfa25bf52012-07-23 19:26:30 -0700112 * be adjusted to exclude certain system decoration elements that are always visible.
Jeff Brownbc68a592011-07-25 12:58:12 -0700113 * It may also be scaled to provide compatibility with older applications that
114 * were originally designed for smaller displays.
115 * </p>
116 *
117 * @param outSize A {@link Point} object to receive the size information.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800118 */
Dianne Hackbornac8dea12011-04-20 18:18:51 -0700119 public void getSize(Point outSize) {
Jeff Brownfa25bf52012-07-23 19:26:30 -0700120 synchronized (this) {
121 updateDisplayInfoLocked();
122 mDisplayInfo.getAppMetrics(mTempMetrics, mCompatibilityInfo);
123 outSize.x = mTempMetrics.widthPixels;
124 outSize.y = mTempMetrics.heightPixels;
Dianne Hackbornac8dea12011-04-20 18:18:51 -0700125 }
126 }
Jeff Brownfa25bf52012-07-23 19:26:30 -0700127
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128 /**
Jeff Brownbc68a592011-07-25 12:58:12 -0700129 * Gets the size of the display as a rectangle, in pixels.
130 *
131 * @param outSize A {@link Rect} object to receive the size information.
132 * @see #getSize(Point)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133 */
Dianne Hackbornac8dea12011-04-20 18:18:51 -0700134 public void getRectSize(Rect outSize) {
Jeff Brownfa25bf52012-07-23 19:26:30 -0700135 synchronized (this) {
136 updateDisplayInfoLocked();
137 mDisplayInfo.getAppMetrics(mTempMetrics, mCompatibilityInfo);
138 outSize.set(0, 0, mTempMetrics.widthPixels, mTempMetrics.heightPixels);
Dianne Hackbornac8dea12011-04-20 18:18:51 -0700139 }
140 }
141
142 /**
Dianne Hackborn68c33ca2012-04-19 14:51:25 -0700143 * Return the range of display sizes an application can expect to encounter
144 * under normal operation, as long as there is no physical change in screen
145 * size. This is basically the sizes you will see as the orientation
146 * changes, taking into account whatever screen decoration there is in
147 * each rotation. For example, the status bar is always at the top of the
148 * screen, so it will reduce the height both in landscape and portrait, and
149 * the smallest height returned here will be the smaller of the two.
150 *
151 * This is intended for applications to get an idea of the range of sizes
152 * they will encounter while going through device rotations, to provide a
153 * stable UI through rotation. The sizes here take into account all standard
154 * system decorations that reduce the size actually available to the
155 * application: the status bar, navigation bar, system bar, etc. It does
156 * <em>not</em> take into account more transient elements like an IME
157 * soft keyboard.
158 *
159 * @param outSmallestSize Filled in with the smallest width and height
160 * that the application will encounter, in pixels (not dp units). The x
161 * (width) dimension here directly corresponds to
162 * {@link android.content.res.Configuration#smallestScreenWidthDp
163 * Configuration.smallestScreenWidthDp}, except the value here is in raw
164 * screen pixels rather than dp units. Your application may of course
165 * still get smaller space yet if, for example, a soft keyboard is
166 * being displayed.
167 * @param outLargestSize Filled in with the largest width and height
168 * that the application will encounter, in pixels (not dp units). Your
169 * application may of course still get larger space than this if,
170 * for example, screen decorations like the status bar are being hidden.
171 */
172 public void getCurrentSizeRange(Point outSmallestSize, Point outLargestSize) {
Jeff Brownfa25bf52012-07-23 19:26:30 -0700173 synchronized (this) {
174 updateDisplayInfoLocked();
175 outSmallestSize.x = mDisplayInfo.smallestNominalAppWidth;
176 outSmallestSize.y = mDisplayInfo.smallestNominalAppHeight;
177 outLargestSize.x = mDisplayInfo.largestNominalAppWidth;
178 outLargestSize.y = mDisplayInfo.largestNominalAppHeight;
Dianne Hackborn68c33ca2012-04-19 14:51:25 -0700179 }
180 }
181
182 /**
Dianne Hackbornac8dea12011-04-20 18:18:51 -0700183 * Return the maximum screen size dimension that will happen. This is
184 * mostly for wallpapers.
185 * @hide
186 */
187 public int getMaximumSizeDimension() {
Jeff Brownfa25bf52012-07-23 19:26:30 -0700188 synchronized (this) {
189 updateDisplayInfoLocked();
190 return Math.max(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
Dianne Hackbornac8dea12011-04-20 18:18:51 -0700191 }
192 }
193
194 /**
195 * @deprecated Use {@link #getSize(Point)} instead.
196 */
197 @Deprecated
198 public int getWidth() {
Jeff Brownfa25bf52012-07-23 19:26:30 -0700199 synchronized (this) {
200 updateCachedAppSizeIfNeededLocked();
201 return mCachedAppWidthCompat;
Dianne Hackbornac8dea12011-04-20 18:18:51 -0700202 }
203 }
204
205 /**
206 * @deprecated Use {@link #getSize(Point)} instead.
207 */
208 @Deprecated
209 public int getHeight() {
Jeff Brownfa25bf52012-07-23 19:26:30 -0700210 synchronized (this) {
211 updateCachedAppSizeIfNeededLocked();
212 return mCachedAppHeightCompat;
Dianne Hackbornac8dea12011-04-20 18:18:51 -0700213 }
214 }
215
Jeff Brownbc68a592011-07-25 12:58:12 -0700216 /**
Dianne Hackborn5cb70b52010-02-25 17:01:14 -0800217 * Returns the rotation of the screen from its "natural" orientation.
218 * The returned value may be {@link Surface#ROTATION_0 Surface.ROTATION_0}
219 * (no rotation), {@link Surface#ROTATION_90 Surface.ROTATION_90},
220 * {@link Surface#ROTATION_180 Surface.ROTATION_180}, or
221 * {@link Surface#ROTATION_270 Surface.ROTATION_270}. For
222 * example, if a device has a naturally tall screen, and the user has
223 * turned it on its side to go into a landscape orientation, the value
224 * returned here may be either {@link Surface#ROTATION_90 Surface.ROTATION_90}
225 * or {@link Surface#ROTATION_270 Surface.ROTATION_270} depending on
226 * the direction it was turned. The angle is the rotation of the drawn
227 * graphics on the screen, which is the opposite direction of the physical
228 * rotation of the device. For example, if the device is rotated 90
229 * degrees counter-clockwise, to compensate rendering will be rotated by
230 * 90 degrees clockwise and thus the returned value here will be
231 * {@link Surface#ROTATION_90 Surface.ROTATION_90}.
232 */
233 public int getRotation() {
Jeff Brownfa25bf52012-07-23 19:26:30 -0700234 synchronized (this) {
235 updateDisplayInfoLocked();
236 return mDisplayInfo.rotation;
237 }
Dianne Hackborn5cb70b52010-02-25 17:01:14 -0800238 }
Jeff Brownfa25bf52012-07-23 19:26:30 -0700239
Dianne Hackborn5cb70b52010-02-25 17:01:14 -0800240 /**
Joe Onorato4c904a32010-02-26 12:35:55 -0800241 * @deprecated use {@link #getRotation}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800242 * @return orientation of this display.
243 */
Jeff Brownfa25bf52012-07-23 19:26:30 -0700244 @Deprecated
245 public int getOrientation() {
246 return getRotation();
247 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800248
249 /**
Jeff Brownfa25bf52012-07-23 19:26:30 -0700250 * Gets the pixel format of the display.
251 * @return One of the constants defined in {@link android.graphics.PixelFormat}.
252 *
253 * @deprecated This method is no longer supported.
254 * The result is always {@link PixelFormat#RGBA_8888}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800255 */
Jeff Brownfa25bf52012-07-23 19:26:30 -0700256 @Deprecated
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800257 public int getPixelFormat() {
Jeff Brownfa25bf52012-07-23 19:26:30 -0700258 return PixelFormat.RGBA_8888;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800259 }
Jeff Brownfa25bf52012-07-23 19:26:30 -0700260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800261 /**
Jeff Brownfa25bf52012-07-23 19:26:30 -0700262 * Gets the refresh rate of this display in frames per second.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263 */
264 public float getRefreshRate() {
Jeff Brownfa25bf52012-07-23 19:26:30 -0700265 synchronized (this) {
266 updateDisplayInfoLocked();
267 return mDisplayInfo.refreshRate;
268 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800269 }
Jeff Brownfa25bf52012-07-23 19:26:30 -0700270
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800271 /**
Jeff Brownbc68a592011-07-25 12:58:12 -0700272 * Gets display metrics that describe the size and density of this display.
273 * <p>
274 * The size is adjusted based on the current rotation of the display.
275 * </p><p>
276 * The size returned by this method does not necessarily represent the
277 * actual raw size (native resolution) of the display. The returned size may
278 * be adjusted to exclude certain system decor elements that are always visible.
279 * It may also be scaled to provide compatibility with older applications that
280 * were originally designed for smaller displays.
281 * </p>
282 *
283 * @param outMetrics A {@link DisplayMetrics} object to receive the metrics.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800284 */
285 public void getMetrics(DisplayMetrics outMetrics) {
Jeff Brownfa25bf52012-07-23 19:26:30 -0700286 synchronized (this) {
287 updateDisplayInfoLocked();
288 mDisplayInfo.getAppMetrics(outMetrics, mCompatibilityInfo);
Dianne Hackborn68066c22011-04-21 17:26:39 -0700289 }
Dianne Hackborn5be8de32011-05-24 18:11:57 -0700290
Jeff Brownfa25bf52012-07-23 19:26:30 -0700291 final CompatibilityInfo ci = mCompatibilityInfo.getIfNeeded();
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700292 if (ci != null) {
293 ci.applyToDisplayMetrics(outMetrics);
Dianne Hackborn5be8de32011-05-24 18:11:57 -0700294 }
Jeff Brownfa25bf52012-07-23 19:26:30 -0700295 }
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700296
Jeff Brownfa25bf52012-07-23 19:26:30 -0700297 /**
298 * Gets the real size of the display without subtracting any window decor or
299 * applying any compatibility scale factors.
300 * <p>
301 * The size is adjusted based on the current rotation of the display.
302 * </p><p>
303 * The real size may be smaller than the physical size of the screen when the
304 * window manager is emulating a smaller display (using adb shell am display-size).
305 * </p>
306 *
307 * @param outSize Set to the real size of the display.
308 */
309 public void getRealSize(Point outSize) {
310 synchronized (this) {
311 updateDisplayInfoLocked();
312 outSize.x = mDisplayInfo.logicalWidth;
313 outSize.y = mDisplayInfo.logicalHeight;
314 }
Dianne Hackborn68066c22011-04-21 17:26:39 -0700315 }
316
317 /**
Jeff Brownbc68a592011-07-25 12:58:12 -0700318 * Gets display metrics based on the real size of this display.
Jeff Brownfa25bf52012-07-23 19:26:30 -0700319 * <p>
320 * The size is adjusted based on the current rotation of the display.
321 * </p><p>
322 * The real size may be smaller than the physical size of the screen when the
323 * window manager is emulating a smaller display (using adb shell am display-size).
324 * </p>
325 *
326 * @param outMetrics A {@link DisplayMetrics} object to receive the metrics.
Dianne Hackborn68066c22011-04-21 17:26:39 -0700327 */
328 public void getRealMetrics(DisplayMetrics outMetrics) {
Jeff Brownfa25bf52012-07-23 19:26:30 -0700329 synchronized (this) {
330 updateDisplayInfoLocked();
331 mDisplayInfo.getLogicalMetrics(outMetrics, null);
Jeff Brownbc68a592011-07-25 12:58:12 -0700332 }
Dianne Hackborn68066c22011-04-21 17:26:39 -0700333 }
334
Jeff Brownfa25bf52012-07-23 19:26:30 -0700335 private void updateDisplayInfoLocked() {
336 // TODO: only refresh the display information when needed
337 if (!DisplayManager.getInstance().getDisplayInfo(mDisplayId, mDisplayInfo)) {
338 Log.e(TAG, "Could not get information about logical display " + mDisplayId);
339 }
Jeff Brownbc68a592011-07-25 12:58:12 -0700340 }
341
Jeff Brownfa25bf52012-07-23 19:26:30 -0700342 private void updateCachedAppSizeIfNeededLocked() {
343 long now = SystemClock.uptimeMillis();
344 if (now > mLastCachedAppSizeUpdate + CACHED_APP_SIZE_DURATION_MILLIS) {
345 updateDisplayInfoLocked();
346 mDisplayInfo.getAppMetrics(mTempMetrics, mCompatibilityInfo);
347 mCachedAppWidthCompat = mTempMetrics.widthPixels;
348 mCachedAppHeightCompat = mTempMetrics.heightPixels;
349 mLastCachedAppSizeUpdate = now;
350 }
Jeff Brownbc68a592011-07-25 12:58:12 -0700351 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800352}
353