am 56503b8d: am 8186a5f0: am 10c3f367: Merge "Implement pointer acceleration." into honeycomb-mr2

* commit '56503b8ddfe5c82407da32e18061e725f668432d':
  Implement pointer acceleration.
This commit is contained in:
Jeff Brown
2011-06-03 15:30:33 -07:00
committed by Android Git Automerger
4 changed files with 298 additions and 66 deletions

View File

@ -748,6 +748,20 @@ void InputReader::dump(String8& dump) {
dump.appendFormat(INDENT2 "VirtualKeyQuietTime: %0.1fms\n",
mConfig.virtualKeyQuietTime * 0.000001f);
dump.appendFormat(INDENT2 "PointerVelocityControlParameters: "
"scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, acceleration=%0.3f\n",
mConfig.pointerVelocityControlParameters.scale,
mConfig.pointerVelocityControlParameters.lowThreshold,
mConfig.pointerVelocityControlParameters.highThreshold,
mConfig.pointerVelocityControlParameters.acceleration);
dump.appendFormat(INDENT2 "WheelVelocityControlParameters: "
"scale=%0.3f, lowThreshold=%0.3f, highThreshold=%0.3f, acceleration=%0.3f\n",
mConfig.wheelVelocityControlParameters.scale,
mConfig.wheelVelocityControlParameters.lowThreshold,
mConfig.wheelVelocityControlParameters.highThreshold,
mConfig.wheelVelocityControlParameters.acceleration);
dump.appendFormat(INDENT2 "PointerGesture:\n");
dump.appendFormat(INDENT3 "QuietInterval: %0.1fms\n",
mConfig.pointerGestureQuietInterval * 0.000001f);
@ -1430,6 +1444,10 @@ void CursorInputMapper::configure() {
mHaveVWheel = getEventHub()->hasRelativeAxis(getDeviceId(), REL_WHEEL);
mHaveHWheel = getEventHub()->hasRelativeAxis(getDeviceId(), REL_HWHEEL);
mPointerVelocityControl.setParameters(getConfig()->pointerVelocityControlParameters);
mWheelXVelocityControl.setParameters(getConfig()->wheelVelocityControlParameters);
mWheelYVelocityControl.setParameters(getConfig()->wheelVelocityControlParameters);
}
void CursorInputMapper::configureParameters() {
@ -1491,6 +1509,11 @@ void CursorInputMapper::reset() {
}
} // release lock
// Reset velocity.
mPointerVelocityControl.reset();
mWheelXVelocityControl.reset();
mWheelYVelocityControl.reset();
// Synthesize button up event on reset.
nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
mAccumulator.clear();
@ -1654,11 +1677,16 @@ void CursorInputMapper::sync(nsecs_t when) {
} else {
vscroll = 0;
}
mWheelYVelocityControl.move(when, NULL, &vscroll);
if (mHaveHWheel && (fields & Accumulator::FIELD_REL_HWHEEL)) {
hscroll = mAccumulator.relHWheel;
} else {
hscroll = 0;
}
mWheelXVelocityControl.move(when, &hscroll, NULL);
mPointerVelocityControl.move(when, &deltaX, &deltaY);
if (mPointerController != NULL) {
if (deltaX != 0 || deltaY != 0 || vscroll != 0 || hscroll != 0
@ -1900,6 +1928,7 @@ void TouchInputMapper::initializeLocked() {
mLocked.orientedRanges.haveDistance = false;
mPointerGesture.reset();
mPointerGesture.pointerVelocityControl.setParameters(mConfig->pointerVelocityControlParameters);
}
void TouchInputMapper::configure() {
@ -2369,11 +2398,10 @@ bool TouchInputMapper::configureSurfaceLocked() {
mLocked.associatedDisplayHeight);
// Scale movements such that one whole swipe of the touch pad covers a
// given area relative to the diagonal size of the display.
// given area relative to the diagonal size of the display when no acceleration
// is applied.
// Assume that the touch pad has a square aspect ratio such that movements in
// X and Y of the same number of raw units cover the same physical distance.
const float scaleFactor = 0.8f;
mLocked.pointerGestureXMovementScale = mConfig->pointerGestureMovementSpeedRatio
* displayDiagonal / rawDiagonal;
mLocked.pointerGestureYMovementScale = mLocked.pointerGestureXMovementScale;
@ -3463,6 +3491,9 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag
if (!sendEvents) {
return;
}
if (finishPreviousGesture) {
cancelPreviousGesture = false;
}
// Switch pointer presentation.
mPointerController->setPresentation(
@ -3666,6 +3697,8 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL;
mPointerGesture.currentGestureIdBits.clear();
mPointerGesture.pointerVelocityControl.reset();
if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_NEUTRAL;
mPointerGesture.spotIdBits.clear();
@ -3760,6 +3793,8 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.currentGestureMode = PointerGesture::QUIET;
mPointerGesture.currentGestureIdBits.clear();
mPointerGesture.pointerVelocityControl.reset();
if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_NEUTRAL;
mPointerGesture.spotIdBits.clear();
@ -3791,46 +3826,48 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
// Switch pointers if needed.
// Find the fastest pointer and follow it.
if (activeTouchId >= 0) {
if (mCurrentTouch.pointerCount > 1) {
int32_t bestId = -1;
float bestSpeed = mConfig->pointerGestureDragMinSwitchSpeed;
for (uint32_t i = 0; i < mCurrentTouch.pointerCount; i++) {
uint32_t id = mCurrentTouch.pointers[i].id;
float vx, vy;
if (mPointerGesture.velocityTracker.getVelocity(id, &vx, &vy)) {
float speed = hypotf(vx, vy);
if (speed > bestSpeed) {
bestId = id;
bestSpeed = speed;
}
if (activeTouchId >= 0 && mCurrentTouch.pointerCount > 1) {
int32_t bestId = -1;
float bestSpeed = mConfig->pointerGestureDragMinSwitchSpeed;
for (uint32_t i = 0; i < mCurrentTouch.pointerCount; i++) {
uint32_t id = mCurrentTouch.pointers[i].id;
float vx, vy;
if (mPointerGesture.velocityTracker.getVelocity(id, &vx, &vy)) {
float speed = hypotf(vx, vy);
if (speed > bestSpeed) {
bestId = id;
bestSpeed = speed;
}
}
if (bestId >= 0 && bestId != activeTouchId) {
mPointerGesture.activeTouchId = activeTouchId = bestId;
activeTouchChanged = true;
}
if (bestId >= 0 && bestId != activeTouchId) {
mPointerGesture.activeTouchId = activeTouchId = bestId;
activeTouchChanged = true;
#if DEBUG_GESTURES
LOGD("Gestures: BUTTON_CLICK_OR_DRAG switched pointers, "
"bestId=%d, bestSpeed=%0.3f", bestId, bestSpeed);
LOGD("Gestures: BUTTON_CLICK_OR_DRAG switched pointers, "
"bestId=%d, bestSpeed=%0.3f", bestId, bestSpeed);
#endif
}
}
}
if (mLastTouch.idBits.hasBit(activeTouchId)) {
const PointerData& currentPointer =
mCurrentTouch.pointers[mCurrentTouch.idToIndex[activeTouchId]];
const PointerData& lastPointer =
mLastTouch.pointers[mLastTouch.idToIndex[activeTouchId]];
float deltaX = (currentPointer.x - lastPointer.x)
* mLocked.pointerGestureXMovementScale;
float deltaY = (currentPointer.y - lastPointer.y)
* mLocked.pointerGestureYMovementScale;
if (activeTouchId >= 0 && mLastTouch.idBits.hasBit(activeTouchId)) {
const PointerData& currentPointer =
mCurrentTouch.pointers[mCurrentTouch.idToIndex[activeTouchId]];
const PointerData& lastPointer =
mLastTouch.pointers[mLastTouch.idToIndex[activeTouchId]];
float deltaX = (currentPointer.x - lastPointer.x)
* mLocked.pointerGestureXMovementScale;
float deltaY = (currentPointer.y - lastPointer.y)
* mLocked.pointerGestureYMovementScale;
// Move the pointer using a relative motion.
// When using spots, the click will occur at the position of the anchor
// spot and all other spots will move there.
mPointerController->move(deltaX, deltaY);
}
mPointerGesture.pointerVelocityControl.move(when, &deltaX, &deltaY);
// Move the pointer using a relative motion.
// When using spots, the click will occur at the position of the anchor
// spot and all other spots will move there.
mPointerController->move(deltaX, deltaY);
} else {
mPointerGesture.pointerVelocityControl.reset();
}
float x, y;
@ -3939,6 +3976,8 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
}
}
mPointerGesture.pointerVelocityControl.reset();
if (!tapped) {
#if DEBUG_GESTURES
LOGD("Gestures: NEUTRAL");
@ -3995,9 +4034,13 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
float deltaY = (currentPointer.y - lastPointer.y)
* mLocked.pointerGestureYMovementScale;
mPointerGesture.pointerVelocityControl.move(when, &deltaX, &deltaY);
// Move the pointer using a relative motion.
// When using spots, the hover or drag will occur at the position of the anchor spot.
mPointerController->move(deltaX, deltaY);
} else {
mPointerGesture.pointerVelocityControl.reset();
}
bool down;
@ -4063,16 +4106,32 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
// a decision to transition into SWIPE or FREEFORM mode accordingly.
LOG_ASSERT(activeTouchId >= 0);
bool needReference = false;
bool settled = when >= mPointerGesture.firstTouchTime
+ mConfig->pointerGestureMultitouchSettleInterval;
if (mPointerGesture.lastGestureMode != PointerGesture::PRESS
&& mPointerGesture.lastGestureMode != PointerGesture::SWIPE
&& mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) {
*outFinishPreviousGesture = true;
} else if (!settled && mCurrentTouch.pointerCount > mLastTouch.pointerCount) {
// Additional pointers have gone down but not yet settled.
// Reset the gesture.
#if DEBUG_GESTURES
LOGD("Gestures: Resetting gesture since additional pointers went down for MULTITOUCH, "
"settle time remaining %0.3fms",
(mPointerGesture.firstTouchTime + MULTITOUCH_SETTLE_INTERVAL - when)
* 0.000001f);
#endif
*outCancelPreviousGesture = true;
} else {
// Continue previous gesture.
mPointerGesture.currentGestureMode = mPointerGesture.lastGestureMode;
}
if (*outFinishPreviousGesture || *outCancelPreviousGesture) {
mPointerGesture.currentGestureMode = PointerGesture::PRESS;
mPointerGesture.activeGestureId = 0;
mPointerGesture.referenceIdBits.clear();
mPointerGesture.pointerVelocityControl.reset();
if (settled && mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS
&& mLastTouch.idBits.hasBit(mPointerGesture.activeTouchId)) {
@ -4093,37 +4152,18 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.referenceGestureX = c.getAxisValue(AMOTION_EVENT_AXIS_X);
mPointerGesture.referenceGestureY = c.getAxisValue(AMOTION_EVENT_AXIS_Y);
} else {
// Use the centroid and pointer location as the reference points for the gesture.
#if DEBUG_GESTURES
LOGD("Gestures: Using centroid as reference for MULTITOUCH, "
"settle time remaining %0.3fms",
(mPointerGesture.firstTouchTime + MULTITOUCH_SETTLE_INTERVAL - when)
* 0.000001f);
#endif
needReference = true;
mCurrentTouch.getCentroid(&mPointerGesture.referenceTouchX,
&mPointerGesture.referenceTouchY);
mPointerController->getPosition(&mPointerGesture.referenceGestureX,
&mPointerGesture.referenceGestureY);
}
} else if (!settled && mCurrentTouch.pointerCount > mLastTouch.pointerCount) {
// Additional pointers have gone down but not yet settled.
// Reset the gesture.
#if DEBUG_GESTURES
LOGD("Gestures: Resetting gesture since additional pointers went down for MULTITOUCH, "
"settle time remaining %0.3fms",
(mPointerGesture.firstTouchTime + MULTITOUCH_SETTLE_INTERVAL - when)
* 0.000001f);
#endif
*outCancelPreviousGesture = true;
mPointerGesture.currentGestureMode = PointerGesture::PRESS;
mPointerGesture.activeGestureId = 0;
} else {
// Continue previous gesture.
mPointerGesture.currentGestureMode = mPointerGesture.lastGestureMode;
}
if (needReference) {
// Use the centroid and pointer location as the reference points for the gesture.
mCurrentTouch.getCentroid(&mPointerGesture.referenceTouchX,
&mPointerGesture.referenceTouchY);
mPointerController->getPosition(&mPointerGesture.referenceGestureX,
&mPointerGesture.referenceGestureY);
}
if (mPointerGesture.currentGestureMode == PointerGesture::PRESS) {
@ -4253,10 +4293,14 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.referenceTouchX += commonDeltaX;
mPointerGesture.referenceTouchY += commonDeltaY;
mPointerGesture.referenceGestureX +=
commonDeltaX * mLocked.pointerGestureXMovementScale;
mPointerGesture.referenceGestureY +=
commonDeltaY * mLocked.pointerGestureYMovementScale;
commonDeltaX *= mLocked.pointerGestureXMovementScale;
commonDeltaY *= mLocked.pointerGestureYMovementScale;
mPointerGesture.pointerVelocityControl.move(when, &commonDeltaX, &commonDeltaY);
mPointerGesture.referenceGestureX += commonDeltaX;
mPointerGesture.referenceGestureY += commonDeltaY;
clampPositionUsingPointerBounds(mPointerController,
&mPointerGesture.referenceGestureX,
&mPointerGesture.referenceGestureY);