diff options
Diffstat (limited to 'services/input')
-rw-r--r-- | services/input/InputReader.cpp | 418 | ||||
-rw-r--r-- | services/input/InputReader.h | 21 | ||||
-rw-r--r-- | services/input/PointerController.cpp | 8 | ||||
-rw-r--r-- | services/input/PointerController.h | 39 | ||||
-rw-r--r-- | services/input/tests/InputReader_test.cpp | 4 |
5 files changed, 169 insertions, 321 deletions
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp index c42e3ab..09b24a8 100644 --- a/services/input/InputReader.cpp +++ b/services/input/InputReader.cpp @@ -200,23 +200,6 @@ static int32_t calculateEdgeFlagsUsingPointerBounds( return edgeFlags; } -static void clampPositionUsingPointerBounds( - const sp<PointerControllerInterface>& pointerController, float* x, float* y) { - float minX, minY, maxX, maxY; - if (pointerController->getBounds(&minX, &minY, &maxX, &maxY)) { - if (*x < minX) { - *x = minX; - } else if (*x > maxX) { - *x = maxX; - } - if (*y < minY) { - *y = minY; - } else if (*y > maxY) { - *y = maxY; - } - } -} - static float calculateCommonVector(float a, float b) { if (a > 0 && b > 0) { return a < b ? a : b; @@ -787,8 +770,8 @@ void InputReader::dump(String8& dump) { mConfig.pointerGestureTapSlop); dump.appendFormat(INDENT3 "MultitouchSettleInterval: %0.1fms\n", mConfig.pointerGestureMultitouchSettleInterval * 0.000001f); - dump.appendFormat(INDENT3 "MultitouchMinSpeed: %0.1fpx/s\n", - mConfig.pointerGestureMultitouchMinSpeed); + dump.appendFormat(INDENT3 "MultitouchMinDistance: %0.1fpx\n", + mConfig.pointerGestureMultitouchMinDistance); dump.appendFormat(INDENT3 "SwipeTransitionAngleCosine: %0.1f\n", mConfig.pointerGestureSwipeTransitionAngleCosine); dump.appendFormat(INDENT3 "SwipeMaxWidthRatio: %0.1f\n", @@ -3509,11 +3492,18 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag cancelPreviousGesture = false; } - // Switch pointer presentation. - mPointerController->setPresentation( - mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS - ? PointerControllerInterface::PRESENTATION_SPOT - : PointerControllerInterface::PRESENTATION_POINTER); + // Update the pointer presentation and spots. + if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) { + mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_SPOT); + if (finishPreviousGesture || cancelPreviousGesture) { + mPointerController->clearSpots(); + } + mPointerController->setSpots(mPointerGesture.currentGestureCoords, + mPointerGesture.currentGestureIdToIndex, + mPointerGesture.currentGestureIdBits); + } else { + mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER); + } // Show or hide the pointer if needed. switch (mPointerGesture.currentGestureMode) { @@ -3712,12 +3702,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, mPointerGesture.currentGestureIdBits.clear(); mPointerGesture.pointerVelocityControl.reset(); - - if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) { - mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_NEUTRAL; - mPointerGesture.spotIdBits.clear(); - moveSpotsLocked(); - } return true; } } @@ -3798,22 +3782,18 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, if (isQuietTime) { // Case 1: Quiet time. (QUIET) #if DEBUG_GESTURES - LOGD("Gestures: QUIET for next %0.3fms", - (mPointerGesture.quietTime + QUIET_INTERVAL - when) * 0.000001f); + LOGD("Gestures: QUIET for next %0.3fms", (mPointerGesture.quietTime + + mConfig->pointerGestureQuietInterval - when) * 0.000001f); #endif - *outFinishPreviousGesture = true; + if (mPointerGesture.lastGestureMode != PointerGesture::QUIET) { + *outFinishPreviousGesture = true; + } mPointerGesture.activeGestureId = -1; 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(); - moveSpotsLocked(); - } } else if (isPointerDown(mCurrentTouch.buttonState)) { // Case 2: Button is pressed. (BUTTON_CLICK_OR_DRAG) // The pointer follows the active touch point. @@ -3899,32 +3879,11 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x); mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y); mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f); - - if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) { - if (activeTouchId >= 0) { - // Collapse all spots into one point at the pointer location. - mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_BUTTON_DRAG; - mPointerGesture.spotIdBits.clear(); - for (uint32_t i = 0; i < mCurrentTouch.pointerCount; i++) { - uint32_t id = mCurrentTouch.pointers[i].id; - mPointerGesture.spotIdBits.markBit(id); - mPointerGesture.spotIdToIndex[id] = i; - mPointerGesture.spotCoords[i] = mPointerGesture.currentGestureCoords[0]; - } - } else { - // No fingers. Generate a spot at the pointer location so the - // anchor appears to be pressed. - mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_BUTTON_CLICK; - mPointerGesture.spotIdBits.clear(); - mPointerGesture.spotIdBits.markBit(0); - mPointerGesture.spotIdToIndex[0] = 0; - mPointerGesture.spotCoords[0] = mPointerGesture.currentGestureCoords[0]; - } - moveSpotsLocked(); - } } else if (mCurrentTouch.pointerCount == 0) { // Case 3. No fingers down and button is not pressed. (NEUTRAL) - *outFinishPreviousGesture = true; + if (mPointerGesture.lastGestureMode != PointerGesture::NEUTRAL) { + *outFinishPreviousGesture = true; + } // Watch for taps coming out of HOVER or TAP_DRAG mode. // Checking for taps after TAP_DRAG allows us to detect double-taps. @@ -3965,15 +3924,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, mPointerGesture.currentGestureCoords[0].setAxisValue( AMOTION_EVENT_AXIS_PRESSURE, 1.0f); - if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) { - mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_TAP; - mPointerGesture.spotIdBits.clear(); - mPointerGesture.spotIdBits.markBit(lastActiveTouchId); - mPointerGesture.spotIdToIndex[lastActiveTouchId] = 0; - mPointerGesture.spotCoords[0] = mPointerGesture.currentGestureCoords[0]; - moveSpotsLocked(); - } - tapped = true; } else { #if DEBUG_GESTURES @@ -3999,12 +3949,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, mPointerGesture.activeGestureId = -1; mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL; mPointerGesture.currentGestureIdBits.clear(); - - if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) { - mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_NEUTRAL; - mPointerGesture.spotIdBits.clear(); - moveSpotsLocked(); - } } } else if (mCurrentTouch.pointerCount == 1) { // Case 4. Exactly one finger down, button is not pressed. (HOVER or TAP_DRAG) @@ -4067,7 +4011,9 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, #if DEBUG_GESTURES LOGD("Gestures: HOVER"); #endif - *outFinishPreviousGesture = true; + if (mPointerGesture.lastGestureMode != PointerGesture::HOVER) { + *outFinishPreviousGesture = true; + } mPointerGesture.activeGestureId = 0; down = false; } @@ -4094,16 +4040,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, mPointerGesture.tapX = x; mPointerGesture.tapY = y; } - - if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) { - mPointerGesture.spotGesture = down ? PointerControllerInterface::SPOT_GESTURE_DRAG - : PointerControllerInterface::SPOT_GESTURE_HOVER; - mPointerGesture.spotIdBits.clear(); - mPointerGesture.spotIdBits.markBit(activeTouchId); - mPointerGesture.spotIdToIndex[activeTouchId] = 0; - mPointerGesture.spotCoords[0] = mPointerGesture.currentGestureCoords[0]; - moveSpotsLocked(); - } } else { // Case 5. At least two fingers down, button is not pressed. (PRESS, SWIPE or FREEFORM) // We need to provide feedback for each finger that goes down so we cannot wait @@ -4131,8 +4067,8 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, // 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) + "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime + + mConfig->pointerGestureMultitouchSettleInterval - when) * 0.000001f); #endif *outCancelPreviousGesture = true; @@ -4147,101 +4083,134 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, mPointerGesture.referenceIdBits.clear(); mPointerGesture.pointerVelocityControl.reset(); - if (settled && mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS - && mLastTouch.idBits.hasBit(mPointerGesture.activeTouchId)) { - // The spot is already visible and has settled, use it as the reference point - // for the gesture. Other spots will be positioned relative to this one. + // Use the centroid and pointer location as the reference points for the gesture. #if DEBUG_GESTURES - LOGD("Gestures: Using active spot as reference for MULTITOUCH, " - "settle time expired %0.3fms ago", - (when - mPointerGesture.firstTouchTime - MULTITOUCH_SETTLE_INTERVAL) - * 0.000001f); + LOGD("Gestures: Using centroid as reference for MULTITOUCH, " + "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime + + mConfig->pointerGestureMultitouchSettleInterval - when) + * 0.000001f); #endif - const PointerData& d = mLastTouch.pointers[mLastTouch.idToIndex[ - mPointerGesture.activeTouchId]]; - mPointerGesture.referenceTouchX = d.x; - mPointerGesture.referenceTouchY = d.y; - const PointerCoords& c = mPointerGesture.spotCoords[mPointerGesture.spotIdToIndex[ - mPointerGesture.activeTouchId]]; - mPointerGesture.referenceGestureX = c.getAxisValue(AMOTION_EVENT_AXIS_X); - mPointerGesture.referenceGestureY = c.getAxisValue(AMOTION_EVENT_AXIS_Y); + mCurrentTouch.getCentroid(&mPointerGesture.referenceTouchX, + &mPointerGesture.referenceTouchY); + mPointerController->getPosition(&mPointerGesture.referenceGestureX, + &mPointerGesture.referenceGestureY); + } + + // Clear the reference deltas for fingers not yet included in the reference calculation. + for (BitSet32 idBits(mCurrentTouch.idBits.value & ~mPointerGesture.referenceIdBits.value); + !idBits.isEmpty(); ) { + uint32_t id = idBits.firstMarkedBit(); + idBits.clearBit(id); + + mPointerGesture.referenceDeltas[id].dx = 0; + mPointerGesture.referenceDeltas[id].dy = 0; + } + mPointerGesture.referenceIdBits = mCurrentTouch.idBits; + + // Add delta for all fingers and calculate a common movement delta. + float commonDeltaX = 0, commonDeltaY = 0; + BitSet32 commonIdBits(mLastTouch.idBits.value & mCurrentTouch.idBits.value); + for (BitSet32 idBits(commonIdBits); !idBits.isEmpty(); ) { + bool first = (idBits == commonIdBits); + uint32_t id = idBits.firstMarkedBit(); + idBits.clearBit(id); + + const PointerData& cpd = mCurrentTouch.pointers[mCurrentTouch.idToIndex[id]]; + const PointerData& lpd = mLastTouch.pointers[mLastTouch.idToIndex[id]]; + PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id]; + delta.dx += cpd.x - lpd.x; + delta.dy += cpd.y - lpd.y; + + if (first) { + commonDeltaX = delta.dx; + commonDeltaY = delta.dy; } 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 - mCurrentTouch.getCentroid(&mPointerGesture.referenceTouchX, - &mPointerGesture.referenceTouchY); - mPointerController->getPosition(&mPointerGesture.referenceGestureX, - &mPointerGesture.referenceGestureY); + commonDeltaX = calculateCommonVector(commonDeltaX, delta.dx); + commonDeltaY = calculateCommonVector(commonDeltaY, delta.dy); } } + // Consider transitions from PRESS to SWIPE or MULTITOUCH. if (mPointerGesture.currentGestureMode == PointerGesture::PRESS) { - float d; - if (mCurrentTouch.pointerCount > 2) { - // There are more than two pointers, switch to FREEFORM. + float dist[MAX_POINTER_ID + 1]; + int32_t distOverThreshold = 0; + for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) { + uint32_t id = idBits.firstMarkedBit(); + idBits.clearBit(id); + + PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id]; + dist[id] = hypotf(delta.dx * mLocked.pointerGestureXZoomScale, + delta.dy * mLocked.pointerGestureYZoomScale); + if (dist[id] > mConfig->pointerGestureMultitouchMinDistance) { + distOverThreshold += 1; + } + } + + // Only transition when at least two pointers have moved further than + // the minimum distance threshold. + if (distOverThreshold >= 2) { + float d; + if (mCurrentTouch.pointerCount > 2) { + // There are more than two pointers, switch to FREEFORM. #if DEBUG_GESTURES - LOGD("Gestures: PRESS transitioned to FREEFORM, number of pointers %d > 2", - mCurrentTouch.pointerCount); + LOGD("Gestures: PRESS transitioned to FREEFORM, number of pointers %d > 2", + mCurrentTouch.pointerCount); #endif - *outCancelPreviousGesture = true; - mPointerGesture.currentGestureMode = PointerGesture::FREEFORM; - } else if (((d = distance( - mCurrentTouch.pointers[0].x, mCurrentTouch.pointers[0].y, - mCurrentTouch.pointers[1].x, mCurrentTouch.pointers[1].y)) - > mLocked.pointerGestureMaxSwipeWidth)) { - // There are two pointers but they are too far apart, switch to FREEFORM. + *outCancelPreviousGesture = true; + mPointerGesture.currentGestureMode = PointerGesture::FREEFORM; + } else if (((d = distance( + mCurrentTouch.pointers[0].x, mCurrentTouch.pointers[0].y, + mCurrentTouch.pointers[1].x, mCurrentTouch.pointers[1].y)) + > mLocked.pointerGestureMaxSwipeWidth)) { + // There are two pointers but they are too far apart for a SWIPE, + // switch to FREEFORM. #if DEBUG_GESTURES - LOGD("Gestures: PRESS transitioned to FREEFORM, distance %0.3f > %0.3f", - d, mLocked.pointerGestureMaxSwipeWidth); + LOGD("Gestures: PRESS transitioned to FREEFORM, distance %0.3f > %0.3f", + d, mLocked.pointerGestureMaxSwipeWidth); #endif - *outCancelPreviousGesture = true; - mPointerGesture.currentGestureMode = PointerGesture::FREEFORM; - } else { - // There are two pointers. Wait for both pointers to start moving - // before deciding whether this is a SWIPE or FREEFORM gesture. - uint32_t id1 = mCurrentTouch.pointers[0].id; - uint32_t id2 = mCurrentTouch.pointers[1].id; - - float vx1, vy1, vx2, vy2; - mPointerGesture.velocityTracker.getVelocity(id1, &vx1, &vy1); - mPointerGesture.velocityTracker.getVelocity(id2, &vx2, &vy2); - - float speed1 = hypotf(vx1, vy1); - float speed2 = hypotf(vx2, vy2); - if (speed1 >= mConfig->pointerGestureMultitouchMinSpeed - && speed2 >= mConfig->pointerGestureMultitouchMinSpeed) { - // Calculate the dot product of the velocity vectors. - // When the vectors are oriented in approximately the same direction, - // the angle betweeen them is near zero and the cosine of the angle - // approches 1.0. Recall that dot(v1, v2) = cos(angle) * mag(v1) * mag(v2). - float dot = vx1 * vx2 + vy1 * vy2; - float cosine = dot / (speed1 * speed2); // denominator always > 0 - if (cosine >= mConfig->pointerGestureSwipeTransitionAngleCosine) { - // Pointers are moving in the same direction. Switch to SWIPE. + *outCancelPreviousGesture = true; + mPointerGesture.currentGestureMode = PointerGesture::FREEFORM; + } else { + // There are two pointers. Wait for both pointers to start moving + // before deciding whether this is a SWIPE or FREEFORM gesture. + uint32_t id1 = mCurrentTouch.pointers[0].id; + uint32_t id2 = mCurrentTouch.pointers[1].id; + float dist1 = dist[id1]; + float dist2 = dist[id2]; + if (dist1 >= mConfig->pointerGestureMultitouchMinDistance + && dist2 >= mConfig->pointerGestureMultitouchMinDistance) { + // Calculate the dot product of the displacement vectors. + // When the vectors are oriented in approximately the same direction, + // the angle betweeen them is near zero and the cosine of the angle + // approches 1.0. Recall that dot(v1, v2) = cos(angle) * mag(v1) * mag(v2). + PointerGesture::Delta& delta1 = mPointerGesture.referenceDeltas[id1]; + PointerGesture::Delta& delta2 = mPointerGesture.referenceDeltas[id2]; + float dot = delta1.dx * delta2.dx + delta1.dy * delta2.dy; + float cosine = dot / (dist1 * dist2); // denominator always > 0 + if (cosine >= mConfig->pointerGestureSwipeTransitionAngleCosine) { + // Pointers are moving in the same direction. Switch to SWIPE. #if DEBUG_GESTURES - LOGD("Gestures: PRESS transitioned to SWIPE, " - "speed1 %0.3f >= %0.3f, speed2 %0.3f >= %0.3f, " - "cosine %0.3f >= %0.3f", - speed1, MULTITOUCH_MIN_SPEED, speed2, MULTITOUCH_MIN_SPEED, - cosine, SWIPE_TRANSITION_ANGLE_COSINE); + LOGD("Gestures: PRESS transitioned to SWIPE, " + "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, " + "cosine %0.3f >= %0.3f", + dist1, mConfig->pointerGestureMultitouchMinDistance, + dist2, mConfig->pointerGestureMultitouchMinDistance, + cosine, mConfig->pointerGestureSwipeTransitionAngleCosine); #endif - mPointerGesture.currentGestureMode = PointerGesture::SWIPE; - } else { - // Pointers are moving in different directions. Switch to FREEFORM. + mPointerGesture.currentGestureMode = PointerGesture::SWIPE; + } else { + // Pointers are moving in different directions. Switch to FREEFORM. #if DEBUG_GESTURES - LOGD("Gestures: PRESS transitioned to FREEFORM, " - "speed1 %0.3f >= %0.3f, speed2 %0.3f >= %0.3f, " - "cosine %0.3f < %0.3f", - speed1, MULTITOUCH_MIN_SPEED, speed2, MULTITOUCH_MIN_SPEED, - cosine, SWIPE_TRANSITION_ANGLE_COSINE); + LOGD("Gestures: PRESS transitioned to FREEFORM, " + "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, " + "cosine %0.3f < %0.3f", + dist1, mConfig->pointerGestureMultitouchMinDistance, + dist2, mConfig->pointerGestureMultitouchMinDistance, + cosine, mConfig->pointerGestureSwipeTransitionAngleCosine); #endif - *outCancelPreviousGesture = true; - mPointerGesture.currentGestureMode = PointerGesture::FREEFORM; + *outCancelPreviousGesture = true; + mPointerGesture.currentGestureMode = PointerGesture::FREEFORM; + } } } } @@ -4258,67 +4227,28 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, } } - // Clear the reference deltas for fingers not yet included in the reference calculation. - for (BitSet32 idBits(mCurrentTouch.idBits.value & ~mPointerGesture.referenceIdBits.value); - !idBits.isEmpty(); ) { - uint32_t id = idBits.firstMarkedBit(); - idBits.clearBit(id); - - mPointerGesture.referenceDeltas[id].dx = 0; - mPointerGesture.referenceDeltas[id].dy = 0; - } - mPointerGesture.referenceIdBits = mCurrentTouch.idBits; - - // Move the reference points based on the overall group motion of the fingers. - // The objective is to calculate a vector delta that is common to the movement - // of all fingers. - BitSet32 commonIdBits(mLastTouch.idBits.value & mCurrentTouch.idBits.value); - if (!commonIdBits.isEmpty()) { - float commonDeltaX = 0, commonDeltaY = 0; - for (BitSet32 idBits(commonIdBits); !idBits.isEmpty(); ) { - bool first = (idBits == commonIdBits); + // Move the reference points based on the overall group motion of the fingers + // except in PRESS mode while waiting for a transition to occur. + if (mPointerGesture.currentGestureMode != PointerGesture::PRESS + && (commonDeltaX || commonDeltaY)) { + for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) { uint32_t id = idBits.firstMarkedBit(); idBits.clearBit(id); - const PointerData& cpd = mCurrentTouch.pointers[mCurrentTouch.idToIndex[id]]; - const PointerData& lpd = mLastTouch.pointers[mLastTouch.idToIndex[id]]; PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id]; - delta.dx += cpd.x - lpd.x; - delta.dy += cpd.y - lpd.y; - - if (first) { - commonDeltaX = delta.dx; - commonDeltaY = delta.dy; - } else { - commonDeltaX = calculateCommonVector(commonDeltaX, delta.dx); - commonDeltaY = calculateCommonVector(commonDeltaY, delta.dy); - } + delta.dx = 0; + delta.dy = 0; } - if (commonDeltaX || commonDeltaY) { - for (BitSet32 idBits(commonIdBits); !idBits.isEmpty(); ) { - uint32_t id = idBits.firstMarkedBit(); - idBits.clearBit(id); - - PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id]; - delta.dx = 0; - delta.dy = 0; - } - - mPointerGesture.referenceTouchX += commonDeltaX; - mPointerGesture.referenceTouchY += commonDeltaY; + mPointerGesture.referenceTouchX += commonDeltaX; + mPointerGesture.referenceTouchY += commonDeltaY; - commonDeltaX *= mLocked.pointerGestureXMovementScale; - commonDeltaY *= mLocked.pointerGestureYMovementScale; - mPointerGesture.pointerVelocityControl.move(when, &commonDeltaX, &commonDeltaY); + commonDeltaX *= mLocked.pointerGestureXMovementScale; + commonDeltaY *= mLocked.pointerGestureYMovementScale; + mPointerGesture.pointerVelocityControl.move(when, &commonDeltaX, &commonDeltaY); - mPointerGesture.referenceGestureX += commonDeltaX; - mPointerGesture.referenceGestureY += commonDeltaY; - - clampPositionUsingPointerBounds(mPointerController, - &mPointerGesture.referenceGestureX, - &mPointerGesture.referenceGestureY); - } + mPointerGesture.referenceGestureX += commonDeltaX; + mPointerGesture.referenceGestureY += commonDeltaY; } // Report gestures. @@ -4344,10 +4274,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, mPointerGesture.referenceGestureY); mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f); - - if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) { - mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_PRESS; - } } else if (mPointerGesture.currentGestureMode == PointerGesture::SWIPE) { // SWIPE mode. #if DEBUG_GESTURES @@ -4370,10 +4296,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, mPointerGesture.referenceGestureY); mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f); - - if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) { - mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_SWIPE; - } } else if (mPointerGesture.currentGestureMode == PointerGesture::FREEFORM) { // FREEFORM mode. #if DEBUG_GESTURES @@ -4475,33 +4397,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, "activeGestureId=%d", mPointerGesture.activeGestureId); #endif } - - if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) { - mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_FREEFORM; - } - } - - // Update spot locations for PRESS, SWIPE and FREEFORM. - // We use the same calculation as we do to calculate the gesture pointers - // for FREEFORM so that the spots smoothly track gestures. - if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) { - mPointerGesture.spotIdBits.clear(); - for (uint32_t i = 0; i < mCurrentTouch.pointerCount; i++) { - uint32_t id = mCurrentTouch.pointers[i].id; - mPointerGesture.spotIdBits.markBit(id); - mPointerGesture.spotIdToIndex[id] = i; - - float x = (mCurrentTouch.pointers[i].x - mPointerGesture.referenceTouchX) - * mLocked.pointerGestureXZoomScale + mPointerGesture.referenceGestureX; - float y = (mCurrentTouch.pointers[i].y - mPointerGesture.referenceTouchY) - * mLocked.pointerGestureYZoomScale + mPointerGesture.referenceGestureY; - - mPointerGesture.spotCoords[i].clear(); - mPointerGesture.spotCoords[i].setAxisValue(AMOTION_EVENT_AXIS_X, x); - mPointerGesture.spotCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, y); - mPointerGesture.spotCoords[i].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f); - } - moveSpotsLocked(); } } @@ -4544,11 +4439,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, return true; } -void TouchInputMapper::moveSpotsLocked() { - mPointerController->setSpots(mPointerGesture.spotGesture, - mPointerGesture.spotCoords, mPointerGesture.spotIdToIndex, mPointerGesture.spotIdBits); -} - void TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32_t source, int32_t action, int32_t flags, int32_t metaState, int32_t buttonState, int32_t edgeFlags, const PointerProperties* properties, const PointerCoords* coords, diff --git a/services/input/InputReader.h b/services/input/InputReader.h index 1d4ad87..36cd89c 100644 --- a/services/input/InputReader.h +++ b/services/input/InputReader.h @@ -101,8 +101,8 @@ struct InputReaderConfiguration { nsecs_t pointerGestureMultitouchSettleInterval; // The transition from PRESS to SWIPE or FREEFORM gesture mode is made when - // both of the pointers are moving at least this fast. - float pointerGestureMultitouchMinSpeed; // in pixels per second + // at least two pointers have moved at least this far from their starting place. + float pointerGestureMultitouchMinDistance; // in pixels // The transition from PRESS to SWIPE gesture mode can only occur when the // cosine of the angle between the two vectors is greater than or equal to than this value @@ -134,7 +134,7 @@ struct InputReaderConfiguration { filterTouchEvents(false), filterJumpyTouchEvents(false), virtualKeyQuietTime(0), - pointerVelocityControlParameters(1.0f, 80.0f, 400.0f, 4.0f), + pointerVelocityControlParameters(1.0f, 500.0f, 3000.0f, 3.0f), wheelVelocityControlParameters(1.0f, 15.0f, 50.0f, 4.0f), pointerGestureQuietInterval(100 * 1000000LL), // 100 ms pointerGestureDragMinSwitchSpeed(50), // 50 pixels per second @@ -142,10 +142,10 @@ struct InputReaderConfiguration { pointerGestureTapDragInterval(150 * 1000000LL), // 150 ms pointerGestureTapSlop(10.0f), // 10 pixels pointerGestureMultitouchSettleInterval(100 * 1000000LL), // 100 ms - pointerGestureMultitouchMinSpeed(150.0f), // 150 pixels per second + pointerGestureMultitouchMinDistance(15), // 15 pixels pointerGestureSwipeTransitionAngleCosine(0.5f), // cosine of 45degrees - pointerGestureSwipeMaxWidthRatio(0.333f), - pointerGestureMovementSpeedRatio(0.3f), + pointerGestureSwipeMaxWidthRatio(0.25f), + pointerGestureMovementSpeedRatio(0.8f), pointerGestureZoomSpeedRatio(0.3f) { } }; @@ -1140,12 +1140,6 @@ private: PointerProperties lastGestureProperties[MAX_POINTERS]; PointerCoords lastGestureCoords[MAX_POINTERS]; - // Pointer coords and ids for the current spots. - PointerControllerInterface::SpotGesture spotGesture; - BitSet32 spotIdBits; // same set of ids as touch ids - uint32_t spotIdToIndex[MAX_POINTER_ID + 1]; - PointerCoords spotCoords[MAX_POINTERS]; - // Time the pointer gesture last went down. nsecs_t downTime; @@ -1192,8 +1186,6 @@ private: currentGestureIdBits.clear(); lastGestureMode = NEUTRAL; lastGestureIdBits.clear(); - spotGesture = PointerControllerInterface::SPOT_GESTURE_NEUTRAL; - spotIdBits.clear(); downTime = 0; velocityTracker.clear(); resetTap(); @@ -1219,7 +1211,6 @@ private: void dispatchPointerGestures(nsecs_t when, uint32_t policyFlags, bool isTimeout); bool preparePointerGestures(nsecs_t when, bool* outCancelPreviousGesture, bool* outFinishPreviousGesture, bool isTimeout); - void moveSpotsLocked(); // Dispatches a motion event. // If the changedId is >= 0 and the action is POINTER_DOWN or POINTER_UP, the diff --git a/services/input/PointerController.cpp b/services/input/PointerController.cpp index c18ebcf..12c7cba 100644 --- a/services/input/PointerController.cpp +++ b/services/input/PointerController.cpp @@ -240,15 +240,15 @@ void PointerController::setPresentation(Presentation presentation) { } } -void PointerController::setSpots(SpotGesture spotGesture, - const PointerCoords* spotCoords, const uint32_t* spotIdToIndex, BitSet32 spotIdBits) { +void PointerController::setSpots(const PointerCoords* spotCoords, + const uint32_t* spotIdToIndex, BitSet32 spotIdBits) { #if DEBUG_POINTER_UPDATES - LOGD("setSpots: spotGesture=%d", spotGesture); + LOGD("setSpots: idBits=%08x", spotIdBits.value); for (BitSet32 idBits(spotIdBits); !idBits.isEmpty(); ) { uint32_t id = idBits.firstMarkedBit(); idBits.clearBit(id); const PointerCoords& c = spotCoords[spotIdToIndex[id]]; - LOGD(" spot %d: position=(%0.3f, %0.3f), pressure=%0.3f", id, + LOGD(" spot %d: position=(%0.3f, %0.3f), pressure=%0.3f", id, c.getAxisValue(AMOTION_EVENT_AXIS_X), c.getAxisValue(AMOTION_EVENT_AXIS_Y), c.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE)); diff --git a/services/input/PointerController.h b/services/input/PointerController.h index 1c21db1..700ef72 100644 --- a/services/input/PointerController.h +++ b/services/input/PointerController.h @@ -90,38 +90,6 @@ public: /* Sets the mode of the pointer controller. */ virtual void setPresentation(Presentation presentation) = 0; - // Describes the current gesture. - enum SpotGesture { - // No gesture. - // Do not display any spots. - SPOT_GESTURE_NEUTRAL, - // Tap at current location. - // Briefly display one spot at the tapped location. - SPOT_GESTURE_TAP, - // Drag at current location. - // Display spot at pressed location. - SPOT_GESTURE_DRAG, - // Button pressed but no finger is down. - // Display spot at pressed location. - SPOT_GESTURE_BUTTON_CLICK, - // Button pressed and a finger is down. - // Display spot at pressed location. - SPOT_GESTURE_BUTTON_DRAG, - // One finger down and hovering. - // Display spot at the hovered location. - SPOT_GESTURE_HOVER, - // Two fingers down but not sure in which direction they are moving so we consider - // it a press at the pointer location. - // Display two spots near the pointer location. - SPOT_GESTURE_PRESS, - // Two fingers down and moving in same direction. - // Display two spots near the pointer location. - SPOT_GESTURE_SWIPE, - // Two or more fingers down and moving in arbitrary directions. - // Display two or more spots near the pointer location, one for each finger. - SPOT_GESTURE_FREEFORM, - }; - /* Sets the spots for the current gesture. * The spots are not subject to the inactivity timeout like the pointer * itself it since they are expected to remain visible for so long as @@ -131,8 +99,7 @@ public: * For spotCoords, pressure != 0 indicates that the spot's location is being * pressed (not hovering). */ - virtual void setSpots(SpotGesture spotGesture, - const PointerCoords* spotCoords, const uint32_t* spotIdToIndex, + virtual void setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex, BitSet32 spotIdBits) = 0; /* Removes all spots. */ @@ -198,8 +165,8 @@ public: virtual void unfade(Transition transition); virtual void setPresentation(Presentation presentation); - virtual void setSpots(SpotGesture spotGesture, - const PointerCoords* spotCoords, const uint32_t* spotIdToIndex, BitSet32 spotIdBits); + virtual void setSpots(const PointerCoords* spotCoords, + const uint32_t* spotIdToIndex, BitSet32 spotIdBits); virtual void clearSpots(); void setDisplaySize(int32_t width, int32_t height); diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp index 00b4222..d04c9e7 100644 --- a/services/input/tests/InputReader_test.cpp +++ b/services/input/tests/InputReader_test.cpp @@ -101,8 +101,8 @@ private: virtual void setPresentation(Presentation presentation) { } - virtual void setSpots(SpotGesture spotGesture, - const PointerCoords* spotCoords, const uint32_t* spotIdToIndex, BitSet32 spotIdBits) { + virtual void setSpots(const PointerCoords* spotCoords, + const uint32_t* spotIdToIndex, BitSet32 spotIdBits) { } virtual void clearSpots() { |