summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2012-07-23 19:26:30 -0700
committerJeff Brown <jeffbrown@google.com>2012-07-25 18:56:16 -0700
commitfa25bf5382467b1018bd9af7f1cb30a23d7d59f7 (patch)
tree2b65e9c19319112d1873db55a02303a43d68547a
parentbbcb123d4923b0c2f36af7b2ade82f5d7832357d (diff)
downloadframeworks_base-fa25bf5382467b1018bd9af7f1cb30a23d7d59f7.zip
frameworks_base-fa25bf5382467b1018bd9af7f1cb30a23d7d59f7.tar.gz
frameworks_base-fa25bf5382467b1018bd9af7f1cb30a23d7d59f7.tar.bz2
Add display manager skeleton.
The purpose of this change is to remove direct reliance on SurfaceFlinger for describing the size and characteristics of displays. This patch also starts to make a distinction between logical displays and physical display devices. Currently, the window manager owns the concept of a logical display whereas the new display manager owns the concept of a physical display device. Change-Id: I7e0761f83f033be6c06fd1041280c21500bcabc0
-rw-r--r--Android.mk1
-rw-r--r--api/16.txt2
-rw-r--r--api/current.txt14
-rw-r--r--core/java/android/app/ContextImpl.java6
-rw-r--r--core/java/android/content/Context.java9
-rw-r--r--core/java/android/hardware/display/DisplayManager.java76
-rw-r--r--core/java/android/hardware/display/IDisplayManager.aidl24
-rw-r--r--core/java/android/view/Display.java398
-rw-r--r--core/java/android/view/DisplayInfo.aidl19
-rw-r--r--core/java/android/view/DisplayInfo.java226
-rw-r--r--core/java/android/view/IWindowManager.aidl6
-rw-r--r--core/java/android/view/Surface.java17
-rw-r--r--core/jni/Android.mk1
-rw-r--r--core/jni/AndroidRuntime.cpp2
-rw-r--r--core/jni/android_view_Display.cpp151
-rw-r--r--core/jni/android_view_Surface.cpp6
-rw-r--r--services/java/com/android/server/SystemServer.java11
-rw-r--r--services/java/com/android/server/display/DisplayAdapter.java35
-rw-r--r--services/java/com/android/server/display/DisplayDevice.java25
-rw-r--r--services/java/com/android/server/display/DisplayDeviceInfo.java54
-rw-r--r--services/java/com/android/server/display/DisplayManagerService.java155
-rw-r--r--services/java/com/android/server/display/HeadlessDisplayAdapter.java44
-rw-r--r--services/java/com/android/server/display/SurfaceFlingerDisplayAdapter.java41
-rw-r--r--services/java/com/android/server/power/PowerManagerService.java5
-rw-r--r--services/java/com/android/server/wm/DragState.java4
-rwxr-xr-xservices/java/com/android/server/wm/WindowManagerService.java267
-rw-r--r--services/java/com/android/server/wm/WindowState.java2
-rw-r--r--services/java/com/android/server/wm/WindowStateAnimator.java10
-rw-r--r--services/jni/Android.mk1
-rw-r--r--services/jni/com_android_server_display_SurfaceFlingerDisplayAdapter.cpp94
-rw-r--r--services/jni/onload.cpp2
-rw-r--r--tools/layoutlib/bridge/src/android/view/Display_Delegate.java53
-rw-r--r--tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java23
33 files changed, 1129 insertions, 655 deletions
diff --git a/Android.mk b/Android.mk
index 5fb66ab..61e8a77 100644
--- a/Android.mk
+++ b/Android.mk
@@ -114,6 +114,7 @@ LOCAL_SRC_FILES += \
core/java/android/content/pm/IPackageStatsObserver.aidl \
core/java/android/database/IContentObserver.aidl \
core/java/android/hardware/ISerialManager.aidl \
+ core/java/android/hardware/display/IDisplayManager.aidl \
core/java/android/hardware/input/IInputManager.aidl \
core/java/android/hardware/input/IInputDevicesChangedListener.aidl \
core/java/android/hardware/usb/IUsbManager.aidl \
diff --git a/api/16.txt b/api/16.txt
index 85464ce..984b844 100644
--- a/api/16.txt
+++ b/api/16.txt
@@ -22892,7 +22892,7 @@ package android.view {
method protected void onApplyThemeResource(android.content.res.Resources.Theme, int, boolean);
}
- public class Display {
+ public final class Display {
method public void getCurrentSizeRange(android.graphics.Point, android.graphics.Point);
method public int getDisplayId();
method public deprecated int getHeight();
diff --git a/api/current.txt b/api/current.txt
index 2716d5b..c910bd0 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -5355,6 +5355,7 @@ package android.content {
field public static final int CONTEXT_INCLUDE_CODE = 1; // 0x1
field public static final int CONTEXT_RESTRICTED = 4; // 0x4
field public static final java.lang.String DEVICE_POLICY_SERVICE = "device_policy";
+ field public static final java.lang.String DISPLAY_SERVICE = "display";
field public static final java.lang.String DOWNLOAD_SERVICE = "download";
field public static final java.lang.String DROPBOX_SERVICE = "dropbox";
field public static final java.lang.String INPUT_METHOD_SERVICE = "input_method";
@@ -9952,6 +9953,13 @@ package android.hardware {
}
+package android.hardware.display {
+
+ public final class DisplayManager {
+ }
+
+}
+
package android.hardware.input {
public final class InputManager {
@@ -23120,13 +23128,15 @@ package android.view {
method protected void onApplyThemeResource(android.content.res.Resources.Theme, int, boolean);
}
- public class Display {
+ public final class Display {
method public void getCurrentSizeRange(android.graphics.Point, android.graphics.Point);
method public int getDisplayId();
method public deprecated int getHeight();
method public void getMetrics(android.util.DisplayMetrics);
method public deprecated int getOrientation();
- method public int getPixelFormat();
+ method public deprecated int getPixelFormat();
+ method public void getRealMetrics(android.util.DisplayMetrics);
+ method public void getRealSize(android.graphics.Point);
method public void getRectSize(android.graphics.Rect);
method public float getRefreshRate();
method public int getRotation();
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index f3f9b64..74fce62 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -47,6 +47,7 @@ import android.hardware.ISerialManager;
import android.hardware.SensorManager;
import android.hardware.SerialManager;
import android.hardware.SystemSensorManager;
+import android.hardware.display.DisplayManager;
import android.hardware.input.IInputManager;
import android.hardware.input.InputManager;
import android.hardware.usb.IUsbManager;
@@ -343,6 +344,11 @@ class ContextImpl extends Context {
return InputManager.getInstance();
}});
+ registerService(DISPLAY_SERVICE, new StaticServiceFetcher() {
+ public Object createStaticService() {
+ return DisplayManager.getInstance();
+ }});
+
registerService(INPUT_METHOD_SERVICE, new ServiceFetcher() {
public Object createService(ContextImpl ctx) {
return InputMethodManager.getInstance(ctx);
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 490165d..8597993 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -1955,6 +1955,15 @@ public abstract class Context {
/**
* Use with {@link #getSystemService} to retrieve a
+ * {@link android.hardware.display.DisplayManager} for interacting with display devices.
+ *
+ * @see #getSystemService
+ * @see android.hardware.display.DisplayManager
+ */
+ public static final String DISPLAY_SERVICE = "display";
+
+ /**
+ * Use with {@link #getSystemService} to retrieve a
* {@link android.os.SchedulingPolicyService} for managing scheduling policy.
*
* @see #getSystemService
diff --git a/core/java/android/hardware/display/DisplayManager.java b/core/java/android/hardware/display/DisplayManager.java
new file mode 100644
index 0000000..13a2db4
--- /dev/null
+++ b/core/java/android/hardware/display/DisplayManager.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.display;
+
+import android.content.Context;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.util.Log;
+import android.view.DisplayInfo;
+
+/**
+ * Manages the properties, media routing and power state of attached displays.
+ * <p>
+ * Get an instance of this class by calling
+ * {@link android.content.Context#getSystemService(java.lang.String)
+ * Context.getSystemService()} with the argument
+ * {@link android.content.Context#DISPLAY_SERVICE}.
+ * </p>
+ */
+public final class DisplayManager {
+ private static final String TAG = "DisplayManager";
+
+ private static DisplayManager sInstance;
+
+ private final IDisplayManager mDm;
+
+ private DisplayManager(IDisplayManager dm) {
+ mDm = dm;
+ }
+
+ /**
+ * Gets an instance of the display manager.
+ * @return The display manager instance.
+ * @hide
+ */
+ public static DisplayManager getInstance() {
+ synchronized (DisplayManager.class) {
+ if (sInstance == null) {
+ IBinder b = ServiceManager.getService(Context.DISPLAY_SERVICE);
+ sInstance = new DisplayManager(IDisplayManager.Stub.asInterface(b));
+ }
+ return sInstance;
+ }
+ }
+
+ /**
+ * Get information about a particular logical display.
+ *
+ * @param displayId The logical display id.
+ * @param outInfo A structure to populate with the display info.
+ * @return True if the logical display exists, false otherwise.
+ */
+ public boolean getDisplayInfo(int displayId, DisplayInfo outInfo) {
+ try {
+ return mDm.getDisplayInfo(displayId, outInfo);
+ } catch (RemoteException ex) {
+ Log.e(TAG, "Could not get display information from display manager.", ex);
+ return false;
+ }
+ }
+}
diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl
new file mode 100644
index 0000000..fd8c35f
--- /dev/null
+++ b/core/java/android/hardware/display/IDisplayManager.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.display;
+
+import android.view.DisplayInfo;
+
+/** @hide */
+interface IDisplayManager {
+ boolean getDisplayInfo(int displayId, out DisplayInfo outInfo);
+}
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 6136d8f..46e4d6e 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -17,20 +17,56 @@
package android.view;
import android.content.res.CompatibilityInfo;
+import android.graphics.PixelFormat;
import android.graphics.Point;
import android.graphics.Rect;
+import android.hardware.display.DisplayManager;
import android.os.RemoteException;
-import android.os.ServiceManager;
import android.os.SystemClock;
import android.util.DisplayMetrics;
-import android.util.Slog;
+import android.util.Log;
/**
- * Provides information about the display size and density.
+ * Provides information about the size and density of a logical display.
+ * <p>
+ * The display area is described in two different ways.
+ * <ul>
+ * <li>The application display area specifies the part of the display that may contain
+ * an application window, excluding the system decorations. The application display area may
+ * be smaller than the real display area because the system subtracts the space needed
+ * for decor elements such as the status bar. Use the following methods to query the
+ * application display area: {@link #getSize}, {@link #getRectSize} and {@link #getMetrics}.</li>
+ * <li>The real display area specifies the part of the display that contains content
+ * including the system decorations. Even so, the real display area may be smaller than the
+ * physical size of the display if the window manager is emulating a smaller display
+ * using (adb shell am display-size). Use the following methods to query the
+ * real display area: {@link #getRealSize}, {@link #getRealMetrics}.</li>
+ * </ul>
+ * </p><p>
+ * A logical display does not necessarily represent a particular physical display device
+ * such as the built-in screen or an external monitor. The contents of a logical
+ * display may be presented on one or more physical displays according to the devices
+ * that are currently attached and whether mirroring has been enabled.
+ * </p>
*/
-public class Display {
- static final String TAG = "Display";
- static final boolean DEBUG_DISPLAY_SIZE = false;
+public final class Display {
+ private static final String TAG = "Display";
+
+ private final int mDisplayId;
+ private final CompatibilityInfoHolder mCompatibilityInfo;
+ private final DisplayInfo mDisplayInfo = new DisplayInfo();
+
+ // Temporary display metrics structure used for compatibility mode.
+ private final DisplayMetrics mTempMetrics = new DisplayMetrics();
+
+ // We cache the app width and height properties briefly between calls
+ // to getHeight() and getWidth() to ensure that applications perceive
+ // consistent results when the size changes (most of the time).
+ // Applications should now be using getSize() instead.
+ private static final int CACHED_APP_SIZE_DURATION_MILLIS = 20;
+ private long mLastCachedAppSizeUpdate;
+ private int mCachedAppWidthCompat;
+ private int mCachedAppHeightCompat;
/**
* The default Display id.
@@ -38,40 +74,29 @@ public class Display {
public static final int DEFAULT_DISPLAY = 0;
/**
- * Use {@link android.view.WindowManager#getDefaultDisplay()
- * WindowManager.getDefaultDisplay()} to create a Display object.
- * Display gives you access to some information about a particular display
- * connected to the device.
+ * Internal method to create a display.
+ * Applications should use {@link android.view.WindowManager#getDefaultDisplay()}
+ * to get a display object for the default display.
+ *
+ * @hide
*/
- Display(int display, CompatibilityInfoHolder compatInfo) {
- // initalize the statics when this class is first instansiated. This is
- // done here instead of in the static block because Zygote
- synchronized (sStaticInit) {
- if (!sInitialized) {
- nativeClassInit();
- sInitialized = true;
- }
- }
- mCompatibilityInfo = compatInfo != null ? compatInfo : new CompatibilityInfoHolder();
- mDisplay = display;
- init(display);
+ public Display(int displayId, CompatibilityInfoHolder compatibilityInfo) {
+ mDisplayId = displayId;
+ mCompatibilityInfo = compatibilityInfo;
}
/**
- * Returns the index of this display. This is currently undefined; do
- * not use.
+ * Gets the display id.
+ * <p>
+ * Each logical display has a unique id.
+ * The default display has id {@link #DEFAULT_DISPLAY}.
+ * </p>
*/
public int getDisplayId() {
- return mDisplay;
+ return mDisplayId;
}
/**
- * Returns the number of displays connected to the device. This is
- * currently undefined; do not use.
- */
- native static int getDisplayCount();
-
- /**
* Gets the size of the display, in pixels.
* <p>
* Note that this value should <em>not</em> be used for computing layouts,
@@ -84,7 +109,7 @@ public class Display {
* </p><p>
* The size returned by this method does not necessarily represent the
* actual raw size (native resolution) of the display. The returned size may
- * be adjusted to exclude certain system decor elements that are always visible.
+ * be adjusted to exclude certain system decoration elements that are always visible.
* It may also be scaled to provide compatibility with older applications that
* were originally designed for smaller displays.
* </p>
@@ -92,43 +117,14 @@ public class Display {
* @param outSize A {@link Point} object to receive the size information.
*/
public void getSize(Point outSize) {
- getSizeInternal(outSize, true);
- }
-
- private void getSizeInternal(Point outSize, boolean doCompat) {
- try {
- IWindowManager wm = getWindowManager();
- if (wm != null) {
- wm.getDisplaySize(outSize);
- CompatibilityInfo ci;
- if (doCompat && (ci=mCompatibilityInfo.getIfNeeded()) != null) {
- synchronized (mTmpMetrics) {
- mTmpMetrics.noncompatWidthPixels = outSize.x;
- mTmpMetrics.noncompatHeightPixels = outSize.y;
- mTmpMetrics.density = mDensity;
- ci.applyToDisplayMetrics(mTmpMetrics);
- outSize.x = mTmpMetrics.widthPixels;
- outSize.y = mTmpMetrics.heightPixels;
- }
- }
- } else {
- // This is just for boot-strapping, initializing the
- // system process before the window manager is up.
- outSize.x = getRawWidth();
- outSize.y = getRawHeight();
- }
- if (false) {
- RuntimeException here = new RuntimeException("here");
- here.fillInStackTrace();
- Slog.v(TAG, "Returning display size: " + outSize, here);
- }
- if (DEBUG_DISPLAY_SIZE && doCompat) Slog.v(
- TAG, "Returning display size: " + outSize);
- } catch (RemoteException e) {
- Slog.w("Display", "Unable to get display size", e);
+ synchronized (this) {
+ updateDisplayInfoLocked();
+ mDisplayInfo.getAppMetrics(mTempMetrics, mCompatibilityInfo);
+ outSize.x = mTempMetrics.widthPixels;
+ outSize.y = mTempMetrics.heightPixels;
}
}
-
+
/**
* Gets the size of the display as a rectangle, in pixels.
*
@@ -136,9 +132,10 @@ public class Display {
* @see #getSize(Point)
*/
public void getRectSize(Rect outSize) {
- synchronized (mTmpPoint) {
- getSizeInternal(mTmpPoint, true);
- outSize.set(0, 0, mTmpPoint.x, mTmpPoint.y);
+ synchronized (this) {
+ updateDisplayInfoLocked();
+ mDisplayInfo.getAppMetrics(mTempMetrics, mCompatibilityInfo);
+ outSize.set(0, 0, mTempMetrics.widthPixels, mTempMetrics.heightPixels);
}
}
@@ -173,15 +170,12 @@ public class Display {
* for example, screen decorations like the status bar are being hidden.
*/
public void getCurrentSizeRange(Point outSmallestSize, Point outLargestSize) {
- try {
- IWindowManager wm = getWindowManager();
- wm.getCurrentSizeRange(outSmallestSize, outLargestSize);
- } catch (RemoteException e) {
- Slog.w("Display", "Unable to get display size range", e);
- outSmallestSize.x = 0;
- outSmallestSize.y = 0;
- outLargestSize.x = 0;
- outLargestSize.y = 0;
+ synchronized (this) {
+ updateDisplayInfoLocked();
+ outSmallestSize.x = mDisplayInfo.smallestNominalAppWidth;
+ outSmallestSize.y = mDisplayInfo.smallestNominalAppHeight;
+ outLargestSize.x = mDisplayInfo.largestNominalAppWidth;
+ outLargestSize.y = mDisplayInfo.largestNominalAppHeight;
}
}
@@ -191,12 +185,9 @@ public class Display {
* @hide
*/
public int getMaximumSizeDimension() {
- try {
- IWindowManager wm = getWindowManager();
- return wm.getMaximumSizeDimension();
- } catch (RemoteException e) {
- Slog.w("Display", "Unable to get display maximum size dimension", e);
- return 0;
+ synchronized (this) {
+ updateDisplayInfoLocked();
+ return Math.max(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
}
}
@@ -205,13 +196,9 @@ public class Display {
*/
@Deprecated
public int getWidth() {
- synchronized (mTmpPoint) {
- long now = SystemClock.uptimeMillis();
- if (now > (mLastGetTime+20)) {
- getSizeInternal(mTmpPoint, true);
- mLastGetTime = now;
- }
- return mTmpPoint.x;
+ synchronized (this) {
+ updateCachedAppSizeIfNeededLocked();
+ return mCachedAppWidthCompat;
}
}
@@ -220,76 +207,13 @@ public class Display {
*/
@Deprecated
public int getHeight() {
- synchronized (mTmpPoint) {
- long now = SystemClock.uptimeMillis();
- if (now > (mLastGetTime+20)) {
- getSizeInternal(mTmpPoint, true);
- mLastGetTime = now;
- }
- return mTmpPoint.y;
- }
- }
-
- /**
- * Gets the real size of the display without subtracting any window decor or
- * applying any compatibility scale factors.
- * <p>
- * The real size may be smaller than the raw size when the window manager
- * is emulating a smaller display (using adb shell am display-size).
- * </p><p>
- * The size is adjusted based on the current rotation of the display.
- * </p>
- * @hide
- */
- public void getRealSize(Point outSize) {
- try {
- IWindowManager wm = getWindowManager();
- if (wm != null) {
- wm.getRealDisplaySize(outSize);
- } else {
- // This is just for boot-strapping, initializing the
- // system process before the window manager is up.
- outSize.x = getRawWidth();
- outSize.y = getRawHeight();
- }
- if (DEBUG_DISPLAY_SIZE) Slog.v(
- TAG, "Returning real display size: " + outSize);
- } catch (RemoteException e) {
- Slog.w("Display", "Unable to get real display size", e);
+ synchronized (this) {
+ updateCachedAppSizeIfNeededLocked();
+ return mCachedAppHeightCompat;
}
}
/**
- * Gets the raw width of the display, in pixels.
- * <p>
- * The size is adjusted based on the current rotation of the display.
- * </p>
- * @hide
- */
- public int getRawWidth() {
- int w = getRawWidthNative();
- if (DEBUG_DISPLAY_SIZE) Slog.v(
- TAG, "Returning raw display width: " + w);
- return w;
- }
- private native int getRawWidthNative();
-
- /**
- * Gets the raw height of the display, in pixels.
- * <p>
- * The size is adjusted based on the current rotation of the display.
- * </p>
- * @hide
- */
- public int getRawHeight() {
- int h = getRawHeightNative();
- if (DEBUG_DISPLAY_SIZE) Slog.v(
- TAG, "Returning raw display height: " + h);
- return h;
- }
- private native int getRawHeightNative();
-
- /**
* Returns the rotation of the screen from its "natural" orientation.
* The returned value may be {@link Surface#ROTATION_0 Surface.ROTATION_0}
* (no rotation), {@link Surface#ROTATION_90 Surface.ROTATION_90},
@@ -307,30 +231,43 @@ public class Display {
* {@link Surface#ROTATION_90 Surface.ROTATION_90}.
*/
public int getRotation() {
- return getOrientation();
+ synchronized (this) {
+ updateDisplayInfoLocked();
+ return mDisplayInfo.rotation;
+ }
}
-
+
/**
* @deprecated use {@link #getRotation}
* @return orientation of this display.
*/
- @Deprecated native public int getOrientation();
+ @Deprecated
+ public int getOrientation() {
+ return getRotation();
+ }
/**
- * Return the native pixel format of the display. The returned value
- * may be one of the constants int {@link android.graphics.PixelFormat}.
+ * Gets the pixel format of the display.
+ * @return One of the constants defined in {@link android.graphics.PixelFormat}.
+ *
+ * @deprecated This method is no longer supported.
+ * The result is always {@link PixelFormat#RGBA_8888}.
*/
+ @Deprecated
public int getPixelFormat() {
- return mPixelFormat;
+ return PixelFormat.RGBA_8888;
}
-
+
/**
- * Return the refresh rate of this display in frames per second.
+ * Gets the refresh rate of this display in frames per second.
*/
public float getRefreshRate() {
- return mRefreshRate;
+ synchronized (this) {
+ updateDisplayInfoLocked();
+ return mDisplayInfo.refreshRate;
+ }
}
-
+
/**
* Gets display metrics that describe the size and density of this display.
* <p>
@@ -346,102 +283,71 @@ public class Display {
* @param outMetrics A {@link DisplayMetrics} object to receive the metrics.
*/
public void getMetrics(DisplayMetrics outMetrics) {
- synchronized (mTmpPoint) {
- getSizeInternal(mTmpPoint, false);
- getMetricsWithSize(outMetrics, mTmpPoint.x, mTmpPoint.y);
+ synchronized (this) {
+ updateDisplayInfoLocked();
+ mDisplayInfo.getAppMetrics(outMetrics, mCompatibilityInfo);
}
- CompatibilityInfo ci = mCompatibilityInfo.getIfNeeded();
+ final CompatibilityInfo ci = mCompatibilityInfo.getIfNeeded();
if (ci != null) {
ci.applyToDisplayMetrics(outMetrics);
}
-
- if (DEBUG_DISPLAY_SIZE) Slog.v(TAG, "Returning DisplayMetrics: "
- + outMetrics.widthPixels + "x" + outMetrics.heightPixels
- + " " + outMetrics.density);
}
/**
- * Gets display metrics based on the real size of this display.
- * @hide
+ * Gets the real size of the display without subtracting any window decor or
+ * applying any compatibility scale factors.
+ * <p>
+ * The size is adjusted based on the current rotation of the display.
+ * </p><p>
+ * The real size may be smaller than the physical size of the screen when the
+ * window manager is emulating a smaller display (using adb shell am display-size).
+ * </p>
+ *
+ * @param outSize Set to the real size of the display.
*/
- public void getRealMetrics(DisplayMetrics outMetrics) {
- synchronized (mTmpPoint) {
- getRealSize(mTmpPoint);
- getMetricsWithSize(outMetrics, mTmpPoint.x, mTmpPoint.y);
+ public void getRealSize(Point outSize) {
+ synchronized (this) {
+ updateDisplayInfoLocked();
+ outSize.x = mDisplayInfo.logicalWidth;
+ outSize.y = mDisplayInfo.logicalHeight;
}
}
/**
- * If the display is mirrored to an external HDMI display, returns the
- * width of that display.
- * @hide
- */
- public int getRawExternalWidth() {
- return 1280;
- }
-
- /**
- * If the display is mirrored to an external HDMI display, returns the
- * height of that display.
- * @hide
- */
- public int getRawExternalHeight() {
- return 720;
- }
-
- /**
- * If the display is mirrored to an external HDMI display, returns the
- * rotation of that display relative to its natural orientation.
- * @hide
+ * Gets display metrics based on the real size of this display.
+ * <p>
+ * The size is adjusted based on the current rotation of the display.
+ * </p><p>
+ * The real size may be smaller than the physical size of the screen when the
+ * window manager is emulating a smaller display (using adb shell am display-size).
+ * </p>
+ *
+ * @param outMetrics A {@link DisplayMetrics} object to receive the metrics.
*/
- public int getExternalRotation() {
- return Surface.ROTATION_0;
+ public void getRealMetrics(DisplayMetrics outMetrics) {
+ synchronized (this) {
+ updateDisplayInfoLocked();
+ mDisplayInfo.getLogicalMetrics(outMetrics, null);
+ }
}
- /**
- * Gets display metrics based on an explicit assumed display size.
- * @hide
- */
- public void getMetricsWithSize(DisplayMetrics outMetrics,
- int width, int height) {
- outMetrics.densityDpi = (int)((mDensity*DisplayMetrics.DENSITY_DEFAULT)+.5f);
-
- outMetrics.noncompatWidthPixels = outMetrics.widthPixels = width;
- outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height;
-
- outMetrics.density = outMetrics.noncompatDensity = mDensity;
- outMetrics.scaledDensity = outMetrics.noncompatScaledDensity = outMetrics.density;
- outMetrics.xdpi = outMetrics.noncompatXdpi = mDpiX;
- outMetrics.ydpi = outMetrics.noncompatYdpi = mDpiY;
+ private void updateDisplayInfoLocked() {
+ // TODO: only refresh the display information when needed
+ if (!DisplayManager.getInstance().getDisplayInfo(mDisplayId, mDisplayInfo)) {
+ Log.e(TAG, "Could not get information about logical display " + mDisplayId);
+ }
}
- private static IWindowManager getWindowManager() {
- return WindowManagerImpl.getWindowManagerService();
+ private void updateCachedAppSizeIfNeededLocked() {
+ long now = SystemClock.uptimeMillis();
+ if (now > mLastCachedAppSizeUpdate + CACHED_APP_SIZE_DURATION_MILLIS) {
+ updateDisplayInfoLocked();
+ mDisplayInfo.getAppMetrics(mTempMetrics, mCompatibilityInfo);
+ mCachedAppWidthCompat = mTempMetrics.widthPixels;
+ mCachedAppHeightCompat = mTempMetrics.heightPixels;
+ mLastCachedAppSizeUpdate = now;
+ }
}
-
- /*
- * We use a class initializer to allow the native code to cache some
- * field offsets.
- */
- native private static void nativeClassInit();
-
- private native void init(int display);
-
- private final CompatibilityInfoHolder mCompatibilityInfo;
- private final int mDisplay;
- // Following fields are initialized from native code
- private int mPixelFormat;
- private float mRefreshRate;
- /*package*/ float mDensity;
- /*package*/ float mDpiX;
- /*package*/ float mDpiY;
-
- private final Point mTmpPoint = new Point();
- private final DisplayMetrics mTmpMetrics = new DisplayMetrics();
- private float mLastGetTime;
-
- private static final Object sStaticInit = new Object();
- private static boolean sInitialized = false;
}
diff --git a/core/java/android/view/DisplayInfo.aidl b/core/java/android/view/DisplayInfo.aidl
new file mode 100644
index 0000000..e679208
--- /dev/null
+++ b/core/java/android/view/DisplayInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+parcelable DisplayInfo;
diff --git a/core/java/android/view/DisplayInfo.java b/core/java/android/view/DisplayInfo.java
new file mode 100644
index 0000000..69b6d67
--- /dev/null
+++ b/core/java/android/view/DisplayInfo.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view;
+
+import android.content.res.CompatibilityInfo;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.DisplayMetrics;
+
+/**
+ * Describes the characteristics of a particular logical display.
+ * @hide
+ */
+public final class DisplayInfo implements Parcelable {
+ /**
+ * The width of the portion of the display that is available to applications, in pixels.
+ * Represents the size of the display minus any system decorations.
+ */
+ public int appWidth;
+
+ /**
+ * The height of the portion of the display that is available to applications, in pixels.
+ * Represents the size of the display minus any system decorations.
+ */
+ public int appHeight;
+
+ /**
+ * The smallest value of {@link #appWidth} that an application is likely to encounter,
+ * in pixels, excepting cases where the width may be even smaller due to the presence
+ * of a soft keyboard, for example.
+ */
+ public int smallestNominalAppWidth;
+
+ /**
+ * The smallest value of {@link #appHeight} that an application is likely to encounter,
+ * in pixels, excepting cases where the height may be even smaller due to the presence
+ * of a soft keyboard, for example.
+ */
+ public int smallestNominalAppHeight;
+
+ /**
+ * The largest value of {@link #appWidth} that an application is likely to encounter,
+ * in pixels, excepting cases where the width may be even larger due to system decorations
+ * such as the status bar being hidden, for example.
+ */
+ public int largestNominalAppWidth;
+
+ /**
+ * The largest value of {@link #appHeight} that an application is likely to encounter,
+ * in pixels, excepting cases where the height may be even larger due to system decorations
+ * such as the status bar being hidden, for example.
+ */
+ public int largestNominalAppHeight;
+
+ /**
+ * The logical width of the display, in pixels.
+ * Represents the usable size of the display which may be smaller than the
+ * physical size when the system is emulating a smaller display.
+ */
+ public int logicalWidth;
+
+ /**
+ * The logical height of the display, in pixels.
+ * Represents the usable size of the display which may be smaller than the
+ * physical size when the system is emulating a smaller display.
+ */
+ public int logicalHeight;
+
+ /**
+ * The rotation of the display relative to its natural orientation.
+ * May be one of {@link android.view.Surface#ROTATION_0},
+ * {@link android.view.Surface#ROTATION_90}, {@link android.view.Surface#ROTATION_180},
+ * {@link android.view.Surface#ROTATION_270}.
+ * <p>
+ * The value of this field is indeterminate if the logical display is presented on
+ * more than one physical display.
+ * </p>
+ */
+ public int rotation;
+
+ /**
+ * The refresh rate of this display in frames per second.
+ * <p>
+ * The value of this field is indeterminate if the logical display is presented on
+ * more than one physical display.
+ * </p>
+ */
+ public float refreshRate;
+
+ /**
+ * The logical display density which represents the scaling factor for
+ * the Density Independent Pixel unit.
+ */
+ public float logicalDensity;
+
+ /**
+ * The exact physical pixels per inch of the screen in the X dimension.
+ * <p>
+ * The value of this field is indeterminate if the logical display is presented on
+ * more than one physical display.
+ * </p>
+ */
+ public float physicalXDpi;
+
+ /**
+ * The exact physical pixels per inch of the screen in the Y dimension.
+ * <p>
+ * The value of this field is indeterminate if the logical display is presented on
+ * more than one physical display.
+ * </p>
+ */
+ public float physicalYDpi;
+
+ public static final Creator<DisplayInfo> CREATOR = new Creator<DisplayInfo>() {
+ public DisplayInfo createFromParcel(Parcel source) {
+ return new DisplayInfo(source);
+ }
+
+ public DisplayInfo[] newArray(int size) {
+ return new DisplayInfo[size];
+ }
+ };
+
+ public DisplayInfo() {
+ }
+
+ private DisplayInfo(Parcel source) {
+ readFromParcel(source);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ public void copyFrom(DisplayInfo other) {
+ appWidth = other.appWidth;
+ appHeight = other.appHeight;
+ smallestNominalAppWidth = other.smallestNominalAppWidth;
+ smallestNominalAppHeight = other.smallestNominalAppHeight;
+ largestNominalAppWidth = other.largestNominalAppWidth;
+ largestNominalAppHeight = other.largestNominalAppHeight;
+ logicalWidth = other.logicalWidth;
+ logicalHeight = other.logicalHeight;
+ rotation = other.rotation;
+ refreshRate = other.refreshRate;
+ logicalDensity = other.logicalDensity;
+ physicalXDpi = other.physicalXDpi;
+ physicalYDpi = other.physicalYDpi;
+ }
+
+ public void readFromParcel(Parcel source) {
+ appWidth = source.readInt();
+ appHeight = source.readInt();
+ smallestNominalAppWidth = source.readInt();
+ smallestNominalAppHeight = source.readInt();
+ largestNominalAppWidth = source.readInt();
+ largestNominalAppHeight = source.readInt();
+ logicalWidth = source.readInt();
+ logicalHeight = source.readInt();
+ rotation = source.readInt();
+ refreshRate = source.readFloat();
+ logicalDensity = source.readFloat();
+ physicalXDpi = source.readFloat();
+ physicalYDpi = source.readFloat();
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(appWidth);
+ dest.writeInt(appHeight);
+ dest.writeInt(smallestNominalAppWidth);
+ dest.writeInt(smallestNominalAppHeight);
+ dest.writeInt(largestNominalAppWidth);
+ dest.writeInt(largestNominalAppHeight);
+ dest.writeInt(logicalWidth);
+ dest.writeInt(logicalHeight);
+ dest.writeInt(rotation);
+ dest.writeFloat(refreshRate);
+ dest.writeFloat(logicalDensity);
+ dest.writeFloat(physicalXDpi);
+ dest.writeFloat(physicalYDpi);
+ }
+
+ public void getAppMetrics(DisplayMetrics outMetrics, CompatibilityInfoHolder cih) {
+ getMetricsWithSize(outMetrics, cih, appWidth, appHeight);
+ }
+
+ public void getLogicalMetrics(DisplayMetrics outMetrics, CompatibilityInfoHolder cih) {
+ getMetricsWithSize(outMetrics, cih, logicalWidth, logicalHeight);
+ }
+
+ private void getMetricsWithSize(DisplayMetrics outMetrics, CompatibilityInfoHolder cih,
+ int width, int height) {
+ outMetrics.densityDpi =
+ (int)((logicalDensity * DisplayMetrics.DENSITY_DEFAULT) + .5f);
+ outMetrics.noncompatWidthPixels = outMetrics.widthPixels = width;
+ outMetrics.noncompatHeightPixels = outMetrics.heightPixels = height;
+
+ outMetrics.density = outMetrics.noncompatDensity = logicalDensity;
+ outMetrics.scaledDensity = outMetrics.noncompatScaledDensity = outMetrics.density;
+ outMetrics.xdpi = outMetrics.noncompatXdpi = physicalXDpi;
+ outMetrics.ydpi = outMetrics.noncompatYdpi = physicalYDpi;
+
+ if (cih != null) {
+ CompatibilityInfo ci = cih.getIfNeeded();
+ if (ci != null) {
+ ci.applyToDisplayMetrics(outMetrics);
+ }
+ }
+ }
+}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 5941e44..a65d6f5 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -25,6 +25,7 @@ import android.graphics.Bitmap;
import android.graphics.Point;
import android.graphics.Rect;
import android.os.IRemoteCallback;
+import android.view.DisplayInfo;
import android.view.IApplicationToken;
import android.view.IOnKeyguardExitResult;
import android.view.IRotationWatcher;
@@ -56,11 +57,6 @@ interface IWindowManager
IWindowSession openSession(in IInputMethodClient client,
in IInputContext inputContext);
boolean inputMethodClientHasFocus(IInputMethodClient client);
-
- void getDisplaySize(out Point size);
- void getRealDisplaySize(out Point size);
- int getMaximumSizeDimension();
- void getCurrentSizeRange(out Point smallestSize, out Point largestSize);
void setForcedDisplaySize(int longDimen, int shortDimen);
void clearForcedDisplaySize();
diff --git a/core/java/android/view/Surface.java b/core/java/android/view/Surface.java
index 1105038..02ecb65 100644
--- a/core/java/android/view/Surface.java
+++ b/core/java/android/view/Surface.java
@@ -403,31 +403,16 @@ public class Surface implements Parcelable {
public native void destroy();
private native Canvas lockCanvasNative(Rect dirty);
-
- /*
- * set display parameters & screenshots
- */
/**
* set the orientation of the given display.
* @param display
* @param orientation
- * @param flags Currently unused, set to 0.
* @hide
*/
- public static native void setOrientation(int display, int orientation, int flags);
+ public static native void setOrientation(int display, int orientation);
/**
- * set the orientation of the given display.
- * @param display
- * @param orientation
- * @hide
- */
- public static void setOrientation(int display, int orientation) {
- setOrientation(display, orientation, 0);
- }
-
- /**
* Like {@link #screenshot(int, int, int, int)} but includes all
* Surfaces in the screenshot.
*
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index e429ffc..b1423ca 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -44,7 +44,6 @@ LOCAL_SRC_FILES:= \
android_database_SQLiteGlobal.cpp \
android_database_SQLiteDebug.cpp \
android_emoji_EmojiFactory.cpp \
- android_view_Display.cpp \
android_view_DisplayEventReceiver.cpp \
android_view_Surface.cpp \
android_view_TextureView.cpp \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index f0dd321..c936b0b 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -116,7 +116,6 @@ extern int register_android_graphics_Region(JNIEnv* env);
extern int register_android_graphics_SurfaceTexture(JNIEnv* env);
extern int register_android_graphics_Xfermode(JNIEnv* env);
extern int register_android_graphics_PixelFormat(JNIEnv* env);
-extern int register_android_view_Display(JNIEnv* env);
extern int register_android_view_DisplayEventReceiver(JNIEnv* env);
extern int register_android_view_GLES20DisplayList(JNIEnv* env);
extern int register_android_view_GLES20Canvas(JNIEnv* env);
@@ -1088,7 +1087,6 @@ static const RegJNIRec gRegJNI[] = {
REG_JNI(register_android_os_SystemProperties),
REG_JNI(register_android_os_Binder),
REG_JNI(register_android_os_Parcel),
- REG_JNI(register_android_view_Display),
REG_JNI(register_android_view_DisplayEventReceiver),
REG_JNI(register_android_nio_utils),
REG_JNI(register_android_graphics_PixelFormat),
diff --git a/core/jni/android_view_Display.cpp b/core/jni/android_view_Display.cpp
deleted file mode 100644
index aedf1e4..0000000
--- a/core/jni/android_view_Display.cpp
+++ /dev/null
@@ -1,151 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <stdio.h>
-#include <assert.h>
-
-#include <cutils/properties.h>
-
-#include <gui/SurfaceComposerClient.h>
-#include <ui/PixelFormat.h>
-#include <ui/DisplayInfo.h>
-
-#include "jni.h"
-#include "JNIHelp.h"
-#include <android_runtime/AndroidRuntime.h>
-#include <utils/misc.h>
-#include <utils/Log.h>
-#include <cutils/properties.h>
-
-// ----------------------------------------------------------------------------
-
-namespace android {
-
-// ----------------------------------------------------------------------------
-
-struct offsets_t {
- jfieldID display;
- jfieldID pixelFormat;
- jfieldID fps;
- jfieldID density;
- jfieldID xdpi;
- jfieldID ydpi;
-};
-static offsets_t offsets;
-static bool headless = false;
-
-// ----------------------------------------------------------------------------
-
-static void android_view_Display_init(
- JNIEnv* env, jobject clazz, jint dpy)
-{
- DisplayInfo info;
- if (headless) {
- // initialize dummy display with reasonable values
- info.pixelFormatInfo.format = 1; // RGB_8888
- info.fps = 60;
- info.density = 160;
- info.xdpi = 160;
- info.ydpi = 160;
- } else {
- status_t err = SurfaceComposerClient::getDisplayInfo(DisplayID(dpy), &info);
- if (err < 0) {
- jniThrowException(env, "java/lang/IllegalArgumentException", NULL);
- return;
- }
- }
- env->SetIntField(clazz, offsets.pixelFormat,info.pixelFormatInfo.format);
- env->SetFloatField(clazz, offsets.fps, info.fps);
- env->SetFloatField(clazz, offsets.density, info.density);
- env->SetFloatField(clazz, offsets.xdpi, info.xdpi);
- env->SetFloatField(clazz, offsets.ydpi, info.ydpi);
-}
-
-static jint android_view_Display_getRawWidthNative(
- JNIEnv* env, jobject clazz)
-{
- if (headless) return 640;
- DisplayID dpy = env->GetIntField(clazz, offsets.display);
- return SurfaceComposerClient::getDisplayWidth(dpy);
-}
-
-static jint android_view_Display_getRawHeightNative(
- JNIEnv* env, jobject clazz)
-{
- if (headless) return 480;
- DisplayID dpy = env->GetIntField(clazz, offsets.display);
- return SurfaceComposerClient::getDisplayHeight(dpy);
-}
-
-static jint android_view_Display_getOrientation(
- JNIEnv* env, jobject clazz)
-{
- if (headless) return 0; // Surface.ROTATION_0
- DisplayID dpy = env->GetIntField(clazz, offsets.display);
- return SurfaceComposerClient::getDisplayOrientation(dpy);
-}
-
-static jint android_view_Display_getDisplayCount(
- JNIEnv* env, jclass clazz)
-{
- if (headless) return 1;
- return SurfaceComposerClient::getNumberOfDisplays();
-}
-
-// ----------------------------------------------------------------------------
-
-const char* const kClassPathName = "android/view/Display";
-
-static void nativeClassInit(JNIEnv* env, jclass clazz);
-
-static JNINativeMethod gMethods[] = {
- { "nativeClassInit", "()V",
- (void*)nativeClassInit },
- { "getDisplayCount", "()I",
- (void*)android_view_Display_getDisplayCount },
- { "init", "(I)V",
- (void*)android_view_Display_init },
- { "getRawWidthNative", "()I",
- (void*)android_view_Display_getRawWidthNative },
- { "getRawHeightNative", "()I",
- (void*)android_view_Display_getRawHeightNative },
- { "getOrientation", "()I",
- (void*)android_view_Display_getOrientation }
-};
-
-void nativeClassInit(JNIEnv* env, jclass clazz)
-{
- char value[PROPERTY_VALUE_MAX];
-
- property_get("ro.config.headless", value, "0");
- if (strcmp(value, "1") == 0)
- headless = true;
-
- offsets.display = env->GetFieldID(clazz, "mDisplay", "I");
- offsets.pixelFormat = env->GetFieldID(clazz, "mPixelFormat", "I");
- offsets.fps = env->GetFieldID(clazz, "mRefreshRate", "F");
- offsets.density = env->GetFieldID(clazz, "mDensity", "F");
- offsets.xdpi = env->GetFieldID(clazz, "mDpiX", "F");
- offsets.ydpi = env->GetFieldID(clazz, "mDpiY", "F");
-}
-
-int register_android_view_Display(JNIEnv* env)
-{
- return AndroidRuntime::registerNativeMethods(env,
- kClassPathName, gMethods, NELEM(gMethods));
-}
-
-};
diff --git a/core/jni/android_view_Surface.cpp b/core/jni/android_view_Surface.cpp
index 60f8c48..3cd28b1 100644
--- a/core/jni/android_view_Surface.cpp
+++ b/core/jni/android_view_Surface.cpp
@@ -473,9 +473,9 @@ static void Surface_closeTransaction(
}
static void Surface_setOrientation(
- JNIEnv* env, jobject clazz, jint display, jint orientation, jint flags)
+ JNIEnv* env, jobject clazz, jint display, jint orientation)
{
- int err = SurfaceComposerClient::setOrientation(display, orientation, flags);
+ int err = SurfaceComposerClient::setOrientation(display, orientation, 0);
if (err < 0) {
doThrowIAE(env);
}
@@ -839,7 +839,7 @@ static JNINativeMethod gSurfaceMethods[] = {
{"unlockCanvas", "(Landroid/graphics/Canvas;)V", (void*)Surface_unlockCanvas },
{"openTransaction", "()V", (void*)Surface_openTransaction },
{"closeTransaction", "()V", (void*)Surface_closeTransaction },
- {"setOrientation", "(III)V", (void*)Surface_setOrientation },
+ {"setOrientation", "(II)V", (void*)Surface_setOrientation },
{"screenshot", "(II)Landroid/graphics/Bitmap;", (void*)Surface_screenshotAll },
{"screenshot", "(IIII)Landroid/graphics/Bitmap;", (void*)Surface_screenshot },
{"setLayer", "(I)V", (void*)Surface_setLayer },
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 2185456..d766afd 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -49,6 +49,7 @@ import com.android.internal.os.SamplingProfilerIntegration;
import com.android.internal.widget.LockSettingsService;
import com.android.server.accessibility.AccessibilityManagerService;
import com.android.server.am.ActivityManagerService;
+import com.android.server.display.DisplayManagerService;
import com.android.server.input.InputManagerService;
import com.android.server.net.NetworkPolicyManagerService;
import com.android.server.net.NetworkStatsService;
@@ -115,6 +116,7 @@ class ServerThread extends Thread {
LightsService lights = null;
PowerManagerService power = null;
+ DisplayManagerService display = null;
BatteryService battery = null;
VibratorService vibrator = null;
AlarmManagerService alarm = null;
@@ -148,8 +150,13 @@ class ServerThread extends Thread {
power = new PowerManagerService();
ServiceManager.addService(Context.POWER_SERVICE, power);
+ Slog.i(TAG, "Display Manager");
+ display = new DisplayManagerService();
+ ServiceManager.addService(Context.DISPLAY_SERVICE, display);
+
Slog.i(TAG, "Activity Manager");
context = ActivityManagerService.main(factoryTest);
+ display.setContext(context);
Slog.i(TAG, "Telephony Registry");
ServiceManager.addService("telephony.registry", new TelephonyRegistry(context));
@@ -214,7 +221,7 @@ class ServerThread extends Thread {
// only initialize the power service after we have started the
// lights service, content providers and the battery service.
- power.init(context, lights, ActivityManagerService.self(), battery);
+ power.init(context, lights, ActivityManagerService.self(), battery, display);
Slog.i(TAG, "Alarm Manager");
alarm = new AlarmManagerService(context);
@@ -225,7 +232,7 @@ class ServerThread extends Thread {
ActivityManagerService.self());
Slog.i(TAG, "Window Manager");
- wm = WindowManagerService.main(context, power,
+ wm = WindowManagerService.main(context, power, display,
factoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL,
!firstBoot, onlyCore);
ServiceManager.addService(Context.WINDOW_SERVICE, wm);
diff --git a/services/java/com/android/server/display/DisplayAdapter.java b/services/java/com/android/server/display/DisplayAdapter.java
new file mode 100644
index 0000000..e150bf8
--- /dev/null
+++ b/services/java/com/android/server/display/DisplayAdapter.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display;
+
+/**
+ * A display adapter makes one or more display devices available to the system.
+ * <p>
+ * For now, all display adapters are registered in the system server but
+ * in principle it could be done from other processes.
+ * </p>
+ */
+public abstract class DisplayAdapter {
+ /**
+ * Gets the display adapter name.
+ * @return The display adapter name.
+ */
+ public abstract String getName();
+
+ // TODO: dynamically register display devices
+ public abstract DisplayDevice[] getDisplayDevices();
+}
diff --git a/services/java/com/android/server/display/DisplayDevice.java b/services/java/com/android/server/display/DisplayDevice.java
new file mode 100644
index 0000000..6d723f2
--- /dev/null
+++ b/services/java/com/android/server/display/DisplayDevice.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display;
+
+/**
+ * Represents a physical display device such as the built-in display
+ * or an external monitor.
+ */
+public abstract class DisplayDevice {
+ public abstract void getInfo(DisplayDeviceInfo outInfo);
+}
diff --git a/services/java/com/android/server/display/DisplayDeviceInfo.java b/services/java/com/android/server/display/DisplayDeviceInfo.java
new file mode 100644
index 0000000..c28b9bb
--- /dev/null
+++ b/services/java/com/android/server/display/DisplayDeviceInfo.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display;
+
+/**
+ * Describes the characteristics of a physical display device.
+ */
+public final class DisplayDeviceInfo {
+ /**
+ * The width of the display in its natural orientation, in pixels.
+ * This value is not affected by display rotation.
+ */
+ public int width;
+
+ /**
+ * The height of the display in its natural orientation, in pixels.
+ * This value is not affected by display rotation.
+ */
+ public int height;
+
+ public float refreshRate;
+ public float density;
+ public float xDpi;
+ public float yDpi;
+
+ public void copyFrom(DisplayDeviceInfo other) {
+ width = other.width;
+ height = other.height;
+ refreshRate = other.refreshRate;
+ density = other.density;
+ xDpi = other.xDpi;
+ yDpi = other.yDpi;
+ }
+
+ @Override
+ public String toString() {
+ return width + " x " + height + ", " + refreshRate + " fps, "
+ + "density " + density + ", " + xDpi + " x " + yDpi + " dpi";
+ }
+}
diff --git a/services/java/com/android/server/display/DisplayManagerService.java b/services/java/com/android/server/display/DisplayManagerService.java
new file mode 100644
index 0000000..082d28f
--- /dev/null
+++ b/services/java/com/android/server/display/DisplayManagerService.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display;
+
+import android.Manifest;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.hardware.display.IDisplayManager;
+import android.os.Binder;
+import android.os.SystemProperties;
+import android.view.Display;
+import android.view.DisplayInfo;
+import android.view.Surface;
+
+import java.io.FileDescriptor;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+
+/**
+ * Manages the properties, media routing and power state of attached displays.
+ * <p>
+ * The display manager service does not own or directly control the displays.
+ * Instead, other components in the system register their display adapters with the
+ * display manager service which acts as a central controller.
+ * </p>
+ */
+public final class DisplayManagerService extends IDisplayManager.Stub {
+ private static final String TAG = "DisplayManagerService";
+
+ private static final String SYSTEM_HEADLESS = "ro.config.headless";
+
+ private final Object mLock = new Object();
+
+ private Context mContext;
+ private final boolean mHeadless;
+ private final ArrayList<DisplayAdapter> mDisplayAdapters = new ArrayList<DisplayAdapter>();
+
+ // TODO: represent this as a map between logical and physical devices
+ private DisplayInfo mDefaultDisplayInfo;
+ private DisplayDevice mDefaultDisplayDevice;
+ private DisplayDeviceInfo mDefaultDisplayDeviceInfo;
+
+ public DisplayManagerService() {
+ mHeadless = SystemProperties.get(SYSTEM_HEADLESS).equals("1");
+ registerDisplayAdapters();
+ initializeDefaultDisplay();
+ }
+
+ public void setContext(Context context) {
+ mContext = context;
+ }
+
+ // FIXME: this isn't the right API for the long term
+ public void setDefaultDisplayInfo(DisplayInfo info) {
+ synchronized (mLock) {
+ mDefaultDisplayInfo.copyFrom(info);
+ }
+ }
+
+ // FIXME: this isn't the right API for the long term
+ public void getDefaultExternalDisplayDeviceInfo(DisplayDeviceInfo info) {
+ // hardcoded assuming 720p touch screen plugged into HDMI and USB
+ // need to redesign this
+ info.width = 1280;
+ info.height = 720;
+ }
+
+ public boolean isHeadless() {
+ return mHeadless;
+ }
+
+ @Override // Binder call
+ public boolean getDisplayInfo(int displayId, DisplayInfo outInfo) {
+ synchronized (mLock) {
+ if (displayId == Display.DEFAULT_DISPLAY) {
+ outInfo.copyFrom(mDefaultDisplayInfo);
+ return true;
+ }
+ return false;
+ }
+ }
+
+ @Override // Binder call
+ public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
+ if (mContext == null
+ || mContext.checkCallingOrSelfPermission(Manifest.permission.DUMP)
+ != PackageManager.PERMISSION_GRANTED) {
+ pw.println("Permission Denial: can't dump DisplayManager from from pid="
+ + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid());
+ return;
+ }
+
+ pw.println("DISPLAY MANAGER (dumpsys display)\n");
+
+ pw.println("Headless: " + mHeadless);
+
+ DisplayDeviceInfo info = new DisplayDeviceInfo();
+ for (DisplayAdapter adapter : mDisplayAdapters) {
+ pw.println("Displays for adapter " + adapter.getName());
+ for (DisplayDevice device : adapter.getDisplayDevices()) {
+ device.getInfo(info);
+ pw.print(" ");
+ pw.println(info);
+ }
+ }
+ }
+
+ private void registerDisplayAdapters() {
+ if (mHeadless) {
+ registerDisplayAdapter(new HeadlessDisplayAdapter());
+ } else {
+ registerDisplayAdapter(new SurfaceFlingerDisplayAdapter());
+ }
+ }
+
+ private void registerDisplayAdapter(DisplayAdapter adapter) {
+ // TODO: do this dynamically
+ mDisplayAdapters.add(adapter);
+ mDefaultDisplayDevice = adapter.getDisplayDevices()[0];
+ mDefaultDisplayDeviceInfo = new DisplayDeviceInfo();
+ mDefaultDisplayDevice.getInfo(mDefaultDisplayDeviceInfo);
+ }
+
+ private void initializeDefaultDisplay() {
+ // Bootstrap the default logical display using the default physical display.
+ mDefaultDisplayInfo = new DisplayInfo();
+ mDefaultDisplayInfo.appWidth = mDefaultDisplayDeviceInfo.width;
+ mDefaultDisplayInfo.appHeight = mDefaultDisplayDeviceInfo.height;
+ mDefaultDisplayInfo.logicalWidth = mDefaultDisplayDeviceInfo.width;
+ mDefaultDisplayInfo.logicalHeight = mDefaultDisplayDeviceInfo.height;
+ mDefaultDisplayInfo.rotation = Surface.ROTATION_0;
+ mDefaultDisplayInfo.refreshRate = mDefaultDisplayDeviceInfo.refreshRate;
+ mDefaultDisplayInfo.logicalDensity = mDefaultDisplayDeviceInfo.density;
+ mDefaultDisplayInfo.physicalXDpi = mDefaultDisplayDeviceInfo.xDpi;
+ mDefaultDisplayInfo.physicalYDpi = mDefaultDisplayDeviceInfo.yDpi;
+ mDefaultDisplayInfo.smallestNominalAppWidth = mDefaultDisplayDeviceInfo.width;
+ mDefaultDisplayInfo.smallestNominalAppHeight = mDefaultDisplayDeviceInfo.height;
+ mDefaultDisplayInfo.largestNominalAppWidth = mDefaultDisplayDeviceInfo.width;
+ mDefaultDisplayInfo.largestNominalAppHeight = mDefaultDisplayDeviceInfo.height;
+ }
+}
diff --git a/services/java/com/android/server/display/HeadlessDisplayAdapter.java b/services/java/com/android/server/display/HeadlessDisplayAdapter.java
new file mode 100644
index 0000000..d2a70d2
--- /dev/null
+++ b/services/java/com/android/server/display/HeadlessDisplayAdapter.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display;
+
+/**
+ * Provides a fake default display for headless systems.
+ */
+public final class HeadlessDisplayAdapter extends DisplayAdapter {
+ private final DisplayDevice mDefaultDisplay = new DisplayDevice() {
+ @Override
+ public void getInfo(DisplayDeviceInfo outInfo) {
+ outInfo.width = 640;
+ outInfo.height = 480;
+ outInfo.refreshRate = 60;
+ outInfo.density = 1.0f;
+ outInfo.xDpi = 160;
+ outInfo.yDpi = 160;
+ }
+ };
+
+ @Override
+ public String getName() {
+ return "HeadlessDisplayAdapter";
+ }
+
+ @Override
+ public DisplayDevice[] getDisplayDevices() {
+ return new DisplayDevice[] { mDefaultDisplay };
+ }
+}
diff --git a/services/java/com/android/server/display/SurfaceFlingerDisplayAdapter.java b/services/java/com/android/server/display/SurfaceFlingerDisplayAdapter.java
new file mode 100644
index 0000000..89934d3
--- /dev/null
+++ b/services/java/com/android/server/display/SurfaceFlingerDisplayAdapter.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.display;
+
+/**
+ * A display adapter for the displays managed by Surface Flinger.
+ */
+public final class SurfaceFlingerDisplayAdapter extends DisplayAdapter {
+ private static native void nativeGetDefaultDisplayDeviceInfo(DisplayDeviceInfo outInfo);
+
+ private final DisplayDevice mDefaultDisplay = new DisplayDevice() {
+ @Override
+ public void getInfo(DisplayDeviceInfo outInfo) {
+ nativeGetDefaultDisplayDeviceInfo(outInfo);
+ }
+ };
+
+ @Override
+ public String getName() {
+ return "SurfaceFlingerDisplayAdapter";
+ }
+
+ @Override
+ public DisplayDevice[] getDisplayDevices() {
+ return new DisplayDevice[] { mDefaultDisplay };
+ }
+}
diff --git a/services/java/com/android/server/power/PowerManagerService.java b/services/java/com/android/server/power/PowerManagerService.java
index 2940b70..b3cd0f2 100644
--- a/services/java/com/android/server/power/PowerManagerService.java
+++ b/services/java/com/android/server/power/PowerManagerService.java
@@ -22,6 +22,7 @@ import com.android.server.EventLogTags;
import com.android.server.LightsService;
import com.android.server.Watchdog;
import com.android.server.am.BatteryStatsService;
+import com.android.server.display.DisplayManagerService;
import android.app.ActivityManagerNative;
import android.app.IActivityManager;
@@ -254,6 +255,7 @@ public class PowerManagerService extends IPowerManager.Stub
private IActivityManager mActivityService;
private IBatteryStats mBatteryStats;
private BatteryService mBatteryService;
+ private DisplayManagerService mDisplayManagerService;
private SensorManager mSensorManager;
private Sensor mProximitySensor;
private Sensor mLightSensor;
@@ -543,12 +545,13 @@ public class PowerManagerService extends IPowerManager.Stub
private ContentQueryMap mSettings;
public void init(Context context, LightsService lights, IActivityManager activity,
- BatteryService battery) {
+ BatteryService battery, DisplayManagerService displayManagerService) {
mLightsService = lights;
mContext = context;
mActivityService = activity;
mBatteryStats = BatteryStatsService.getService();
mBatteryService = battery;
+ mDisplayManagerService = displayManagerService;
mLcdLight = lights.getLight(LightsService.LIGHT_ID_BACKLIGHT);
mButtonLight = lights.getLight(LightsService.LIGHT_ID_BUTTONS);
diff --git a/services/java/com/android/server/wm/DragState.java b/services/java/com/android/server/wm/DragState.java
index b2cf3e0..f0b0e1f 100644
--- a/services/java/com/android/server/wm/DragState.java
+++ b/services/java/com/android/server/wm/DragState.java
@@ -125,8 +125,8 @@ class DragState {
// The drag window covers the entire display
mDragWindowHandle.frameLeft = 0;
mDragWindowHandle.frameTop = 0;
- mDragWindowHandle.frameRight = mService.mCurDisplayWidth;
- mDragWindowHandle.frameBottom = mService.mCurDisplayHeight;
+ mDragWindowHandle.frameRight = mService.mDisplayInfo.logicalWidth;
+ mDragWindowHandle.frameBottom = mService.mDisplayInfo.logicalHeight;
// Pause rotations before a drag.
if (WindowManagerService.DEBUG_ORIENTATION) {
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index d0456ee..ac0fa87 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -45,6 +45,8 @@ import com.android.server.AttributeCache;
import com.android.server.EventLogTags;
import com.android.server.Watchdog;
import com.android.server.am.BatteryStatsService;
+import com.android.server.display.DisplayDeviceInfo;
+import com.android.server.display.DisplayManagerService;
import com.android.server.input.InputManagerService;
import com.android.server.power.PowerManagerService;
import com.android.server.power.ShutdownThread;
@@ -104,6 +106,7 @@ import android.util.SparseIntArray;
import android.util.TypedValue;
import android.view.Choreographer;
import android.view.Display;
+import android.view.DisplayInfo;
import android.view.Gravity;
import android.view.IApplicationToken;
import android.view.IInputFilter;
@@ -271,7 +274,6 @@ public class WindowManagerService extends IWindowManager.Stub
private static final String SYSTEM_SECURE = "ro.secure";
private static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
- private static final String SYSTEM_HEADLESS = "ro.config.headless";
/**
* Condition waited on by {@link #reenableKeyguard} to know the call to
@@ -482,14 +484,7 @@ public class WindowManagerService extends IWindowManager.Stub
int mInitialDisplayHeight = 0;
int mBaseDisplayWidth = 0;
int mBaseDisplayHeight = 0;
- int mCurDisplayWidth = 0;
- int mCurDisplayHeight = 0;
- int mAppDisplayWidth = 0;
- int mAppDisplayHeight = 0;
- int mSmallestDisplayWidth = 0;
- int mSmallestDisplayHeight = 0;
- int mLargestDisplayWidth = 0;
- int mLargestDisplayHeight = 0;
+ final DisplayInfo mDisplayInfo = new DisplayInfo();
int mRotation = 0;
int mForcedAppOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
@@ -616,6 +611,7 @@ public class WindowManagerService extends IWindowManager.Stub
float mAnimatorDurationScale = 1.0f;
final InputManagerService mInputManager;
+ final DisplayManagerService mDisplayManager;
// Who is holding the screen on.
Session mHoldingScreenOn;
@@ -785,9 +781,10 @@ public class WindowManagerService extends IWindowManager.Stub
final boolean mOnlyCore;
public static WindowManagerService main(Context context,
- PowerManagerService pm, boolean haveInputMethods, boolean allowBootMsgs,
+ PowerManagerService pm, DisplayManagerService dm,
+ boolean haveInputMethods, boolean allowBootMsgs,
boolean onlyCore) {
- WMThread thr = new WMThread(context, pm, haveInputMethods, allowBootMsgs, onlyCore);
+ WMThread thr = new WMThread(context, pm, dm, haveInputMethods, allowBootMsgs, onlyCore);
thr.start();
synchronized (thr) {
@@ -806,15 +803,18 @@ public class WindowManagerService extends IWindowManager.Stub
private final Context mContext;
private final PowerManagerService mPM;
+ private final DisplayManagerService mDisplayManager;
private final boolean mHaveInputMethods;
private final boolean mAllowBootMessages;
private final boolean mOnlyCore;
public WMThread(Context context, PowerManagerService pm,
+ DisplayManagerService dm,
boolean haveInputMethods, boolean allowBootMsgs, boolean onlyCore) {
super("WindowManager");
mContext = context;
mPM = pm;
+ mDisplayManager = dm;
mHaveInputMethods = haveInputMethods;
mAllowBootMessages = allowBootMsgs;
mOnlyCore = onlyCore;
@@ -825,7 +825,7 @@ public class WindowManagerService extends IWindowManager.Stub
Looper.prepare();
//Looper.myLooper().setMessageLogging(new LogPrinter(
// android.util.Log.DEBUG, TAG, android.util.Log.LOG_ID_SYSTEM));
- WindowManagerService s = new WindowManagerService(mContext, mPM,
+ WindowManagerService s = new WindowManagerService(mContext, mPM, mDisplayManager,
mHaveInputMethods, mAllowBootMessages, mOnlyCore);
android.os.Process.setThreadPriority(
android.os.Process.THREAD_PRIORITY_DISPLAY);
@@ -892,6 +892,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
private WindowManagerService(Context context, PowerManagerService pm,
+ DisplayManagerService displayManager,
boolean haveInputMethods, boolean showBootMsgs, boolean onlyCore) {
mContext = context;
mHaveInputMethods = haveInputMethods;
@@ -899,7 +900,8 @@ public class WindowManagerService extends IWindowManager.Stub
mOnlyCore = onlyCore;
mLimitedAlphaCompositing = context.getResources().getBoolean(
com.android.internal.R.bool.config_sf_limitedAlpha);
- mHeadless = "1".equals(SystemProperties.get(SYSTEM_HEADLESS, "0"));
+ mDisplayManager = displayManager;
+ mHeadless = displayManager.isHeadless();
mPowerManager = pm;
mPowerManager.setPolicy(mPolicy);
@@ -1650,8 +1652,8 @@ public class WindowManagerService extends IWindowManager.Stub
mInnerFields.mWallpaperMayChange = false;
int changed = 0;
- final int dw = mAppDisplayWidth;
- final int dh = mAppDisplayHeight;
+ final int dw = mDisplayInfo.appWidth;
+ final int dh = mDisplayInfo.appHeight;
// First find top-most window that has asked to be on top of the
// wallpaper; all wallpapers go behind it.
@@ -2060,8 +2062,8 @@ public class WindowManagerService extends IWindowManager.Stub
}
void updateWallpaperOffsetLocked(WindowState changingTarget, boolean sync) {
- final int dw = mAppDisplayWidth;
- final int dh = mAppDisplayHeight;
+ final int dw = mDisplayInfo.appWidth;
+ final int dh = mDisplayInfo.appHeight;
WindowState target = mWallpaperTarget;
if (target != null) {
@@ -2123,8 +2125,8 @@ public class WindowManagerService extends IWindowManager.Stub
void updateWallpaperVisibilityLocked() {
final boolean visible = isWallpaperVisible(mWallpaperTarget);
- final int dw = mAppDisplayWidth;
- final int dh = mAppDisplayHeight;
+ final int dw = mDisplayInfo.appWidth;
+ final int dh = mDisplayInfo.appHeight;
int curTokenIndex = mWallpaperTokens.size();
while (curTokenIndex > 0) {
@@ -2699,9 +2701,11 @@ public class WindowManagerService extends IWindowManager.Stub
mTmpFloats[Matrix.MSKEW_X] = dsdy;
mTmpFloats[Matrix.MSCALE_Y] = dtdy;
matrix.setValues(mTmpFloats);
- final RectF dispRect = new RectF(0, 0, mCurDisplayWidth, mCurDisplayHeight);
+ final RectF dispRect = new RectF(0, 0,
+ mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
matrix.mapRect(dispRect);
- window.mGivenTouchableRegion.set(0, 0, mCurDisplayWidth, mCurDisplayHeight);
+ window.mGivenTouchableRegion.set(0, 0,
+ mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight);
window.mGivenTouchableRegion.op((int)dispRect.left, (int)dispRect.top,
(int)dispRect.right, (int)dispRect.bottom, Region.Op.DIFFERENCE);
window.mTouchableInsets = ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
@@ -2981,7 +2985,8 @@ public class WindowManagerService extends IWindowManager.Stub
configChanged = updateOrientationFromAppTokensLocked(false);
performLayoutAndPlaceSurfacesLocked();
if (toBeDisplayed && win.mIsWallpaper) {
- updateWallpaperOffsetLocked(win, mAppDisplayWidth, mAppDisplayHeight, false);
+ updateWallpaperOffsetLocked(win,
+ mDisplayInfo.appWidth, mDisplayInfo.appHeight, false);
}
if (win.mAppToken != null) {
win.mAppToken.updateReportedVisibilityLocked();
@@ -3201,8 +3206,8 @@ public class WindowManagerService extends IWindowManager.Stub
}
if (enter) {
// Entering app zooms out from the center of the initial rect.
- float scaleW = mNextAppTransitionStartWidth / (float) mAppDisplayWidth;
- float scaleH = mNextAppTransitionStartHeight / (float) mAppDisplayHeight;
+ float scaleW = mNextAppTransitionStartWidth / (float) mDisplayInfo.appWidth;
+ float scaleH = mNextAppTransitionStartHeight / (float) mDisplayInfo.appHeight;
Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
computePivot(mNextAppTransitionStartX, scaleW),
computePivot(mNextAppTransitionStartY, scaleH));
@@ -3222,8 +3227,8 @@ public class WindowManagerService extends IWindowManager.Stub
final Interpolator interpolator = AnimationUtils.loadInterpolator(mContext,
com.android.internal.R.interpolator.decelerate_cubic);
a.setInterpolator(interpolator);
- a.initialize(mAppDisplayWidth, mAppDisplayHeight,
- mAppDisplayWidth, mAppDisplayHeight);
+ a.initialize(mDisplayInfo.appWidth, mDisplayInfo.appHeight,
+ mDisplayInfo.appWidth, mDisplayInfo.appHeight);
return a;
}
@@ -3252,8 +3257,8 @@ public class WindowManagerService extends IWindowManager.Stub
if (thumb) {
// Animation for zooming thumbnail from its initial size to
// filling the screen.
- float scaleW = mAppDisplayWidth/thumbWidth;
- float scaleH = mAppDisplayHeight/thumbHeight;
+ float scaleW = mDisplayInfo.appWidth/thumbWidth;
+ float scaleH = mDisplayInfo.appHeight/thumbHeight;
Animation scale = new ScaleAnimation(1, scaleW, 1, scaleH,
computePivot(mNextAppTransitionStartX, 1/scaleW),
@@ -3273,8 +3278,8 @@ public class WindowManagerService extends IWindowManager.Stub
a = set;
} else if (enter) {
// Entering app zooms out from the center of the thumbnail.
- float scaleW = thumbWidth / mAppDisplayWidth;
- float scaleH = thumbHeight / mAppDisplayHeight;
+ float scaleW = thumbWidth / mDisplayInfo.appWidth;
+ float scaleH = thumbHeight / mDisplayInfo.appHeight;
Animation scale = new ScaleAnimation(scaleW, 1, scaleH, 1,
computePivot(mNextAppTransitionStartX, scaleW),
computePivot(mNextAppTransitionStartY, scaleH));
@@ -3300,8 +3305,8 @@ public class WindowManagerService extends IWindowManager.Stub
final Interpolator interpolator = AnimationUtils.loadInterpolator(mContext,
com.android.internal.R.interpolator.decelerate_quad);
a.setInterpolator(interpolator);
- a.initialize(mAppDisplayWidth, mAppDisplayHeight,
- mAppDisplayWidth, mAppDisplayHeight);
+ a.initialize(mDisplayInfo.appWidth, mDisplayInfo.appHeight,
+ mDisplayInfo.appWidth, mDisplayInfo.appHeight);
return a;
}
@@ -5498,8 +5503,8 @@ public class WindowManagerService extends IWindowManager.Stub
synchronized(mWindowMap) {
long ident = Binder.clearCallingIdentity();
- dw = mCurDisplayWidth;
- dh = mCurDisplayHeight;
+ dw = mDisplayInfo.logicalWidth;
+ dh = mDisplayInfo.logicalHeight;
int aboveAppLayer = mPolicy.windowTypeToLayerLw(
WindowManager.LayoutParams.TYPE_APPLICATION) * TYPE_LAYER_MULTIPLIER
@@ -5793,8 +5798,7 @@ public class WindowManagerService extends IWindowManager.Stub
mWaitingForConfig = true;
mLayoutNeeded = true;
startFreezingDisplayLocked(inTransaction);
- mInputManager.setDisplayOrientation(0, rotation,
- mDisplay != null ? mDisplay.getExternalRotation() : Surface.ROTATION_0);
+ mInputManager.setDisplayOrientation(0, rotation, Surface.ROTATION_0);
// We need to update our screen size information to match the new
// rotation. Note that this is redundant with the later call to
@@ -5816,7 +5820,7 @@ public class WindowManagerService extends IWindowManager.Stub
&& mAnimator.mScreenRotationAnimation.hasScreenshot()) {
if (mAnimator.mScreenRotationAnimation.setRotation(rotation, mFxSession,
MAX_ANIMATION_DURATION, mTransitionAnimationScale,
- mCurDisplayWidth, mCurDisplayHeight)) {
+ mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight)) {
updateLayoutToAnimationLocked();
}
}
@@ -6315,18 +6319,18 @@ public class WindowManagerService extends IWindowManager.Stub
private void adjustDisplaySizeRanges(int rotation, int dw, int dh) {
final int width = mPolicy.getConfigDisplayWidth(dw, dh, rotation);
- if (width < mSmallestDisplayWidth) {
- mSmallestDisplayWidth = width;
+ if (width < mDisplayInfo.smallestNominalAppWidth) {
+ mDisplayInfo.smallestNominalAppWidth = width;
}
- if (width > mLargestDisplayWidth) {
- mLargestDisplayWidth = width;
+ if (width > mDisplayInfo.largestNominalAppWidth) {
+ mDisplayInfo.largestNominalAppWidth = width;
}
final int height = mPolicy.getConfigDisplayHeight(dw, dh, rotation);
- if (height < mSmallestDisplayHeight) {
- mSmallestDisplayHeight = height;
+ if (height < mDisplayInfo.smallestNominalAppHeight) {
+ mDisplayInfo.smallestNominalAppHeight = height;
}
- if (height > mLargestDisplayHeight) {
- mLargestDisplayHeight = height;
+ if (height > mDisplayInfo.largestNominalAppHeight) {
+ mDisplayInfo.largestNominalAppHeight = height;
}
}
@@ -6423,10 +6427,10 @@ public class WindowManagerService extends IWindowManager.Stub
unrotDw = dw;
unrotDh = dh;
}
- mSmallestDisplayWidth = 1<<30;
- mSmallestDisplayHeight = 1<<30;
- mLargestDisplayWidth = 0;
- mLargestDisplayHeight = 0;
+ mDisplayInfo.smallestNominalAppWidth = 1<<30;
+ mDisplayInfo.smallestNominalAppHeight = 1<<30;
+ mDisplayInfo.largestNominalAppWidth = 0;
+ mDisplayInfo.largestNominalAppHeight = 0;
adjustDisplaySizeRanges(Surface.ROTATION_0, unrotDw, unrotDh);
adjustDisplaySizeRanges(Surface.ROTATION_90, unrotDh, unrotDw);
adjustDisplaySizeRanges(Surface.ROTATION_180, unrotDw, unrotDh);
@@ -6437,7 +6441,7 @@ public class WindowManagerService extends IWindowManager.Stub
sl = reduceConfigLayout(sl, Surface.ROTATION_90, density, unrotDh, unrotDw);
sl = reduceConfigLayout(sl, Surface.ROTATION_180, density, unrotDw, unrotDh);
sl = reduceConfigLayout(sl, Surface.ROTATION_270, density, unrotDh, unrotDw);
- outConfig.smallestScreenWidthDp = (int)(mSmallestDisplayWidth / density);
+ outConfig.smallestScreenWidthDp = (int)(mDisplayInfo.smallestNominalAppWidth / density);
outConfig.screenLayout = sl;
}
@@ -6481,33 +6485,25 @@ public class WindowManagerService extends IWindowManager.Stub
|| mRotation == Surface.ROTATION_270);
final int realdw = rotated ? mBaseDisplayHeight : mBaseDisplayWidth;
final int realdh = rotated ? mBaseDisplayWidth : mBaseDisplayHeight;
+ int dw = realdw;
+ int dh = realdh;
- synchronized(mDisplaySizeLock) {
- if (mAltOrientation) {
- mCurDisplayWidth = realdw;
- mCurDisplayHeight = realdh;
- if (realdw > realdh) {
- // Turn landscape into portrait.
- int maxw = (int)(realdh/1.3f);
- if (maxw < realdw) {
- mCurDisplayWidth = maxw;
- }
- } else {
- // Turn portrait into landscape.
- int maxh = (int)(realdw/1.3f);
- if (maxh < realdh) {
- mCurDisplayHeight = maxh;
- }
+ if (mAltOrientation) {
+ if (realdw > realdh) {
+ // Turn landscape into portrait.
+ int maxw = (int)(realdh/1.3f);
+ if (maxw < realdw) {
+ dw = maxw;
}
} else {
- mCurDisplayWidth = realdw;
- mCurDisplayHeight = realdh;
+ // Turn portrait into landscape.
+ int maxh = (int)(realdw/1.3f);
+ if (maxh < realdh) {
+ dh = maxh;
+ }
}
}
- final int dw = mCurDisplayWidth;
- final int dh = mCurDisplayHeight;
-
if (config != null) {
int orientation = Configuration.ORIENTATION_SQUARE;
if (dw < dh) {
@@ -6518,25 +6514,26 @@ public class WindowManagerService extends IWindowManager.Stub
config.orientation = orientation;
}
- // Update real display metrics.
- mDisplay.getMetricsWithSize(mRealDisplayMetrics, mCurDisplayWidth, mCurDisplayHeight);
-
// Update application display metrics.
- final DisplayMetrics dm = mDisplayMetrics;
final int appWidth = mPolicy.getNonDecorDisplayWidth(dw, dh, mRotation);
final int appHeight = mPolicy.getNonDecorDisplayHeight(dw, dh, mRotation);
synchronized(mDisplaySizeLock) {
- mAppDisplayWidth = appWidth;
- mAppDisplayHeight = appHeight;
- mAnimator.setDisplayDimensions(mCurDisplayWidth, mCurDisplayHeight,
- mAppDisplayWidth, mAppDisplayHeight);
+ mDisplayInfo.rotation = mRotation;
+ mDisplayInfo.logicalWidth = dw;
+ mDisplayInfo.logicalHeight = dh;
+ mDisplayInfo.appWidth = appWidth;
+ mDisplayInfo.appHeight = appHeight;
+ mDisplayInfo.getLogicalMetrics(mRealDisplayMetrics, null);
+ mDisplayInfo.getAppMetrics(mDisplayMetrics, null);
+ mDisplayManager.setDefaultDisplayInfo(mDisplayInfo);
+
+ mAnimator.setDisplayDimensions(dw, dh, appWidth, appHeight);
}
if (false) {
- Slog.i(TAG, "Set app display size: " + mAppDisplayWidth
- + " x " + mAppDisplayHeight);
+ Slog.i(TAG, "Set app display size: " + appWidth + " x " + appHeight);
}
- mDisplay.getMetricsWithSize(dm, mAppDisplayWidth, mAppDisplayHeight);
+ final DisplayMetrics dm = mDisplayMetrics;
mCompatibleScreenScale = CompatibilityInfo.computeCompatibleScaling(dm,
mCompatDisplayMetrics);
@@ -6843,27 +6840,26 @@ public class WindowManagerService extends IWindowManager.Stub
mDisplay = wm.getDefaultDisplay();
mIsTouchDevice = mContext.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_TOUCHSCREEN);
+
synchronized(mDisplaySizeLock) {
- mInitialDisplayWidth = mDisplay.getRawWidth();
- mInitialDisplayHeight = mDisplay.getRawHeight();
- int rot = mDisplay.getRotation();
- if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270) {
- // If the screen is currently rotated, we need to swap the
- // initial width and height to get the true natural values.
- int tmp = mInitialDisplayWidth;
- mInitialDisplayWidth = mInitialDisplayHeight;
- mInitialDisplayHeight = tmp;
- }
- mBaseDisplayWidth = mCurDisplayWidth = mAppDisplayWidth = mInitialDisplayWidth;
- mBaseDisplayHeight = mCurDisplayHeight = mAppDisplayHeight = mInitialDisplayHeight;
- mAnimator.setDisplayDimensions(mCurDisplayWidth, mCurDisplayHeight,
- mAppDisplayWidth, mAppDisplayHeight);
+ // Bootstrap the default logical display from the display manager.
+ mDisplayManager.getDisplayInfo(Display.DEFAULT_DISPLAY, mDisplayInfo);
+ mInitialDisplayWidth = mDisplayInfo.logicalWidth;
+ mInitialDisplayHeight = mDisplayInfo.logicalHeight;
+ mBaseDisplayWidth = mInitialDisplayWidth;
+ mBaseDisplayHeight = mInitialDisplayHeight;
+
+ mAnimator.setDisplayDimensions(mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight,
+ mDisplayInfo.appWidth, mDisplayInfo.appHeight);
}
+
+ DisplayDeviceInfo info = new DisplayDeviceInfo();
+ mDisplayManager.getDefaultExternalDisplayDeviceInfo(info);
mInputManager.setDisplaySize(Display.DEFAULT_DISPLAY,
- mDisplay.getRawWidth(), mDisplay.getRawHeight(),
- mDisplay.getRawExternalWidth(), mDisplay.getRawExternalHeight());
+ mInitialDisplayWidth, mInitialDisplayHeight,
+ info.width, info.height);
mInputManager.setDisplayOrientation(Display.DEFAULT_DISPLAY,
- mDisplay.getRotation(), mDisplay.getExternalRotation());
+ mDisplay.getRotation(), Surface.ROTATION_0);
mPolicy.setInitialDisplaySize(mDisplay, mInitialDisplayWidth, mInitialDisplayHeight);
}
@@ -7471,20 +7467,6 @@ public class WindowManagerService extends IWindowManager.Stub
return false;
}
- public void getDisplaySize(Point size) {
- synchronized(mDisplaySizeLock) {
- size.x = mAppDisplayWidth;
- size.y = mAppDisplayHeight;
- }
- }
-
- public void getRealDisplaySize(Point size) {
- synchronized(mDisplaySizeLock) {
- size.x = mCurDisplayWidth;
- size.y = mCurDisplayHeight;
- }
- }
-
public void getInitialDisplaySize(Point size) {
synchronized(mDisplaySizeLock) {
size.x = mInitialDisplayWidth;
@@ -7492,23 +7474,6 @@ public class WindowManagerService extends IWindowManager.Stub
}
}
- public int getMaximumSizeDimension() {
- synchronized(mDisplaySizeLock) {
- // Do this based on the raw screen size, until we are smarter.
- return mBaseDisplayWidth > mBaseDisplayHeight
- ? mBaseDisplayWidth : mBaseDisplayHeight;
- }
- }
-
- public void getCurrentSizeRange(Point smallestSize, Point largestSize) {
- synchronized(mDisplaySizeLock) {
- smallestSize.x = mSmallestDisplayWidth;
- smallestSize.y = mSmallestDisplayHeight;
- largestSize.x = mLargestDisplayWidth;
- largestSize.y = mLargestDisplayHeight;
- }
- }
-
public void setForcedDisplaySize(int longDimen, int shortDimen) {
synchronized(mWindowMap) {
int width, height;
@@ -7899,8 +7864,8 @@ public class WindowManagerService extends IWindowManager.Stub
mLayoutNeeded = false;
- final int dw = mCurDisplayWidth;
- final int dh = mCurDisplayHeight;
+ final int dw = mDisplayInfo.logicalWidth;
+ final int dh = mDisplayInfo.logicalHeight;
final int NFW = mFakeWindows.size();
for (int i=0; i<NFW; i++) {
@@ -8492,8 +8457,8 @@ public class WindowManagerService extends IWindowManager.Stub
if (!mAnimator.isDimming(winAnimator)) {
final int width, height;
if (attrs.type == WindowManager.LayoutParams.TYPE_BOOT_PROGRESS) {
- width = mCurDisplayWidth;
- height = mCurDisplayHeight;
+ width = mDisplayInfo.logicalWidth;
+ height = mDisplayInfo.logicalHeight;
} else {
width = innerDw;
height = innerDh;
@@ -8537,10 +8502,10 @@ public class WindowManagerService extends IWindowManager.Stub
}
final long currentTime = SystemClock.uptimeMillis();
- final int dw = mCurDisplayWidth;
- final int dh = mCurDisplayHeight;
- final int innerDw = mAppDisplayWidth;
- final int innerDh = mAppDisplayHeight;
+ final int dw = mDisplayInfo.logicalWidth;
+ final int dh = mDisplayInfo.logicalHeight;
+ final int innerDw = mDisplayInfo.appWidth;
+ final int innerDh = mDisplayInfo.appHeight;
int i;
@@ -9456,7 +9421,7 @@ public class WindowManagerService extends IWindowManager.Stub
}
mAnimator.mScreenRotationAnimation = new ScreenRotationAnimation(mContext,
- mFxSession, inTransaction, mCurDisplayWidth, mCurDisplayHeight,
+ mFxSession, inTransaction, mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight,
mDisplay.getRotation());
}
}
@@ -9486,7 +9451,7 @@ public class WindowManagerService extends IWindowManager.Stub
&& mAnimator.mScreenRotationAnimation.hasScreenshot()) {
if (DEBUG_ORIENTATION) Slog.i(TAG, "**** Dismissing screen rotation animation");
if (mAnimator.mScreenRotationAnimation.dismiss(mFxSession, MAX_ANIMATION_DURATION,
- mTransitionAnimationScale, mCurDisplayWidth, mCurDisplayHeight)) {
+ mTransitionAnimationScale, mDisplayInfo.logicalWidth, mDisplayInfo.logicalHeight)) {
updateLayoutToAnimationLocked();
} else {
mAnimator.mScreenRotationAnimation.kill();
@@ -9935,19 +9900,21 @@ public class WindowManagerService extends IWindowManager.Stub
pw.print(" base=");
pw.print(mBaseDisplayWidth); pw.print("x"); pw.print(mBaseDisplayHeight);
}
- final int rawWidth = mDisplay.getRawWidth();
- final int rawHeight = mDisplay.getRawHeight();
- if (rawWidth != mCurDisplayWidth || rawHeight != mCurDisplayHeight) {
- pw.print(" raw="); pw.print(rawWidth); pw.print("x"); pw.print(rawHeight);
+ if (mInitialDisplayWidth != mDisplayInfo.logicalWidth
+ || mInitialDisplayHeight != mDisplayInfo.logicalHeight) {
+ pw.print(" init="); pw.print(mInitialDisplayWidth);
+ pw.print("x"); pw.print(mInitialDisplayHeight);
}
pw.print(" cur=");
- pw.print(mCurDisplayWidth); pw.print("x"); pw.print(mCurDisplayHeight);
+ pw.print(mDisplayInfo.logicalWidth);
+ pw.print("x"); pw.print(mDisplayInfo.logicalHeight);
pw.print(" app=");
- pw.print(mAppDisplayWidth); pw.print("x"); pw.print(mAppDisplayHeight);
- pw.print(" rng="); pw.print(mSmallestDisplayWidth);
- pw.print("x"); pw.print(mSmallestDisplayHeight);
- pw.print("-"); pw.print(mLargestDisplayWidth);
- pw.print("x"); pw.println(mLargestDisplayHeight);
+ pw.print(mDisplayInfo.appWidth);
+ pw.print("x"); pw.print(mDisplayInfo.appHeight);
+ pw.print(" rng="); pw.print(mDisplayInfo.smallestNominalAppWidth);
+ pw.print("x"); pw.print(mDisplayInfo.smallestNominalAppHeight);
+ pw.print("-"); pw.print(mDisplayInfo.largestNominalAppWidth);
+ pw.print("x"); pw.println(mDisplayInfo.largestNominalAppHeight);
} else {
pw.println(" NO DISPLAY");
}
diff --git a/services/java/com/android/server/wm/WindowState.java b/services/java/com/android/server/wm/WindowState.java
index 94fd199..d371828 100644
--- a/services/java/com/android/server/wm/WindowState.java
+++ b/services/java/com/android/server/wm/WindowState.java
@@ -480,7 +480,7 @@ final class WindowState implements WindowManagerPolicy.WindowState {
if (mIsWallpaper && (fw != frame.width() || fh != frame.height())) {
mService.updateWallpaperOffsetLocked(this,
- mService.mAppDisplayWidth, mService.mAppDisplayHeight, false);
+ mService.mDisplayInfo.appWidth, mService.mDisplayInfo.appHeight, false);
}
if (WindowManagerService.localLOGV) {
diff --git a/services/java/com/android/server/wm/WindowStateAnimator.java b/services/java/com/android/server/wm/WindowStateAnimator.java
index f08204f..ce87f4c 100644
--- a/services/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/java/com/android/server/wm/WindowStateAnimator.java
@@ -151,8 +151,8 @@ class WindowStateAnimator {
mAnimator = service.mAnimator;
mPolicy = service.mPolicy;
mContext = service.mContext;
- mAnimDw = service.mAppDisplayWidth;
- mAnimDh = service.mAppDisplayHeight;
+ mAnimDw = service.mDisplayInfo.appWidth;
+ mAnimDh = service.mDisplayInfo.appHeight;
mWin = win;
mAttachedWinAnimator = win.mAttachedWindow == null
@@ -248,8 +248,8 @@ class WindowStateAnimator {
" scale=" + mService.mWindowAnimationScale);
mAnimation.initialize(mWin.mFrame.width(), mWin.mFrame.height(),
mAnimDw, mAnimDh);
- mAnimDw = mService.mAppDisplayWidth;
- mAnimDh = mService.mAppDisplayHeight;
+ mAnimDw = mService.mDisplayInfo.appWidth;
+ mAnimDh = mService.mDisplayInfo.appHeight;
mAnimation.setStartTime(currentTime);
mLocalAnimating = true;
mAnimating = true;
@@ -1102,7 +1102,7 @@ class WindowStateAnimator {
WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
if ((w.mAttrs.flags & LayoutParams.FLAG_DIM_BEHIND) != 0) {
mService.startDimming(this, w.mExiting ? 0 : w.mAttrs.dimAmount,
- mService.mAppDisplayWidth, mService.mAppDisplayHeight);
+ mService.mDisplayInfo.appWidth, mService.mDisplayInfo.appHeight);
}
} catch (RuntimeException e) {
// If something goes wrong with the surface (such
diff --git a/services/jni/Android.mk b/services/jni/Android.mk
index d097a93..43e59b2 100644
--- a/services/jni/Android.mk
+++ b/services/jni/Android.mk
@@ -4,6 +4,7 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES:= \
com_android_server_AlarmManagerService.cpp \
com_android_server_BatteryService.cpp \
+ com_android_server_display_SurfaceFlingerDisplayAdapter.cpp \
com_android_server_input_InputApplicationHandle.cpp \
com_android_server_input_InputManagerService.cpp \
com_android_server_input_InputWindowHandle.cpp \
diff --git a/services/jni/com_android_server_display_SurfaceFlingerDisplayAdapter.cpp b/services/jni/com_android_server_display_SurfaceFlingerDisplayAdapter.cpp
new file mode 100644
index 0000000..162cbaf
--- /dev/null
+++ b/services/jni/com_android_server_display_SurfaceFlingerDisplayAdapter.cpp
@@ -0,0 +1,94 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "SurfaceFlingerDisplayAdapter"
+
+#include "JNIHelp.h"
+#include "jni.h"
+#include <android_runtime/AndroidRuntime.h>
+
+#include <gui/SurfaceComposerClient.h>
+#include <ui/DisplayInfo.h>
+
+#include <utils/Log.h>
+
+namespace android {
+
+static struct {
+ jfieldID width;
+ jfieldID height;
+ jfieldID refreshRate;
+ jfieldID density;
+ jfieldID xDpi;
+ jfieldID yDpi;
+} gDisplayDeviceInfoClassInfo;
+
+
+static void nativeGetDefaultDisplayDeviceInfo(JNIEnv* env, jclass clazz, jobject infoObj) {
+ DisplayInfo info;
+ status_t err = SurfaceComposerClient::getDisplayInfo(0, &info);
+ if (err < 0) {
+ jniThrowExceptionFmt(env, "java/lang/RuntimeException",
+ "Could not get display info. err=%d", err);
+ return;
+ }
+
+ bool rotated = (info.orientation == DISPLAY_ORIENTATION_90
+ || info.orientation == DISPLAY_ORIENTATION_270);
+ env->SetIntField(infoObj, gDisplayDeviceInfoClassInfo.width,
+ rotated ? info.h : info.w);
+ env->SetIntField(infoObj, gDisplayDeviceInfoClassInfo.height,
+ rotated ? info.w : info.h);
+ env->SetFloatField(infoObj, gDisplayDeviceInfoClassInfo.refreshRate, info.fps);
+ env->SetFloatField(infoObj, gDisplayDeviceInfoClassInfo.density, info.density);
+ env->SetFloatField(infoObj, gDisplayDeviceInfoClassInfo.xDpi, info.xdpi);
+ env->SetFloatField(infoObj, gDisplayDeviceInfoClassInfo.yDpi, info.ydpi);
+}
+
+
+static JNINativeMethod gSurfaceFlingerDisplayAdapterMethods[] = {
+ /* name, signature, funcPtr */
+ { "nativeGetDefaultDisplayDeviceInfo",
+ "(Lcom/android/server/display/DisplayDeviceInfo;)V",
+ (void*) nativeGetDefaultDisplayDeviceInfo },
+};
+
+#define FIND_CLASS(var, className) \
+ var = env->FindClass(className); \
+ LOG_FATAL_IF(! var, "Unable to find class " className);
+
+#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
+ var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
+ LOG_FATAL_IF(! var, "Unable to find field " fieldName);
+
+int register_android_server_display_SurfaceFlingerDisplayAdapter(JNIEnv* env) {
+ int res = jniRegisterNativeMethods(env,
+ "com/android/server/display/SurfaceFlingerDisplayAdapter",
+ gSurfaceFlingerDisplayAdapterMethods, NELEM(gSurfaceFlingerDisplayAdapterMethods));
+ LOG_FATAL_IF(res < 0, "Unable to register native methods.");
+
+ jclass clazz;
+ FIND_CLASS(clazz, "com/android/server/display/DisplayDeviceInfo");
+ GET_FIELD_ID(gDisplayDeviceInfoClassInfo.width, clazz, "width", "I");
+ GET_FIELD_ID(gDisplayDeviceInfoClassInfo.height, clazz, "height", "I");
+ GET_FIELD_ID(gDisplayDeviceInfoClassInfo.refreshRate, clazz, "refreshRate", "F");
+ GET_FIELD_ID(gDisplayDeviceInfoClassInfo.density, clazz, "density", "F");
+ GET_FIELD_ID(gDisplayDeviceInfoClassInfo.xDpi, clazz, "xDpi", "F");
+ GET_FIELD_ID(gDisplayDeviceInfoClassInfo.yDpi, clazz, "yDpi", "F");
+ return 0;
+}
+
+} /* namespace android */
diff --git a/services/jni/onload.cpp b/services/jni/onload.cpp
index 423ebd1..50873fc 100644
--- a/services/jni/onload.cpp
+++ b/services/jni/onload.cpp
@@ -22,6 +22,7 @@
namespace android {
int register_android_server_AlarmManagerService(JNIEnv* env);
int register_android_server_BatteryService(JNIEnv* env);
+int register_android_server_display_SurfaceFlingerDisplayAdapter(JNIEnv* env);
int register_android_server_InputApplicationHandle(JNIEnv* env);
int register_android_server_InputWindowHandle(JNIEnv* env);
int register_android_server_InputManager(JNIEnv* env);
@@ -51,6 +52,7 @@ extern "C" jint JNI_OnLoad(JavaVM* vm, void* reserved)
register_android_server_PowerManagerService(env);
register_android_server_SerialService(env);
+ register_android_server_display_SurfaceFlingerDisplayAdapter(env);
register_android_server_InputApplicationHandle(env);
register_android_server_InputWindowHandle(env);
register_android_server_InputManager(env);
diff --git a/tools/layoutlib/bridge/src/android/view/Display_Delegate.java b/tools/layoutlib/bridge/src/android/view/Display_Delegate.java
index 8868c65..6ccdcb6 100644
--- a/tools/layoutlib/bridge/src/android/view/Display_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/view/Display_Delegate.java
@@ -31,57 +31,4 @@ import android.os.RemoteException;
*/
public class Display_Delegate {
- // ---- Overridden methods ----
-
- @LayoutlibDelegate
- public static IWindowManager getWindowManager() {
- return RenderAction.getCurrentContext().getIWindowManager();
- }
-
- // ---- Native methods ----
-
- @LayoutlibDelegate
- /*package*/ static int getDisplayCount() {
- return 1;
- }
-
- @LayoutlibDelegate
- /** @hide special for when we are faking the screen size. */
- /*package*/ static int getRawWidthNative(Display theDisplay) {
- // same as real since we're not faking compatibility mode.
- return RenderAction.getCurrentContext().getIWindowManager().getMetrics().widthPixels;
- }
-
- @LayoutlibDelegate
- /** @hide special for when we are faking the screen size. */
- /*package*/ static int getRawHeightNative(Display theDisplay) {
- // same as real since we're not faking compatibility mode.
- return RenderAction.getCurrentContext().getIWindowManager().getMetrics().heightPixels;
- }
-
- @LayoutlibDelegate
- /*package*/ static int getOrientation(Display theDisplay) {
- try {
- // always dynamically query for the current window manager
- return getWindowManager().getRotation();
- } catch (RemoteException e) {
- // this will never been thrown since this is not a true RPC.
- }
-
- return Surface.ROTATION_0;
- }
-
- @LayoutlibDelegate
- /*package*/ static void nativeClassInit() {
- // not needed for now.
- }
-
- @LayoutlibDelegate
- /*package*/ static void init(Display theDisplay, int display) {
- // always dynamically query for the current window manager
- BridgeWindowManager wm = RenderAction.getCurrentContext().getIWindowManager();
- theDisplay.mDensity = wm.getMetrics().density;
- theDisplay.mDpiX = wm.getMetrics().xdpi;
- theDisplay.mDpiY = wm.getMetrics().ydpi;
- }
}
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
index 3e56b60..2acccd3 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/android/BridgeWindowManager.java
@@ -29,6 +29,7 @@ import android.os.IRemoteCallback;
import android.os.RemoteException;
import android.util.DisplayMetrics;
import android.view.Display;
+import android.view.DisplayInfo;
import android.view.Display_Delegate;
import android.view.Gravity;
import android.view.IApplicationToken;
@@ -70,20 +71,14 @@ public class BridgeWindowManager implements IWindowManager {
}
@Override
- public int getMaximumSizeDimension() throws RemoteException {
- return 0;
- }
-
- @Override
- public void getCurrentSizeRange(Point smallestSize, Point largestSize) {
- }
-
- @Override
- public void getDisplaySize(Point arg0) throws RemoteException {
- }
-
- @Override
- public void getRealDisplaySize(Point arg0) throws RemoteException {
+ public void getDisplayInfo(int arg0, DisplayInfo arg1) throws RemoteException {
+ arg1.appWidth = mMetrics.widthPixels;
+ arg1.appHeight = mMetrics.heightPixels;
+ arg1.logicalWidth = mMetrics.widthPixels;
+ arg1.logicalHeight = mMetrics.heightPixels;
+ arg1.logicalDensity = mMetrics.density;
+ arg1.physicalXDpi = mMetrics.xdpi;
+ arg1.physicalYDpi = mMetrics.ydpi;
}
// ---- unused implementation of IWindowManager ----