Make display manager tell input system about viewports.

The window manager is no longer responsible for telling the
input system about the display viewport.

Change-Id: I932882bae55decef55f25093bb2a7ebac1620bb1
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index 6d63998..513dc13 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -203,34 +203,18 @@
 
 // --- InputReaderConfiguration ---
 
-bool InputReaderConfiguration::getDisplayInfo(int32_t displayId, bool external,
-        int32_t* width, int32_t* height, int32_t* orientation) const {
-    if (displayId == 0) {
-        const DisplayInfo& info = external ? mExternalDisplay : mInternalDisplay;
-        if (info.width > 0 && info.height > 0) {
-            if (width) {
-                *width = info.width;
-            }
-            if (height) {
-                *height = info.height;
-            }
-            if (orientation) {
-                *orientation = info.orientation;
-            }
-            return true;
-        }
+bool InputReaderConfiguration::getDisplayInfo(bool external, DisplayViewport* outViewport) const {
+    const DisplayViewport& viewport = external ? mExternalDisplay : mInternalDisplay;
+    if (viewport.displayId >= 0) {
+        *outViewport = viewport;
+        return true;
     }
     return false;
 }
 
-void InputReaderConfiguration::setDisplayInfo(int32_t displayId, bool external,
-        int32_t width, int32_t height, int32_t orientation) {
-    if (displayId == 0) {
-        DisplayInfo& info = external ? mExternalDisplay : mInternalDisplay;
-        info.width = width;
-        info.height = height;
-        info.orientation = orientation;
-    }
+void InputReaderConfiguration::setDisplayInfo(bool external, const DisplayViewport& viewport) {
+    DisplayViewport& v = external ? mExternalDisplay : mInternalDisplay;
+    v = viewport;
 }
 
 
@@ -2001,9 +1985,11 @@
     }
 
     if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
-        if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0) {
-            if (!config->getDisplayInfo(mParameters.associatedDisplayId,
-                        false /*external*/, NULL, NULL, &mOrientation)) {
+        if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
+            DisplayViewport v;
+            if (config->getDisplayInfo(false /*external*/, &v)) {
+                mOrientation = v.orientation;
+            } else {
                 mOrientation = DISPLAY_ORIENTATION_0;
             }
         } else {
@@ -2017,16 +2003,16 @@
     getDevice()->getConfiguration().tryGetProperty(String8("keyboard.orientationAware"),
             mParameters.orientationAware);
 
-    mParameters.associatedDisplayId = -1;
+    mParameters.hasAssociatedDisplay = false;
     if (mParameters.orientationAware) {
-        mParameters.associatedDisplayId = 0;
+        mParameters.hasAssociatedDisplay = true;
     }
 }
 
 void KeyboardInputMapper::dumpParameters(String8& dump) {
     dump.append(INDENT3 "Parameters:\n");
-    dump.appendFormat(INDENT4 "AssociatedDisplayId: %d\n",
-            mParameters.associatedDisplayId);
+    dump.appendFormat(INDENT4 "HasAssociatedDisplay: %s\n",
+            toString(mParameters.hasAssociatedDisplay));
     dump.appendFormat(INDENT4 "OrientationAware: %s\n",
             toString(mParameters.orientationAware));
 }
@@ -2086,7 +2072,7 @@
 
     if (down) {
         // Rotate key codes according to orientation if needed.
-        if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0) {
+        if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
             keyCode = rotateKeyCode(keyCode, mOrientation);
         }
 
@@ -2317,9 +2303,11 @@
     }
 
     if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) {
-        if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0) {
-            if (!config->getDisplayInfo(mParameters.associatedDisplayId,
-                        false /*external*/, NULL, NULL, &mOrientation)) {
+        if (mParameters.orientationAware && mParameters.hasAssociatedDisplay) {
+            DisplayViewport v;
+            if (config->getDisplayInfo(false /*external*/, &v)) {
+                mOrientation = v.orientation;
+            } else {
                 mOrientation = DISPLAY_ORIENTATION_0;
             }
         } else {
@@ -2344,16 +2332,16 @@
     getDevice()->getConfiguration().tryGetProperty(String8("cursor.orientationAware"),
             mParameters.orientationAware);
 
-    mParameters.associatedDisplayId = -1;
+    mParameters.hasAssociatedDisplay = false;
     if (mParameters.mode == Parameters::MODE_POINTER || mParameters.orientationAware) {
-        mParameters.associatedDisplayId = 0;
+        mParameters.hasAssociatedDisplay = true;
     }
 }
 
 void CursorInputMapper::dumpParameters(String8& dump) {
     dump.append(INDENT3 "Parameters:\n");
-    dump.appendFormat(INDENT4 "AssociatedDisplayId: %d\n",
-            mParameters.associatedDisplayId);
+    dump.appendFormat(INDENT4 "HasAssociatedDisplay: %s\n",
+            toString(mParameters.hasAssociatedDisplay));
 
     switch (mParameters.mode) {
     case Parameters::MODE_POINTER:
@@ -2420,7 +2408,7 @@
     bool moved = deltaX != 0 || deltaY != 0;
 
     // Rotate delta according to orientation if needed.
-    if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0
+    if (mParameters.orientationAware && mParameters.hasAssociatedDisplay
             && (deltaX != 0.0f || deltaY != 0.0f)) {
         rotateDelta(mOrientation, &deltaX, &deltaY);
     }
@@ -2782,15 +2770,15 @@
     getDevice()->getConfiguration().tryGetProperty(String8("touch.orientationAware"),
             mParameters.orientationAware);
 
-    mParameters.associatedDisplayId = -1;
+    mParameters.hasAssociatedDisplay = false;
     mParameters.associatedDisplayIsExternal = false;
     if (mParameters.orientationAware
             || mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
             || mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) {
+        mParameters.hasAssociatedDisplay = true;
         mParameters.associatedDisplayIsExternal =
                 mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
                         && getDevice()->isExternal();
-        mParameters.associatedDisplayId = 0;
     }
 }
 
@@ -2822,8 +2810,9 @@
         ALOG_ASSERT(false);
     }
 
-    dump.appendFormat(INDENT4 "AssociatedDisplay: id=%d, isExternal=%s\n",
-            mParameters.associatedDisplayId, toString(mParameters.associatedDisplayIsExternal));
+    dump.appendFormat(INDENT4 "AssociatedDisplay: present=%s, isExternal=%s\n",
+            toString(mParameters.hasAssociatedDisplay),
+            toString(mParameters.associatedDisplayIsExternal));
     dump.appendFormat(INDENT4 "OrientationAware: %s\n",
             toString(mParameters.orientationAware));
 }
@@ -2861,7 +2850,7 @@
             mSource |= AINPUT_SOURCE_STYLUS;
         }
     } else if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN
-            && mParameters.associatedDisplayId >= 0) {
+            && mParameters.hasAssociatedDisplay) {
         mSource = AINPUT_SOURCE_TOUCHSCREEN;
         mDeviceMode = DEVICE_MODE_DIRECT;
         if (hasStylus()) {
@@ -2881,15 +2870,13 @@
     }
 
     // Get associated display dimensions.
-    if (mParameters.associatedDisplayId >= 0) {
-        if (!mConfig.getDisplayInfo(mParameters.associatedDisplayId,
-                mParameters.associatedDisplayIsExternal,
-                &mAssociatedDisplayWidth, &mAssociatedDisplayHeight,
-                &mAssociatedDisplayOrientation)) {
+    if (mParameters.hasAssociatedDisplay) {
+        if (!mConfig.getDisplayInfo(mParameters.associatedDisplayIsExternal,
+                &mAssociatedDisplayViewport)) {
             ALOGI(INDENT "Touch device '%s' could not query the properties of its associated "
-                    "display %d.  The device will be inoperable until the display size "
+                    "display.  The device will be inoperable until the display size "
                     "becomes available.",
-                    getDeviceName().string(), mParameters.associatedDisplayId);
+                    getDeviceName().string());
             mDeviceMode = DEVICE_MODE_DISABLED;
             return;
         }
@@ -2898,10 +2885,16 @@
     // Configure dimensions.
     int32_t width, height, orientation;
     if (mDeviceMode == DEVICE_MODE_DIRECT || mDeviceMode == DEVICE_MODE_POINTER) {
-        width = mAssociatedDisplayWidth;
-        height = mAssociatedDisplayHeight;
+        width = mAssociatedDisplayViewport.logicalRight - mAssociatedDisplayViewport.logicalLeft;
+        height = mAssociatedDisplayViewport.logicalBottom - mAssociatedDisplayViewport.logicalTop;
+        if (mAssociatedDisplayViewport.orientation == DISPLAY_ORIENTATION_90
+                || mAssociatedDisplayViewport.orientation == DISPLAY_ORIENTATION_270) {
+            int32_t temp = height;
+            height = width;
+            width = temp;
+        }
         orientation = mParameters.orientationAware ?
-                mAssociatedDisplayOrientation : DISPLAY_ORIENTATION_0;
+                mAssociatedDisplayViewport.orientation : DISPLAY_ORIENTATION_0;
     } else {
         width = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
         height = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
@@ -3163,8 +3156,7 @@
             int32_t rawWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
             int32_t rawHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
             float rawDiagonal = hypotf(rawWidth, rawHeight);
-            float displayDiagonal = hypotf(mAssociatedDisplayWidth,
-                    mAssociatedDisplayHeight);
+            float displayDiagonal = hypotf(width, height);
 
             // Scale movements such that one whole swipe of the touch pad covers a
             // given area relative to the diagonal size of the display when no acceleration
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index 6c06986..e345a5fb 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -24,7 +24,6 @@
 #include <androidfw/Input.h>
 #include <androidfw/VelocityControl.h>
 #include <androidfw/VelocityTracker.h>
-#include <ui/DisplayInfo.h>
 #include <utils/KeyedVector.h>
 #include <utils/threads.h>
 #include <utils/Timers.h>
@@ -48,6 +47,45 @@
 class InputDevice;
 class InputMapper;
 
+/*
+ * Describes how coordinates are mapped on a physical display.
+ * See com.android.server.display.DisplayViewport.
+ */
+struct DisplayViewport {
+    int32_t displayId; // -1 if invalid
+    int32_t orientation;
+    int32_t logicalLeft;
+    int32_t logicalTop;
+    int32_t logicalRight;
+    int32_t logicalBottom;
+    int32_t physicalLeft;
+    int32_t physicalTop;
+    int32_t physicalRight;
+    int32_t physicalBottom;
+
+    DisplayViewport() :
+            displayId(-1), orientation(DISPLAY_ORIENTATION_0),
+            logicalLeft(0), logicalTop(0), logicalRight(0), logicalBottom(0),
+            physicalLeft(0), physicalTop(0), physicalRight(0), physicalBottom(0) {
+    }
+
+    bool operator==(const DisplayViewport& other) const {
+        return displayId == other.displayId
+                && orientation == other.orientation
+                && logicalLeft == other.logicalLeft
+                && logicalTop == other.logicalTop
+                && logicalRight == other.logicalRight
+                && logicalBottom == other.logicalBottom
+                && physicalLeft == other.physicalLeft
+                && physicalTop == other.physicalTop
+                && physicalRight == other.physicalRight
+                && physicalBottom == other.physicalBottom;
+    }
+
+    bool operator!=(const DisplayViewport& other) const {
+        return !(*this == other);
+    }
+};
 
 /*
  * Input reader configuration.
@@ -180,25 +218,12 @@
             pointerGestureZoomSpeedRatio(0.3f),
             showTouches(false) { }
 
-    bool getDisplayInfo(int32_t displayId, bool external,
-            int32_t* width, int32_t* height, int32_t* orientation) const;
-
-    void setDisplayInfo(int32_t displayId, bool external,
-            int32_t width, int32_t height, int32_t orientation);
+    bool getDisplayInfo(bool external, DisplayViewport* outViewport) const;
+    void setDisplayInfo(bool external, const DisplayViewport& viewport);
 
 private:
-    struct DisplayInfo {
-        int32_t width;
-        int32_t height;
-        int32_t orientation;
-
-        DisplayInfo() :
-            width(-1), height(-1), orientation(DISPLAY_ORIENTATION_0) {
-        }
-    };
-
-    DisplayInfo mInternalDisplay;
-    DisplayInfo mExternalDisplay;
+    DisplayViewport mInternalDisplay;
+    DisplayViewport mExternalDisplay;
 };
 
 
@@ -992,7 +1017,7 @@
 
     // Immutable configuration parameters.
     struct Parameters {
-        int32_t associatedDisplayId;
+        bool hasAssociatedDisplay;
         bool orientationAware;
     } mParameters;
 
@@ -1042,7 +1067,7 @@
         };
 
         Mode mode;
-        int32_t associatedDisplayId;
+        bool hasAssociatedDisplay;
         bool orientationAware;
     } mParameters;
 
@@ -1143,7 +1168,7 @@
         };
 
         DeviceType deviceType;
-        int32_t associatedDisplayId;
+        bool hasAssociatedDisplay;
         bool associatedDisplayIsExternal;
         bool orientationAware;
 
@@ -1277,10 +1302,8 @@
     int32_t mSurfaceWidth;
     int32_t mSurfaceHeight;
 
-    // The associated display orientation and width and height set by configureSurface().
-    int32_t mAssociatedDisplayOrientation;
-    int32_t mAssociatedDisplayWidth;
-    int32_t mAssociatedDisplayHeight;
+    // The associated display viewport set by configureSurface().
+    DisplayViewport mAssociatedDisplayViewport;
 
     // Translation and scaling factors, orientation-independent.
     float mXScale;
diff --git a/services/input/PointerController.cpp b/services/input/PointerController.cpp
index fc828a6..9af521b 100644
--- a/services/input/PointerController.cpp
+++ b/services/input/PointerController.cpp
@@ -307,9 +307,17 @@
     }
 }
 
-void PointerController::setDisplaySize(int32_t width, int32_t height) {
+void PointerController::setDisplayViewport(int32_t width, int32_t height, int32_t orientation) {
     AutoMutex _l(mLock);
 
+    // Adjust to use the display's unrotated coordinate frame.
+    if (orientation == DISPLAY_ORIENTATION_90
+            || orientation == DISPLAY_ORIENTATION_270) {
+        int32_t temp = height;
+        height = width;
+        width = temp;
+    }
+
     if (mLocked.displayWidth != width || mLocked.displayHeight != height) {
         mLocked.displayWidth = width;
         mLocked.displayHeight = height;
@@ -324,12 +332,7 @@
         }
 
         fadeOutAndReleaseAllSpotsLocked();
-        updatePointerLocked();
     }
-}
-
-void PointerController::setDisplayOrientation(int32_t orientation) {
-    AutoMutex _l(mLock);
 
     if (mLocked.displayOrientation != orientation) {
         // Apply offsets to convert from the pixel top-left corner position to the pixel center.
@@ -380,9 +383,9 @@
         mLocked.pointerX = x - 0.5f;
         mLocked.pointerY = y - 0.5f;
         mLocked.displayOrientation = orientation;
-
-        updatePointerLocked();
     }
+
+    updatePointerLocked();
 }
 
 void PointerController::setPointerIcon(const SpriteIcon& icon) {
diff --git a/services/input/PointerController.h b/services/input/PointerController.h
index 4c307c4..fd68b61 100644
--- a/services/input/PointerController.h
+++ b/services/input/PointerController.h
@@ -170,8 +170,7 @@
             const uint32_t* spotIdToIndex, BitSet32 spotIdBits);
     virtual void clearSpots();
 
-    void setDisplaySize(int32_t width, int32_t height);
-    void setDisplayOrientation(int32_t orientation);
+    void setDisplayViewport(int32_t width, int32_t height, int32_t orientation);
     void setPointerIcon(const SpriteIcon& icon);
     void setInactivityTimeout(InactivityTimeout inactivityTimeout);
 
diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp
index abda10b..03516af 100644
--- a/services/input/tests/InputReader_test.cpp
+++ b/services/input/tests/InputReader_test.cpp
@@ -138,8 +138,21 @@
 
     void setDisplayInfo(int32_t displayId, int32_t width, int32_t height, int32_t orientation) {
         // Set the size of both the internal and external display at the same time.
-        mConfig.setDisplayInfo(displayId, false /*external*/, width, height, orientation);
-        mConfig.setDisplayInfo(displayId, true /*external*/, width, height, orientation);
+        bool isRotated = (orientation == DISPLAY_ORIENTATION_90
+                || orientation == DISPLAY_ORIENTATION_270);
+        DisplayViewport v;
+        v.displayId = displayId;
+        v.orientation = orientation;
+        v.logicalLeft = 0;
+        v.logicalTop = 0;
+        v.logicalRight = isRotated ? height : width;
+        v.logicalBottom = isRotated ? width : height;
+        v.physicalLeft = 0;
+        v.physicalTop = 0;
+        v.physicalRight = isRotated ? height : width;
+        v.physicalBottom = isRotated ? width : height;
+        mConfig.setDisplayInfo(false /*external*/, v);
+        mConfig.setDisplayInfo(true /*external*/, v);
     }
 
     void addExcludedDeviceName(const String8& deviceName) {