Rework display size access.

Applications now get the display size from the window manager.  No
behavior should be changed yet, this is just prep for some real
changes.

Change-Id: I2958a6660895c1cba2b670509600014e55ee9273
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 389d4856..f5849c2 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -818,18 +818,6 @@
         return mWindow != null ? mWindow.getCurrentFocus() : null;
     }
 
-    @Override
-    public int getWallpaperDesiredMinimumWidth() {
-        int width = super.getWallpaperDesiredMinimumWidth();
-        return width <= 0 ? getWindowManager().getDefaultDisplay().getWidth() : width;
-    }
-
-    @Override
-    public int getWallpaperDesiredMinimumHeight() {
-        int height = super.getWallpaperDesiredMinimumHeight();
-        return height <= 0 ? getWindowManager().getDefaultDisplay().getHeight() : height;
-    }
-
     /**
      * Called when the activity is starting.  This is where most initialization
      * should go: calling {@link #setContentView(int)} to inflate the
diff --git a/core/java/android/app/backup/WallpaperBackupHelper.java b/core/java/android/app/backup/WallpaperBackupHelper.java
index 55368d6..0c034cf 100644
--- a/core/java/android/app/backup/WallpaperBackupHelper.java
+++ b/core/java/android/app/backup/WallpaperBackupHelper.java
@@ -19,6 +19,7 @@
 import android.app.WallpaperManager;
 import android.content.Context;
 import android.graphics.BitmapFactory;
+import android.graphics.Point;
 import android.os.ParcelFileDescriptor;
 import android.util.Slog;
 import android.view.Display;
@@ -70,8 +71,10 @@
         if (mDesiredMinWidth <= 0 || mDesiredMinHeight <= 0) {
             WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
             Display d = wm.getDefaultDisplay();
-            mDesiredMinWidth = d.getWidth();
-            mDesiredMinHeight = d.getHeight();
+            Point size = new Point();
+            d.getSize(size);
+            mDesiredMinWidth = size.x;
+            mDesiredMinHeight = size.y;
         }
 
         if (DEBUG) {
diff --git a/core/java/android/view/Display.java b/core/java/android/view/Display.java
index 126f409..980239b 100644
--- a/core/java/android/view/Display.java
+++ b/core/java/android/view/Display.java
@@ -16,10 +16,15 @@
 
 package android.view;
 
+import android.graphics.Point;
+import android.graphics.Rect;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
 import android.util.DisplayMetrics;
+import android.util.Slog;
 
-public class Display
-{
+public class Display {
     /**
      * Specify the default Display
      */
@@ -35,10 +40,10 @@
     Display(int display) {
         // initalize the statics when this class is first instansiated. This is
         // done here instead of in the static block because Zygote
-        synchronized (mStaticInit) {
-            if (!mInitialized) {
+        synchronized (sStaticInit) {
+            if (!sInitialized) {
                 nativeClassInit();
-                mInitialized = true;
+                sInitialized = true;
             }
         }
         mDisplay = display;
@@ -60,29 +65,92 @@
     native static int getDisplayCount();
     
     /**
-     * Returns the raw width of the display, in pixels.  Note that this
+     * Returns the raw size of the display, in pixels.  Note that this
      * should <em>not</em> generally be used for computing layouts, since
      * a device will typically have screen decoration (such as a status bar)
      * along the edges of the display that reduce the amount of application
      * space available from the raw size returned here.  This value is
      * adjusted for you based on the current rotation of the display.
      */
-    native public int getWidth();
+    public void getSize(Point outSize) {
+        try {
+            IWindowManager wm = getWindowManager();
+            if (wm != null) {
+                wm.getDisplaySize(outSize);
+            } else {
+                // This is just for boot-strapping, initializing the
+                // system process before the window manager is up.
+                outSize.y = getRealHeight();
+            }
+        } catch (RemoteException e) {
+            Slog.w("Display", "Unable to get display size", e);
+        }
+    }
     
     /**
-     * Returns the raw height of the display, in pixels.  Note that this
-     * should <em>not</em> generally be used for computing layouts, since
-     * a device will typically have screen decoration (such as a status bar)
-     * along the edges of the display that reduce the amount of application
-     * space available from the raw size returned here.  This value is
-     * adjusted for you based on the current rotation of the display.
+     * This is just easier for some parts of the framework.
      */
-    native public int getHeight();
+    public void getRectSize(Rect outSize) {
+        synchronized (mTmpPoint) {
+            getSize(mTmpPoint);
+            outSize.set(0, 0, mTmpPoint.x, mTmpPoint.y);
+        }
+    }
+
+    /**
+     * Return the maximum screen size dimension that will happen.  This is
+     * mostly for wallpapers.
+     * @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;
+        }
+    }
+
+    /**
+     * @deprecated Use {@link #getSize(Point)} instead.
+     */
+    @Deprecated
+    public int getWidth() {
+        synchronized (mTmpPoint) {
+            long now = SystemClock.uptimeMillis();
+            if (now > (mLastGetTime+20)) {
+                getSize(mTmpPoint);
+                mLastGetTime = now;
+            }
+            return mTmpPoint.x;
+        }
+    }
+
+    /**
+     * @deprecated Use {@link #getSize(Point)} instead.
+     */
+    @Deprecated
+    public int getHeight() {
+        synchronized (mTmpPoint) {
+            long now = SystemClock.uptimeMillis();
+            if (now > (mLastGetTime+20)) {
+                getSize(mTmpPoint);
+                mLastGetTime = now;
+            }
+            return mTmpPoint.y;
+        }
+    }
+
+    /** @hide Returns the actual screen size, not including any decor. */
+    native public int getRealWidth();
+    /** @hide Returns the actual screen size, not including any decor. */
+    native public int getRealHeight();
 
     /** @hide special for when we are faking the screen size. */
-    native public int getRealWidth();
+    native public int getRawWidth();
     /** @hide special for when we are faking the screen size. */
-    native public int getRealHeight();
+    native public int getRawHeight();
     
     /**
      * Returns the rotation of the screen from its "natural" orientation.
@@ -141,6 +209,16 @@
         outMetrics.ydpi         = mDpiY;
     }
 
+    static IWindowManager getWindowManager() {
+        synchronized (sStaticInit) {
+            if (sWindowManager == null) {
+                sWindowManager = IWindowManager.Stub.asInterface(
+                        ServiceManager.getService("window"));
+            }
+            return sWindowManager;
+        }
+    }
+
     /*
      * We use a class initializer to allow the native code to cache some
      * field offsets.
@@ -157,8 +235,12 @@
     private float       mDpiX;
     private float       mDpiY;
     
-    private static final Object mStaticInit = new Object();
-    private static boolean mInitialized = false;
+    private final Point mTmpPoint = new Point();
+    private float mLastGetTime;
+
+    private static final Object sStaticInit = new Object();
+    private static boolean sInitialized = false;
+    private static IWindowManager sWindowManager;
 
     /**
      * Returns a display object which uses the metric's width/height instead.
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index dd8242a..0be02a6 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -21,6 +21,7 @@
 
 import android.content.res.Configuration;
 import android.graphics.Bitmap;
+import android.graphics.Point;
 import android.view.IApplicationToken;
 import android.view.IOnKeyguardExitResult;
 import android.view.IRotationWatcher;
@@ -52,6 +53,9 @@
             in IInputContext inputContext);
     boolean inputMethodClientHasFocus(IInputMethodClient client);
     
+    void getDisplaySize(out Point size);
+    int getMaximumSizeDimension();
+
     // These can only be called when injecting events to your own window,
     // or by holding the INJECT_EVENTS permission.  These methods may block
     // until pending input events are finished being dispatched even when 'sync' is false.
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index 98d4eb9..8cb68f9 100755
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -290,7 +290,7 @@
      * @return The input device or null if not found.
      */
     public static InputDevice getDevice(int id) {
-        IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
+        IWindowManager wm = Display.getWindowManager();
         try {
             return wm.getInputDevice(id);
         } catch (RemoteException ex) {
@@ -304,7 +304,7 @@
      * @return The input device ids.
      */
     public static int[] getDeviceIds() {
-        IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
+        IWindowManager wm = Display.getWindowManager();
         try {
             return wm.getInputDeviceIds();
         } catch (RemoteException ex) {
diff --git a/core/java/android/view/KeyCharacterMap.java b/core/java/android/view/KeyCharacterMap.java
index 3ff7fcd..885a75f 100644
--- a/core/java/android/view/KeyCharacterMap.java
+++ b/core/java/android/view/KeyCharacterMap.java
@@ -527,7 +527,7 @@
      */
     public static boolean[] deviceHasKeys(int[] keyCodes) {
         boolean[] ret = new boolean[keyCodes.length];
-        IWindowManager wm = IWindowManager.Stub.asInterface(ServiceManager.getService("window"));
+        IWindowManager wm = Display.getWindowManager();
         try {
             wm.hasKeys(keyCodes, ret);
         } catch (RemoteException e) {
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index fe8af19..4a62892 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -4992,7 +4992,7 @@
             return;
         }
         Display d = WindowManagerImpl.getDefault().getDefaultDisplay();
-        outRect.set(0, 0, d.getWidth(), d.getHeight());
+        d.getRectSize(outRect);
     }
 
     /**
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 1a6bae7..4104b07 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -263,9 +263,8 @@
             if (!mInitialized) {
                 try {
                     InputMethodManager imm = InputMethodManager.getInstance(mainLooper);
-                    sWindowSession = IWindowManager.Stub.asInterface(
-                            ServiceManager.getService("window"))
-                            .openSession(imm.getClient(), imm.getInputContext());
+                    sWindowSession = Display.getWindowManager().openSession(
+                            imm.getClient(), imm.getInputContext());
                     mInitialized = true;
                 } catch (RemoteException e) {
                 }
diff --git a/core/jni/android_view_Display.cpp b/core/jni/android_view_Display.cpp
index 8feeb9a..97f9fc34 100644
--- a/core/jni/android_view_Display.cpp
+++ b/core/jni/android_view_Display.cpp
@@ -92,14 +92,14 @@
     return h == gOldSize ? gNewSize : h;
 }
 
-static jint android_view_Display_getRealWidth(
+static jint android_view_Display_getRawWidth(
         JNIEnv* env, jobject clazz)
 {
     DisplayID dpy = env->GetIntField(clazz, offsets.display);
     return SurfaceComposerClient::getDisplayWidth(dpy);
 }
 
-static jint android_view_Display_getRealHeight(
+static jint android_view_Display_getRawHeight(
         JNIEnv* env, jobject clazz)
 {
     DisplayID dpy = env->GetIntField(clazz, offsets.display);
@@ -132,14 +132,14 @@
             (void*)android_view_Display_getDisplayCount },
 	{   "init", "(I)V",
             (void*)android_view_Display_init },
-    {   "getWidth", "()I",
-            (void*)android_view_Display_getWidth },
-    {   "getHeight", "()I",
-            (void*)android_view_Display_getHeight },
     {   "getRealWidth", "()I",
-            (void*)android_view_Display_getRealWidth },
+            (void*)android_view_Display_getWidth },
     {   "getRealHeight", "()I",
-            (void*)android_view_Display_getRealHeight },
+            (void*)android_view_Display_getHeight },
+    {   "getRawWidth", "()I",
+            (void*)android_view_Display_getRawWidth },
+    {   "getRawHeight", "()I",
+            (void*)android_view_Display_getRawHeight },
     {   "getOrientation", "()I",
             (void*)android_view_Display_getOrientation }
 };