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) {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 1aad9b3..c28afb2 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -304,6 +304,7 @@
ActivityManagerService.self().setWindowManager(wm);
display.setWindowManager(wm);
+ display.setInputManager(inputManager);
// Skip Bluetooth if we have an emulator kernel
// TODO: Use a more reliable check to see if this product should
diff --git a/services/java/com/android/server/display/DisplayDevice.java b/services/java/com/android/server/display/DisplayDevice.java
index 995c553..8eeefb4 100644
--- a/services/java/com/android/server/display/DisplayDevice.java
+++ b/services/java/com/android/server/display/DisplayDevice.java
@@ -132,14 +132,17 @@
|| mCurrentDisplayRect == null
|| !mCurrentDisplayRect.equals(displayRect)) {
mCurrentOrientation = orientation;
+
if (mCurrentLayerStackRect == null) {
mCurrentLayerStackRect = new Rect();
}
mCurrentLayerStackRect.set(layerStackRect);
+
if (mCurrentDisplayRect == null) {
mCurrentDisplayRect = new Rect();
}
mCurrentDisplayRect.set(displayRect);
+
Surface.setDisplayProjection(mDisplayToken,
orientation, layerStackRect, displayRect);
}
@@ -156,6 +159,26 @@
}
/**
+ * Populates the specified viewport object with orientation,
+ * physical and logical rects based on the display's current projection.
+ */
+ public final void populateViewportLocked(DisplayViewport viewport) {
+ viewport.orientation = mCurrentOrientation;
+
+ if (mCurrentLayerStackRect != null) {
+ viewport.logicalFrame.set(mCurrentLayerStackRect);
+ } else {
+ viewport.logicalFrame.setEmpty();
+ }
+
+ if (mCurrentDisplayRect != null) {
+ viewport.physicalFrame.set(mCurrentDisplayRect);
+ } else {
+ viewport.physicalFrame.setEmpty();
+ }
+ }
+
+ /**
* Dumps the local state of the display device.
* Does not need to dump the display device info because that is already dumped elsewhere.
*/
diff --git a/services/java/com/android/server/display/DisplayDeviceInfo.java b/services/java/com/android/server/display/DisplayDeviceInfo.java
index c90a1c6..7c57694 100644
--- a/services/java/com/android/server/display/DisplayDeviceInfo.java
+++ b/services/java/com/android/server/display/DisplayDeviceInfo.java
@@ -43,6 +43,21 @@
public static final int FLAG_SUPPORTS_ROTATION = 1 << 2;
/**
+ * Touch attachment: Display does not receive touch.
+ */
+ public static final int TOUCH_NONE = 0;
+
+ /**
+ * Touch attachment: Touch input is via the internal interface.
+ */
+ public static final int TOUCH_INTERNAL = 1;
+
+ /**
+ * Touch attachment: Touch input is via an external interface, such as USB.
+ */
+ public static final int TOUCH_EXTERNAL = 2;
+
+ /**
* Gets the name of the display device, which may be derived from
* EDID or other sources. The name may be displayed to the user.
*/
@@ -90,6 +105,11 @@
*/
public int flags;
+ /**
+ * The touch attachment, per {@link DisplayViewport#touch}.
+ */
+ public int touch;
+
public void setAssumedDensityForExternalDisplay(int width, int height) {
densityDpi = Math.min(width, height) * DisplayMetrics.DENSITY_XHIGH / 1080;
// Technically, these values should be smaller than the apparent density
@@ -112,7 +132,8 @@
&& densityDpi == other.densityDpi
&& xDpi == other.xDpi
&& yDpi == other.yDpi
- && flags == other.flags;
+ && flags == other.flags
+ && touch == other.touch;
}
@Override
@@ -129,6 +150,7 @@
xDpi = other.xDpi;
yDpi = other.yDpi;
flags = other.flags;
+ touch = other.touch;
}
// For debugging purposes
@@ -136,7 +158,20 @@
public String toString() {
return "DisplayDeviceInfo{\"" + name + "\": " + width + " x " + height + ", " + refreshRate + " fps, "
+ "density " + densityDpi + ", " + xDpi + " x " + yDpi + " dpi"
- + flagsToString(flags) + "}";
+ + ", touch " + touchToString(touch) + flagsToString(flags) + "}";
+ }
+
+ private static String touchToString(int touch) {
+ switch (touch) {
+ case TOUCH_NONE:
+ return "NONE";
+ case TOUCH_INTERNAL:
+ return "INTERNAL";
+ case TOUCH_EXTERNAL:
+ return "EXTERNAL";
+ default:
+ return Integer.toString(touch);
+ }
}
private static String flagsToString(int flags) {
diff --git a/services/java/com/android/server/display/DisplayManagerService.java b/services/java/com/android/server/display/DisplayManagerService.java
index 41a0c09..e11d454 100644
--- a/services/java/com/android/server/display/DisplayManagerService.java
+++ b/services/java/com/android/server/display/DisplayManagerService.java
@@ -96,6 +96,7 @@
private static final int MSG_REGISTER_ADDITIONAL_DISPLAY_ADAPTERS = 2;
private static final int MSG_DELIVER_DISPLAY_EVENT = 3;
private static final int MSG_REQUEST_TRAVERSAL = 4;
+ private static final int MSG_UPDATE_VIEWPORT = 5;
private final Context mContext;
private final boolean mHeadless;
@@ -103,6 +104,7 @@
private final Handler mUiHandler;
private final DisplayAdapterListener mDisplayAdapterListener;
private WindowManagerFuncs mWindowManagerFuncs;
+ private InputManagerFuncs mInputManagerFuncs;
// The synchronization root for the display manager.
// This lock guards most of the display manager's state.
@@ -141,6 +143,11 @@
// The Wifi display adapter, or null if not registered.
private WifiDisplayAdapter mWifiDisplayAdapter;
+ // Viewports of the default display and the display that should receive touch
+ // input from an external source. Used by the input system.
+ private final DisplayViewport mDefaultViewport = new DisplayViewport();
+ private final DisplayViewport mExternalTouchViewport = new DisplayViewport();
+
// Temporary callback list, used when sending display events to applications.
// May be used outside of the lock but only on the handler thread.
private final ArrayList<CallbackRecord> mTempCallbacks = new ArrayList<CallbackRecord>();
@@ -148,6 +155,11 @@
// Temporary display info, used for comparing display configurations.
private final DisplayInfo mTempDisplayInfo = new DisplayInfo();
+ // Temporary viewports, used when sending new viewport information to the
+ // input system. May be used outside of the lock but only on the handler thread.
+ private final DisplayViewport mTempDefaultViewport = new DisplayViewport();
+ private final DisplayViewport mTempExternalTouchViewport = new DisplayViewport();
+
public DisplayManagerService(Context context, Handler mainHandler, Handler uiHandler) {
mContext = context;
mHeadless = SystemProperties.get(SYSTEM_HEADLESS).equals("1");
@@ -183,7 +195,7 @@
}
/**
- * Called during initialization to associated the display manager with the
+ * Called during initialization to associate the display manager with the
* window manager.
*/
public void setWindowManager(WindowManagerFuncs windowManagerFuncs) {
@@ -194,6 +206,17 @@
}
/**
+ * Called during initialization to associate the display manager with the
+ * input manager.
+ */
+ public void setInputManager(InputManagerFuncs inputManagerFuncs) {
+ synchronized (mSyncRoot) {
+ mInputManagerFuncs = inputManagerFuncs;
+ scheduleTraversalLocked();
+ }
+ }
+
+ /**
* Called when the system is ready to go.
*/
public void systemReady(boolean safeMode, boolean onlyCore) {
@@ -487,7 +510,7 @@
final int displayId = assignDisplayIdLocked(isDefault);
final int layerStack = assignLayerStackLocked(displayId);
- LogicalDisplay display = new LogicalDisplay(layerStack, device);
+ LogicalDisplay display = new LogicalDisplay(displayId, layerStack, device);
display.updateLocked(mDisplayDevices);
if (!display.isValidLocked()) {
// This should never happen currently.
@@ -548,6 +571,10 @@
}
mRemovedDisplayDevices.clear();
+ // Clear all viewports before configuring displays so that we can keep
+ // track of which ones we have configured.
+ clearViewportsLocked();
+
// Configure each display device.
final int count = mDisplayDevices.size();
for (int i = 0; i < count; i++) {
@@ -555,6 +582,11 @@
configureDisplayInTransactionLocked(device);
device.performTraversalInTransactionLocked();
}
+
+ // Tell the input system about these new viewports.
+ if (mInputManagerFuncs != null) {
+ mHandler.sendEmptyMessage(MSG_UPDATE_VIEWPORT);
+ }
}
/**
@@ -577,7 +609,11 @@
scheduleTraversalLocked();
}
}
+ }
+ private void clearViewportsLocked() {
+ mDefaultViewport.valid = false;
+ mExternalTouchViewport.valid = false;
}
private void configureDisplayInTransactionLocked(DisplayDevice device) {
@@ -593,11 +629,30 @@
// Apply the logical display configuration to the display device.
if (display == null) {
// TODO: no logical display for the device, blank it
- Slog.d(TAG, "Missing logical display to use for physical display device: "
+ Slog.w(TAG, "Missing logical display to use for physical display device: "
+ device.getDisplayDeviceInfoLocked());
+ return;
} else {
display.configureDisplayInTransactionLocked(device);
}
+
+ // Update the viewports if needed.
+ DisplayDeviceInfo info = device.getDisplayDeviceInfoLocked();
+ if (!mDefaultViewport.valid
+ && (info.flags & DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY) != 0) {
+ setViewportLocked(mDefaultViewport, display, device);
+ }
+ if (!mExternalTouchViewport.valid
+ && info.touch == DisplayDeviceInfo.TOUCH_EXTERNAL) {
+ setViewportLocked(mExternalTouchViewport, display, device);
+ }
+ }
+
+ private static void setViewportLocked(DisplayViewport viewport,
+ LogicalDisplay display, DisplayDevice device) {
+ viewport.valid = true;
+ viewport.displayId = display.getDisplayIdLocked();
+ device.populateViewportLocked(viewport);
}
private LogicalDisplay findLogicalDisplayForDeviceLocked(DisplayDevice device) {
@@ -690,6 +745,10 @@
pw.println(" Display " + displayId + ":");
display.dumpLocked(ipw);
}
+
+ pw.println();
+ pw.println("Default viewport: " + mDefaultViewport);
+ pw.println("External touch viewport: " + mExternalTouchViewport);
}
}
@@ -714,6 +773,18 @@
void requestTraversal();
}
+ /**
+ * Private interface to the input manager.
+ */
+ public interface InputManagerFuncs {
+ /**
+ * Sets information about the displays as needed by the input system.
+ * The input system should copy this information if required.
+ */
+ void setDisplayViewports(DisplayViewport defaultViewport,
+ DisplayViewport externalTouchViewport);
+ }
+
private final class DisplayManagerHandler extends Handler {
public DisplayManagerHandler(Looper looper) {
super(looper, null, true /*async*/);
@@ -737,6 +808,16 @@
case MSG_REQUEST_TRAVERSAL:
mWindowManagerFuncs.requestTraversal();
break;
+
+ case MSG_UPDATE_VIEWPORT: {
+ synchronized (mSyncRoot) {
+ mTempDefaultViewport.copyFrom(mDefaultViewport);
+ mTempExternalTouchViewport.copyFrom(mExternalTouchViewport);
+ }
+ mInputManagerFuncs.setDisplayViewports(
+ mTempDefaultViewport, mTempExternalTouchViewport);
+ break;
+ }
}
}
}
diff --git a/services/java/com/android/server/display/DisplayViewport.java b/services/java/com/android/server/display/DisplayViewport.java
new file mode 100644
index 0000000..ed4016d
--- /dev/null
+++ b/services/java/com/android/server/display/DisplayViewport.java
@@ -0,0 +1,65 @@
+/*
+ * 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.graphics.Rect;
+
+/**
+ * Describes how the pixels of physical display device reflects the content of
+ * a logical display.
+ * <p>
+ * This information is used by the input system to translate touch input from
+ * physical display coordinates into logical display coordinates.
+ * </p>
+ */
+public final class DisplayViewport {
+ // True if this viewport is valid.
+ public boolean valid;
+
+ // The logical display id.
+ public int displayId;
+
+ // The rotation applied to the physical coordinate system.
+ public int orientation;
+
+ // The portion of the logical display that are presented on this physical display.
+ public final Rect logicalFrame = new Rect();
+
+ // The portion of the (rotated) physical display that shows the logical display contents.
+ // The relation between logical and physical frame defines how the coordinate system
+ // should be scaled or translated after rotation.
+ public final Rect physicalFrame = new Rect();
+
+ public void copyFrom(DisplayViewport viewport) {
+ valid = viewport.valid;
+ displayId = viewport.displayId;
+ orientation = viewport.orientation;
+ logicalFrame.set(viewport.logicalFrame);
+ physicalFrame.set(viewport.physicalFrame);
+ }
+
+ // For debugging purposes.
+ @Override
+ public String toString() {
+ return "DisplayViewport{valid=" + valid
+ + ", displayId=" + displayId
+ + ", orientation=" + orientation
+ + ", logicalFrame=" + logicalFrame
+ + ", physicalFrame=" + physicalFrame
+ + "}";
+ }
+}
diff --git a/services/java/com/android/server/display/HeadlessDisplayAdapter.java b/services/java/com/android/server/display/HeadlessDisplayAdapter.java
index 3aaacf1..7629db6 100644
--- a/services/java/com/android/server/display/HeadlessDisplayAdapter.java
+++ b/services/java/com/android/server/display/HeadlessDisplayAdapter.java
@@ -61,6 +61,7 @@
mInfo.yDpi = 160;
mInfo.flags = DisplayDeviceInfo.FLAG_DEFAULT_DISPLAY
| DisplayDeviceInfo.FLAG_SECURE;
+ mInfo.touch = DisplayDeviceInfo.TOUCH_NONE;
}
return mInfo;
}
diff --git a/services/java/com/android/server/display/LocalDisplayAdapter.java b/services/java/com/android/server/display/LocalDisplayAdapter.java
index 4962753..80c860b 100644
--- a/services/java/com/android/server/display/LocalDisplayAdapter.java
+++ b/services/java/com/android/server/display/LocalDisplayAdapter.java
@@ -129,10 +129,12 @@
mInfo.densityDpi = (int)(mPhys.density * 160 + 0.5f);
mInfo.xDpi = mPhys.xDpi;
mInfo.yDpi = mPhys.yDpi;
+ mInfo.touch = DisplayDeviceInfo.TOUCH_INTERNAL;
} else {
mInfo.name = getContext().getResources().getString(
com.android.internal.R.string.display_manager_hdmi_display_name);
mInfo.flags = DisplayDeviceInfo.FLAG_SECURE;
+ mInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL;
mInfo.setAssumedDensityForExternalDisplay(mPhys.width, mPhys.height);
}
}
diff --git a/services/java/com/android/server/display/LogicalDisplay.java b/services/java/com/android/server/display/LogicalDisplay.java
index e0f63dd..2e75260 100644
--- a/services/java/com/android/server/display/LogicalDisplay.java
+++ b/services/java/com/android/server/display/LogicalDisplay.java
@@ -54,6 +54,7 @@
final class LogicalDisplay {
private final DisplayInfo mBaseDisplayInfo = new DisplayInfo();
+ private final int mDisplayId;
private final int mLayerStack;
private DisplayInfo mOverrideDisplayInfo; // set by the window manager
private DisplayInfo mInfo;
@@ -70,12 +71,22 @@
private final Rect mTempLayerStackRect = new Rect();
private final Rect mTempDisplayRect = new Rect();
- public LogicalDisplay(int layerStack, DisplayDevice primaryDisplayDevice) {
+ public LogicalDisplay(int displayId, int layerStack, DisplayDevice primaryDisplayDevice) {
+ mDisplayId = displayId;
mLayerStack = layerStack;
mPrimaryDisplayDevice = primaryDisplayDevice;
}
/**
+ * Gets the logical display id of this logical display.
+ *
+ * @return The logical display id.
+ */
+ public int getDisplayIdLocked() {
+ return mDisplayId;
+ }
+
+ /**
* Gets the primary display device associated with this logical display.
*
* @return The primary display device.
diff --git a/services/java/com/android/server/display/OverlayDisplayAdapter.java b/services/java/com/android/server/display/OverlayDisplayAdapter.java
index e2d3059..9b0e534 100644
--- a/services/java/com/android/server/display/OverlayDisplayAdapter.java
+++ b/services/java/com/android/server/display/OverlayDisplayAdapter.java
@@ -228,6 +228,7 @@
mInfo.xDpi = mDensityDpi;
mInfo.yDpi = mDensityDpi;
mInfo.flags = DisplayDeviceInfo.FLAG_SECURE;
+ mInfo.touch = DisplayDeviceInfo.TOUCH_NONE;
}
return mInfo;
}
diff --git a/services/java/com/android/server/display/WifiDisplayAdapter.java b/services/java/com/android/server/display/WifiDisplayAdapter.java
index abf0d27..ca500c0 100644
--- a/services/java/com/android/server/display/WifiDisplayAdapter.java
+++ b/services/java/com/android/server/display/WifiDisplayAdapter.java
@@ -324,6 +324,7 @@
mInfo.height = mHeight;
mInfo.refreshRate = mRefreshRate;
mInfo.flags = mFlags;
+ mInfo.touch = DisplayDeviceInfo.TOUCH_EXTERNAL;
mInfo.setAssumedDensityForExternalDisplay(mWidth, mHeight);
}
return mInfo;
diff --git a/services/java/com/android/server/input/InputManagerService.java b/services/java/com/android/server/input/InputManagerService.java
index fd4f5fc..95655a5 100644
--- a/services/java/com/android/server/input/InputManagerService.java
+++ b/services/java/com/android/server/input/InputManagerService.java
@@ -19,6 +19,8 @@
import com.android.internal.R;
import com.android.internal.util.XmlUtils;
import com.android.server.Watchdog;
+import com.android.server.display.DisplayManagerService;
+import com.android.server.display.DisplayViewport;
import org.xmlpull.v1.XmlPullParser;
@@ -90,7 +92,8 @@
/*
* Wraps the C++ InputManager and provides its callbacks.
*/
-public class InputManagerService extends IInputManager.Stub implements Watchdog.Monitor {
+public class InputManagerService extends IInputManager.Stub
+ implements Watchdog.Monitor, DisplayManagerService.InputManagerFuncs {
static final String TAG = "InputManager";
static final boolean DEBUG = false;
@@ -143,11 +146,11 @@
private static native int nativeInit(InputManagerService service,
Context context, MessageQueue messageQueue);
private static native void nativeStart(int ptr);
- private static native void nativeSetDisplaySize(int ptr, int displayId,
- int width, int height, int externalWidth, int externalHeight);
- private static native void nativeSetDisplayOrientation(int ptr, int displayId,
- int rotation, int externalRotation);
-
+ private static native void nativeSetDisplayViewport(int ptr, boolean external,
+ int displayId, int rotation,
+ int logicalLeft, int logicalTop, int logicalRight, int logicalBottom,
+ int physicalLeft, int physicalTop, int physicalRight, int physicalBottom);
+
private static native int nativeGetScanCodeState(int ptr,
int deviceId, int sourceMask, int scanCode);
private static native int nativeGetKeyCodeState(int ptr,
@@ -282,28 +285,27 @@
nativeReloadDeviceAliases(mPtr);
}
- public void setDisplaySize(int displayId, int width, int height) {
- if (width <= 0 || height <= 0) {
- throw new IllegalArgumentException("Invalid display id or dimensions.");
+ @Override
+ public void setDisplayViewports(DisplayViewport defaultViewport,
+ DisplayViewport externalTouchViewport) {
+ if (defaultViewport.valid) {
+ setDisplayViewport(false, defaultViewport);
}
-
- if (DEBUG) {
- Slog.d(TAG, "Setting display #" + displayId + " size to " + width + "x" + height);
+
+ if (externalTouchViewport.valid) {
+ setDisplayViewport(true, externalTouchViewport);
+ } else if (defaultViewport.valid) {
+ setDisplayViewport(true, defaultViewport);
}
- // FIXME: external size is deprecated
- nativeSetDisplaySize(mPtr, displayId, width, height, 1280, 720);
}
- public void setDisplayOrientation(int displayId, int rotation) {
- if (rotation < Surface.ROTATION_0 || rotation > Surface.ROTATION_270) {
- throw new IllegalArgumentException("Invalid rotation.");
- }
-
- if (DEBUG) {
- Slog.d(TAG, "Setting display #" + displayId + " orientation to rotation " + rotation);
- }
- // FIXME: external rotation is deprecated
- nativeSetDisplayOrientation(mPtr, displayId, rotation, Surface.ROTATION_0);
+ private void setDisplayViewport(boolean external, DisplayViewport viewport) {
+ nativeSetDisplayViewport(mPtr, external,
+ viewport.displayId, viewport.orientation,
+ viewport.logicalFrame.left, viewport.logicalFrame.top,
+ viewport.logicalFrame.right, viewport.logicalFrame.bottom,
+ viewport.physicalFrame.left, viewport.physicalFrame.top,
+ viewport.physicalFrame.right, viewport.physicalFrame.bottom);
}
/**
diff --git a/services/java/com/android/server/wm/WindowManagerService.java b/services/java/com/android/server/wm/WindowManagerService.java
index 18e793d..cdca8bc 100755
--- a/services/java/com/android/server/wm/WindowManagerService.java
+++ b/services/java/com/android/server/wm/WindowManagerService.java
@@ -5947,7 +5947,6 @@
mWaitingForConfig = true;
getDefaultDisplayContent().layoutNeeded = true;
startFreezingDisplayLocked(inTransaction);
- mInputManager.setDisplayOrientation(0, rotation);
// We need to update our screen size information to match the new
// rotation. Note that this is redundant with the later call to
@@ -7121,10 +7120,6 @@
displayInfo.appWidth, displayInfo.appHeight);
final DisplayContent displayContent = getDefaultDisplayContent();
- mInputManager.setDisplaySize(displayContent.getDisplayId(),
- displayContent.mInitialDisplayWidth, displayContent.mInitialDisplayHeight);
- mInputManager.setDisplayOrientation(displayContent.getDisplayId(),
- mDefaultDisplay.getRotation());
mPolicy.setInitialDisplaySize(mDefaultDisplay, displayContent.mInitialDisplayWidth,
displayContent.mInitialDisplayHeight, displayContent.mInitialDisplayDensity);
}
diff --git a/services/jni/com_android_server_input_InputManagerService.cpp b/services/jni/com_android_server_input_InputManagerService.cpp
index 495d4ab..5e36bf8 100644
--- a/services/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/jni/com_android_server_input_InputManagerService.cpp
@@ -164,9 +164,7 @@
void dump(String8& dump);
- void setDisplaySize(int32_t displayId, int32_t width, int32_t height,
- int32_t externalWidth, int32_t externalHeight);
- void setDisplayOrientation(int32_t displayId, int32_t orientation, int32_t externalOrientation);
+ void setDisplayViewport(bool external, const DisplayViewport& viewport);
status_t registerInputChannel(JNIEnv* env, const sp<InputChannel>& inputChannel,
const sp<InputWindowHandle>& inputWindowHandle, bool monitor);
@@ -223,10 +221,8 @@
Mutex mLock;
struct Locked {
// Display size information.
- int32_t displayWidth, displayHeight; // -1 when not initialized
- int32_t displayOrientation;
- int32_t displayExternalWidth, displayExternalHeight; // -1 when not initialized
- int32_t displayExternalOrientation;
+ DisplayViewport internalViewport;
+ DisplayViewport externalViewport;
// System UI visibility.
int32_t systemUiVisibility;
@@ -274,13 +270,6 @@
{
AutoMutex _l(mLock);
- mLocked.displayWidth = -1;
- mLocked.displayHeight = -1;
- mLocked.displayOrientation = DISPLAY_ORIENTATION_0;
- mLocked.displayExternalWidth = -1;
- mLocked.displayExternalHeight = -1;
- mLocked.displayExternalOrientation = DISPLAY_ORIENTATION_0;
-
mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
mLocked.pointerSpeed = 0;
mLocked.pointerGesturesEnabled = true;
@@ -316,57 +305,26 @@
return false;
}
-void NativeInputManager::setDisplaySize(int32_t displayId, int32_t width, int32_t height,
- int32_t externalWidth, int32_t externalHeight) {
+void NativeInputManager::setDisplayViewport(bool external, const DisplayViewport& viewport) {
bool changed = false;
- if (displayId == 0) {
+ {
AutoMutex _l(mLock);
- if (mLocked.displayWidth != width || mLocked.displayHeight != height) {
+ DisplayViewport& v = external ? mLocked.externalViewport : mLocked.internalViewport;
+ if (v != viewport) {
changed = true;
- mLocked.displayWidth = width;
- mLocked.displayHeight = height;
+ v = viewport;
- sp<PointerController> controller = mLocked.pointerController.promote();
- if (controller != NULL) {
- controller->setDisplaySize(width, height);
+ if (!external) {
+ sp<PointerController> controller = mLocked.pointerController.promote();
+ if (controller != NULL) {
+ controller->setDisplayViewport(
+ viewport.logicalRight - viewport.logicalLeft,
+ viewport.logicalBottom - viewport.logicalTop,
+ viewport.orientation);
+ }
}
}
-
- if (mLocked.displayExternalWidth != externalWidth
- || mLocked.displayExternalHeight != externalHeight) {
- changed = true;
- mLocked.displayExternalWidth = externalWidth;
- mLocked.displayExternalHeight = externalHeight;
- }
- }
-
- if (changed) {
- mInputManager->getReader()->requestRefreshConfiguration(
- InputReaderConfiguration::CHANGE_DISPLAY_INFO);
- }
-}
-
-void NativeInputManager::setDisplayOrientation(int32_t displayId, int32_t orientation,
- int32_t externalOrientation) {
- bool changed = false;
- if (displayId == 0) {
- AutoMutex _l(mLock);
-
- if (mLocked.displayOrientation != orientation) {
- changed = true;
- mLocked.displayOrientation = orientation;
-
- sp<PointerController> controller = mLocked.pointerController.promote();
- if (controller != NULL) {
- controller->setDisplayOrientation(orientation);
- }
- }
-
- if (mLocked.displayExternalOrientation != externalOrientation) {
- changed = true;
- mLocked.displayExternalOrientation = externalOrientation;
- }
}
if (changed) {
@@ -448,11 +406,8 @@
outConfig->showTouches = mLocked.showTouches;
- outConfig->setDisplayInfo(0, false /*external*/,
- mLocked.displayWidth, mLocked.displayHeight, mLocked.displayOrientation);
- outConfig->setDisplayInfo(0, true /*external*/,
- mLocked.displayExternalWidth, mLocked.displayExternalHeight,
- mLocked.displayExternalOrientation);
+ outConfig->setDisplayInfo(false /*external*/, mLocked.internalViewport);
+ outConfig->setDisplayInfo(true /*external*/, mLocked.externalViewport);
} // release lock
}
@@ -466,8 +421,11 @@
controller = new PointerController(this, mLooper, mLocked.spriteController);
mLocked.pointerController = controller;
- controller->setDisplaySize(mLocked.displayWidth, mLocked.displayHeight);
- controller->setDisplayOrientation(mLocked.displayOrientation);
+ DisplayViewport& v = mLocked.internalViewport;
+ controller->setDisplayViewport(
+ v.logicalRight - v.logicalLeft,
+ v.logicalBottom - v.logicalTop,
+ v.orientation);
JNIEnv* env = jniEnv();
jobject pointerIconObj = env->CallObjectMethod(mServiceObj,
@@ -1032,22 +990,24 @@
}
}
-static void nativeSetDisplaySize(JNIEnv* env, jclass clazz, jint ptr,
- jint displayId, jint width, jint height, jint externalWidth, jint externalHeight) {
+static void nativeSetDisplayViewport(JNIEnv* env, jclass clazz, jint ptr, jboolean external,
+ jint displayId, jint orientation,
+ jint logicalLeft, jint logicalTop, jint logicalRight, jint logicalBottom,
+ jint physicalLeft, jint physicalTop, jint physicalRight, jint physicalBottom) {
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
- // XXX we could get this from the SurfaceFlinger directly instead of requiring it
- // to be passed in like this, not sure which is better but leaving it like this
- // keeps the window manager in direct control of when display transitions propagate down
- // to the input dispatcher
- im->setDisplaySize(displayId, width, height, externalWidth, externalHeight);
-}
-
-static void nativeSetDisplayOrientation(JNIEnv* env, jclass clazz,
- jint ptr, jint displayId, jint orientation, jint externalOrientation) {
- NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
-
- im->setDisplayOrientation(displayId, orientation, externalOrientation);
+ DisplayViewport v;
+ v.displayId = displayId;
+ v.orientation = orientation;
+ v.logicalLeft = logicalLeft;
+ v.logicalTop = logicalTop;
+ v.logicalRight = logicalRight;
+ v.logicalBottom = logicalBottom;
+ v.physicalLeft = physicalLeft;
+ v.physicalTop = physicalTop;
+ v.physicalRight = physicalRight;
+ v.physicalBottom = physicalBottom;
+ im->setDisplayViewport(external, v);
}
static jint nativeGetScanCodeState(JNIEnv* env, jclass clazz,
@@ -1328,10 +1288,8 @@
(void*) nativeInit },
{ "nativeStart", "(I)V",
(void*) nativeStart },
- { "nativeSetDisplaySize", "(IIIIII)V",
- (void*) nativeSetDisplaySize },
- { "nativeSetDisplayOrientation", "(IIII)V",
- (void*) nativeSetDisplayOrientation },
+ { "nativeSetDisplayViewport", "(IZIIIIIIIIII)V",
+ (void*) nativeSetDisplayViewport },
{ "nativeGetScanCodeState", "(IIII)I",
(void*) nativeGetScanCodeState },
{ "nativeGetKeyCodeState", "(IIII)I",