blob: ad2283ea9285ef4a3ddaa4ec0732b67aa34decf7 [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;
Dianne Hackbornac8dea12011-04-20 18:18:51 -070020import android.graphics.Point;
21import android.graphics.Rect;
22import android.os.RemoteException;
23import android.os.ServiceManager;
24import android.os.SystemClock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080025import android.util.DisplayMetrics;
Dianne Hackbornac8dea12011-04-20 18:18:51 -070026import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027
Jeff Brownbc68a592011-07-25 12:58:12 -070028/**
29 * Provides information about the display size and density.
30 */
Dianne Hackbornac8dea12011-04-20 18:18:51 -070031public class Display {
Dianne Hackborn5fd21692011-06-07 14:09:47 -070032 static final String TAG = "Display";
Dianne Hackborn30c845f2011-10-05 11:30:55 -070033 static final boolean DEBUG_DISPLAY_SIZE = false;
Dianne Hackborn5fd21692011-06-07 14:09:47 -070034
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035 /**
Jeff Brownbc68a592011-07-25 12:58:12 -070036 * The default Display id.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037 */
38 public static final int DEFAULT_DISPLAY = 0;
39
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040 /**
Mathias Agopian833533c2010-08-16 13:28:55 -070041 * Use {@link android.view.WindowManager#getDefaultDisplay()
42 * WindowManager.getDefaultDisplay()} to create a Display object.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080043 * Display gives you access to some information about a particular display
44 * connected to the device.
45 */
Dianne Hackborn5fd21692011-06-07 14:09:47 -070046 Display(int display, CompatibilityInfoHolder compatInfo) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080047 // initalize the statics when this class is first instansiated. This is
48 // done here instead of in the static block because Zygote
Dianne Hackbornac8dea12011-04-20 18:18:51 -070049 synchronized (sStaticInit) {
50 if (!sInitialized) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080051 nativeClassInit();
Dianne Hackbornac8dea12011-04-20 18:18:51 -070052 sInitialized = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053 }
54 }
Dianne Hackborn5fd21692011-06-07 14:09:47 -070055 mCompatibilityInfo = compatInfo != null ? compatInfo : new CompatibilityInfoHolder();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056 mDisplay = display;
57 init(display);
58 }
Dianne Hackborn5fd21692011-06-07 14:09:47 -070059
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080060 /**
Dianne Hackborn5cb70b52010-02-25 17:01:14 -080061 * Returns the index of this display. This is currently undefined; do
62 * not use.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063 */
64 public int getDisplayId() {
65 return mDisplay;
66 }
67
68 /**
Dianne Hackborn5cb70b52010-02-25 17:01:14 -080069 * Returns the number of displays connected to the device. This is
70 * currently undefined; do not use.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080071 */
72 native static int getDisplayCount();
73
74 /**
Jeff Brownbc68a592011-07-25 12:58:12 -070075 * Gets the size of the display, in pixels.
76 * <p>
77 * Note that this value should <em>not</em> be used for computing layouts,
78 * since a device will typically have screen decoration (such as a status bar)
Dianne Hackborn5cb70b52010-02-25 17:01:14 -080079 * along the edges of the display that reduce the amount of application
Jeff Brownbc68a592011-07-25 12:58:12 -070080 * space available from the size returned here. Layouts should instead use
81 * the window size.
82 * </p><p>
83 * The size is adjusted based on the current rotation of the display.
84 * </p><p>
85 * The size returned by this method does not necessarily represent the
86 * actual raw size (native resolution) of the display. The returned size may
87 * be adjusted to exclude certain system decor elements that are always visible.
88 * It may also be scaled to provide compatibility with older applications that
89 * were originally designed for smaller displays.
90 * </p>
91 *
92 * @param outSize A {@link Point} object to receive the size information.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 */
Dianne Hackbornac8dea12011-04-20 18:18:51 -070094 public void getSize(Point outSize) {
Dianne Hackborn81e56d52011-05-26 00:55:58 -070095 getSizeInternal(outSize, true);
96 }
97
Dianne Hackborn81e56d52011-05-26 00:55:58 -070098 private void getSizeInternal(Point outSize, boolean doCompat) {
Dianne Hackbornac8dea12011-04-20 18:18:51 -070099 try {
100 IWindowManager wm = getWindowManager();
101 if (wm != null) {
102 wm.getDisplaySize(outSize);
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700103 CompatibilityInfo ci;
104 if (doCompat && (ci=mCompatibilityInfo.getIfNeeded()) != null) {
Dianne Hackborn81e56d52011-05-26 00:55:58 -0700105 synchronized (mTmpMetrics) {
Dianne Hackborn2b31d532011-06-23 11:58:50 -0700106 mTmpMetrics.noncompatWidthPixels = outSize.x;
107 mTmpMetrics.noncompatHeightPixels = outSize.y;
Dianne Hackborn81e56d52011-05-26 00:55:58 -0700108 mTmpMetrics.density = mDensity;
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700109 ci.applyToDisplayMetrics(mTmpMetrics);
Dianne Hackborn81e56d52011-05-26 00:55:58 -0700110 outSize.x = mTmpMetrics.widthPixels;
111 outSize.y = mTmpMetrics.heightPixels;
112 }
113 }
Dianne Hackbornac8dea12011-04-20 18:18:51 -0700114 } else {
115 // This is just for boot-strapping, initializing the
116 // system process before the window manager is up.
Jeff Brownbc68a592011-07-25 12:58:12 -0700117 outSize.x = getRawWidth();
118 outSize.y = getRawHeight();
Dianne Hackbornac8dea12011-04-20 18:18:51 -0700119 }
Dianne Hackborn36991742011-10-11 21:35:26 -0700120 if (false) {
121 RuntimeException here = new RuntimeException("here");
122 here.fillInStackTrace();
123 Slog.v(TAG, "Returning display size: " + outSize, here);
124 }
Dianne Hackbornec537452011-09-14 19:19:55 -0700125 if (DEBUG_DISPLAY_SIZE && doCompat) Slog.v(
126 TAG, "Returning display size: " + outSize);
Dianne Hackbornac8dea12011-04-20 18:18:51 -0700127 } catch (RemoteException e) {
128 Slog.w("Display", "Unable to get display size", e);
129 }
130 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131
132 /**
Jeff Brownbc68a592011-07-25 12:58:12 -0700133 * Gets the size of the display as a rectangle, in pixels.
134 *
135 * @param outSize A {@link Rect} object to receive the size information.
136 * @see #getSize(Point)
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137 */
Dianne Hackbornac8dea12011-04-20 18:18:51 -0700138 public void getRectSize(Rect outSize) {
139 synchronized (mTmpPoint) {
Dianne Hackborn81e56d52011-05-26 00:55:58 -0700140 getSizeInternal(mTmpPoint, true);
Dianne Hackbornac8dea12011-04-20 18:18:51 -0700141 outSize.set(0, 0, mTmpPoint.x, mTmpPoint.y);
142 }
143 }
144
145 /**
146 * Return the maximum screen size dimension that will happen. This is
147 * mostly for wallpapers.
148 * @hide
149 */
150 public int getMaximumSizeDimension() {
151 try {
152 IWindowManager wm = getWindowManager();
153 return wm.getMaximumSizeDimension();
154 } catch (RemoteException e) {
155 Slog.w("Display", "Unable to get display maximum size dimension", e);
156 return 0;
157 }
158 }
159
160 /**
161 * @deprecated Use {@link #getSize(Point)} instead.
162 */
163 @Deprecated
164 public int getWidth() {
165 synchronized (mTmpPoint) {
166 long now = SystemClock.uptimeMillis();
167 if (now > (mLastGetTime+20)) {
Dianne Hackborn81e56d52011-05-26 00:55:58 -0700168 getSizeInternal(mTmpPoint, true);
Dianne Hackbornac8dea12011-04-20 18:18:51 -0700169 mLastGetTime = now;
170 }
171 return mTmpPoint.x;
172 }
173 }
174
175 /**
176 * @deprecated Use {@link #getSize(Point)} instead.
177 */
178 @Deprecated
179 public int getHeight() {
180 synchronized (mTmpPoint) {
181 long now = SystemClock.uptimeMillis();
182 if (now > (mLastGetTime+20)) {
Dianne Hackborn81e56d52011-05-26 00:55:58 -0700183 getSizeInternal(mTmpPoint, true);
Dianne Hackbornac8dea12011-04-20 18:18:51 -0700184 mLastGetTime = now;
185 }
186 return mTmpPoint.y;
187 }
188 }
189
Jeff Brownbc68a592011-07-25 12:58:12 -0700190 /**
191 * Gets the real size of the display without subtracting any window decor or
192 * applying any compatibility scale factors.
193 * <p>
194 * The real size may be smaller than the raw size when the window manager
195 * is emulating a smaller display (using adb shell am display-size).
196 * </p><p>
197 * The size is adjusted based on the current rotation of the display.
198 * </p>
199 * @hide
200 */
201 public void getRealSize(Point outSize) {
202 try {
203 IWindowManager wm = getWindowManager();
204 if (wm != null) {
205 wm.getRealDisplaySize(outSize);
206 } else {
207 // This is just for boot-strapping, initializing the
208 // system process before the window manager is up.
209 outSize.x = getRawWidth();
210 outSize.y = getRawHeight();
211 }
Dianne Hackbornec537452011-09-14 19:19:55 -0700212 if (DEBUG_DISPLAY_SIZE) Slog.v(
213 TAG, "Returning real display size: " + outSize);
Jeff Brownbc68a592011-07-25 12:58:12 -0700214 } catch (RemoteException e) {
215 Slog.w("Display", "Unable to get real display size", e);
216 }
217 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800218
Jeff Brownbc68a592011-07-25 12:58:12 -0700219 /**
220 * Gets the raw width of the display, in pixels.
221 * <p>
222 * The size is adjusted based on the current rotation of the display.
223 * </p>
224 * @hide
225 */
Dianne Hackbornec537452011-09-14 19:19:55 -0700226 public int getRawWidth() {
227 int w = getRawWidthNative();
228 if (DEBUG_DISPLAY_SIZE) Slog.v(
229 TAG, "Returning raw display width: " + w);
230 return w;
231 }
232 private native int getRawWidthNative();
Jeff Brownbc68a592011-07-25 12:58:12 -0700233
234 /**
235 * Gets the raw height of the display, in pixels.
236 * <p>
237 * The size is adjusted based on the current rotation of the display.
238 * </p>
239 * @hide
240 */
Dianne Hackbornec537452011-09-14 19:19:55 -0700241 public int getRawHeight() {
242 int h = getRawHeightNative();
243 if (DEBUG_DISPLAY_SIZE) Slog.v(
244 TAG, "Returning raw display height: " + h);
245 return h;
246 }
247 private native int getRawHeightNative();
Dianne Hackborn99aac7b2011-02-25 17:33:02 -0800248
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800249 /**
Dianne Hackborn5cb70b52010-02-25 17:01:14 -0800250 * Returns the rotation of the screen from its "natural" orientation.
251 * The returned value may be {@link Surface#ROTATION_0 Surface.ROTATION_0}
252 * (no rotation), {@link Surface#ROTATION_90 Surface.ROTATION_90},
253 * {@link Surface#ROTATION_180 Surface.ROTATION_180}, or
254 * {@link Surface#ROTATION_270 Surface.ROTATION_270}. For
255 * example, if a device has a naturally tall screen, and the user has
256 * turned it on its side to go into a landscape orientation, the value
257 * returned here may be either {@link Surface#ROTATION_90 Surface.ROTATION_90}
258 * or {@link Surface#ROTATION_270 Surface.ROTATION_270} depending on
259 * the direction it was turned. The angle is the rotation of the drawn
260 * graphics on the screen, which is the opposite direction of the physical
261 * rotation of the device. For example, if the device is rotated 90
262 * degrees counter-clockwise, to compensate rendering will be rotated by
263 * 90 degrees clockwise and thus the returned value here will be
264 * {@link Surface#ROTATION_90 Surface.ROTATION_90}.
265 */
266 public int getRotation() {
267 return getOrientation();
268 }
269
270 /**
Joe Onorato4c904a32010-02-26 12:35:55 -0800271 * @deprecated use {@link #getRotation}
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800272 * @return orientation of this display.
273 */
Dianne Hackborn5cb70b52010-02-25 17:01:14 -0800274 @Deprecated native public int getOrientation();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275
276 /**
Dianne Hackborn5cb70b52010-02-25 17:01:14 -0800277 * Return the native pixel format of the display. The returned value
278 * may be one of the constants int {@link android.graphics.PixelFormat}.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 */
280 public int getPixelFormat() {
281 return mPixelFormat;
282 }
283
284 /**
Dianne Hackborn5cb70b52010-02-25 17:01:14 -0800285 * Return the refresh rate of this display in frames per second.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800286 */
287 public float getRefreshRate() {
288 return mRefreshRate;
289 }
290
291 /**
Jeff Brownbc68a592011-07-25 12:58:12 -0700292 * Gets display metrics that describe the size and density of this display.
293 * <p>
294 * The size is adjusted based on the current rotation of the display.
295 * </p><p>
296 * The size returned by this method does not necessarily represent the
297 * actual raw size (native resolution) of the display. The returned size may
298 * be adjusted to exclude certain system decor elements that are always visible.
299 * It may also be scaled to provide compatibility with older applications that
300 * were originally designed for smaller displays.
301 * </p>
302 *
303 * @param outMetrics A {@link DisplayMetrics} object to receive the metrics.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800304 */
305 public void getMetrics(DisplayMetrics outMetrics) {
Dianne Hackborn68066c22011-04-21 17:26:39 -0700306 synchronized (mTmpPoint) {
Dianne Hackborn81e56d52011-05-26 00:55:58 -0700307 getSizeInternal(mTmpPoint, false);
Jeff Brownbc68a592011-07-25 12:58:12 -0700308 getMetricsWithSize(outMetrics, mTmpPoint.x, mTmpPoint.y);
Dianne Hackborn68066c22011-04-21 17:26:39 -0700309 }
Dianne Hackborn5be8de32011-05-24 18:11:57 -0700310
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700311 CompatibilityInfo ci = mCompatibilityInfo.getIfNeeded();
312 if (ci != null) {
313 ci.applyToDisplayMetrics(outMetrics);
Dianne Hackborn5be8de32011-05-24 18:11:57 -0700314 }
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700315
Dianne Hackbornec537452011-09-14 19:19:55 -0700316 if (DEBUG_DISPLAY_SIZE) Slog.v(TAG, "Returning DisplayMetrics: "
317 + outMetrics.widthPixels + "x" + outMetrics.heightPixels
318 + " " + outMetrics.density);
Dianne Hackborn68066c22011-04-21 17:26:39 -0700319 }
320
321 /**
Jeff Brownbc68a592011-07-25 12:58:12 -0700322 * Gets display metrics based on the real size of this display.
Dianne Hackborn68066c22011-04-21 17:26:39 -0700323 * @hide
324 */
325 public void getRealMetrics(DisplayMetrics outMetrics) {
Jeff Brownbc68a592011-07-25 12:58:12 -0700326 synchronized (mTmpPoint) {
327 getRealSize(mTmpPoint);
328 getMetricsWithSize(outMetrics, mTmpPoint.x, mTmpPoint.y);
329 }
Dianne Hackborn68066c22011-04-21 17:26:39 -0700330 }
331
Jeff Brownbc68a592011-07-25 12:58:12 -0700332 /**
333 * If the display is mirrored to an external HDMI display, returns the
334 * width of that display.
335 * @hide
336 */
337 public int getRawExternalWidth() {
338 return 1280;
339 }
340
341 /**
342 * If the display is mirrored to an external HDMI display, returns the
343 * height of that display.
344 * @hide
345 */
346 public int getRawExternalHeight() {
347 return 720;
348 }
349
350 /**
351 * Gets display metrics based on an explicit assumed display size.
352 * @hide
353 */
354 public void getMetricsWithSize(DisplayMetrics outMetrics,
355 int width, int height) {
Dianne Hackborn11ea3342009-07-22 21:48:55 -0700356 outMetrics.densityDpi = (int)((mDensity*DisplayMetrics.DENSITY_DEFAULT)+.5f);
Dianne Hackborne2515ee2011-04-27 18:52:56 -0400357
Jeff Brownbc68a592011-07-25 12:58:12 -0700358 outMetrics.noncompatWidthPixels = outMetrics.widthPixels = width;
359 outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height;
Dianne Hackborn2b31d532011-06-23 11:58:50 -0700360
361 outMetrics.density = outMetrics.noncompatDensity = mDensity;
362 outMetrics.scaledDensity = outMetrics.noncompatScaledDensity = outMetrics.density;
363 outMetrics.xdpi = outMetrics.noncompatXdpi = mDpiX;
364 outMetrics.ydpi = outMetrics.noncompatYdpi = mDpiY;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800365 }
366
Dianne Hackbornac8dea12011-04-20 18:18:51 -0700367 static IWindowManager getWindowManager() {
368 synchronized (sStaticInit) {
369 if (sWindowManager == null) {
370 sWindowManager = IWindowManager.Stub.asInterface(
371 ServiceManager.getService("window"));
372 }
373 return sWindowManager;
374 }
375 }
376
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800377 /*
378 * We use a class initializer to allow the native code to cache some
379 * field offsets.
380 */
381 native private static void nativeClassInit();
382
383 private native void init(int display);
384
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700385 private final CompatibilityInfoHolder mCompatibilityInfo;
Dianne Hackborn5be8de32011-05-24 18:11:57 -0700386 private final int mDisplay;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800387 // Following fields are initialized from native code
388 private int mPixelFormat;
389 private float mRefreshRate;
Xavier Ducrohet7f9f99ea2011-08-11 10:16:17 -0700390 /*package*/ float mDensity;
391 /*package*/ float mDpiX;
392 /*package*/ float mDpiY;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800393
Dianne Hackbornac8dea12011-04-20 18:18:51 -0700394 private final Point mTmpPoint = new Point();
Dianne Hackborn5be8de32011-05-24 18:11:57 -0700395 private final DisplayMetrics mTmpMetrics = new DisplayMetrics();
Dianne Hackbornac8dea12011-04-20 18:18:51 -0700396 private float mLastGetTime;
397
398 private static final Object sStaticInit = new Object();
399 private static boolean sInitialized = false;
400 private static IWindowManager sWindowManager;
Mitsuru Oshimaddd12532009-07-14 10:41:13 -0700401
402 /**
403 * Returns a display object which uses the metric's width/height instead.
404 * @hide
405 */
Dianne Hackborn5fd21692011-06-07 14:09:47 -0700406 public static Display createCompatibleDisplay(int displayId, CompatibilityInfoHolder compat) {
Dianne Hackborn5be8de32011-05-24 18:11:57 -0700407 return new Display(displayId, compat);
Mitsuru Oshimaddd12532009-07-14 10:41:13 -0700408 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409}
410