Loading core/java/android/view/ViewConfiguration.java +37 −3 Original line number Diff line number Diff line Loading @@ -111,6 +111,20 @@ public class ViewConfiguration { */ private static final int DOUBLE_TAP_TIMEOUT = 300; /** * Defines the maximum duration in milliseconds between a touch pad * touch and release for a given touch to be considered a tap (click) as * opposed to a hover movement gesture. */ private static final int HOVER_TAP_TIMEOUT = 150; /** * Defines the maximum distance in pixels that a touch pad touch can move * before being released for it to be considered a tap (click) as opposed * to a hover movement gesture. */ private static final int HOVER_TAP_SLOP = 20; /** * Defines the duration in milliseconds we want to display zoom controls in response * to a user panning within an application. Loading Loading @@ -388,6 +402,26 @@ public class ViewConfiguration { return DOUBLE_TAP_TIMEOUT; } /** * @return the maximum duration in milliseconds between a touch pad * touch and release for a given touch to be considered a tap (click) as * opposed to a hover movement gesture. * @hide */ public static int getHoverTapTimeout() { return HOVER_TAP_TIMEOUT; } /** * @return the maximum distance in pixels that a touch pad touch can move * before being released for it to be considered a tap (click) as opposed * to a hover movement gesture. * @hide */ public static int getHoverTapSlop() { return HOVER_TAP_SLOP; } /** * @return Inset in pixels to look for touchable content when the user touches the edge of the * screen Loading services/input/InputReader.cpp +173 −155 Original line number Diff line number Diff line Loading @@ -36,6 +36,12 @@ // Log debug messages about gesture detection. #define DEBUG_GESTURES 0 // Specifies whether spots follow fingers or touch points. // If 1, show exactly one spot per finger in multitouch gestures. // If 0, show exactly one spot per generated touch point in multitouch gestures, so the // spots indicate exactly which points on screen are being touched. #define SPOT_FOLLOWS_FINGER 0 #include "InputReader.h" #include <cutils/atomic.h> Loading Loading @@ -200,23 +206,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; Loading Loading @@ -787,8 +776,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", Loading Loading @@ -3509,11 +3498,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.spotGesture, mPointerGesture.spotCoords, mPointerGesture.spotIdToIndex, mPointerGesture.spotIdBits); } else { mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER); } // Show or hide the pointer if needed. switch (mPointerGesture.currentGestureMode) { Loading Loading @@ -3716,7 +3712,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) { mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_NEUTRAL; mPointerGesture.spotIdBits.clear(); moveSpotsLocked(); } return true; } Loading Loading @@ -3798,10 +3793,12 @@ 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 if (mPointerGesture.lastGestureMode != PointerGesture::QUIET) { *outFinishPreviousGesture = true; } mPointerGesture.activeGestureId = -1; mPointerGesture.currentGestureMode = PointerGesture::QUIET; Loading @@ -3812,7 +3809,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, 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) Loading Loading @@ -3920,11 +3916,12 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, 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) 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. Loading Loading @@ -3971,7 +3968,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, mPointerGesture.spotIdBits.markBit(lastActiveTouchId); mPointerGesture.spotIdToIndex[lastActiveTouchId] = 0; mPointerGesture.spotCoords[0] = mPointerGesture.currentGestureCoords[0]; moveSpotsLocked(); } tapped = true; Loading Loading @@ -4003,7 +3999,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) { mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_NEUTRAL; mPointerGesture.spotIdBits.clear(); moveSpotsLocked(); } } } else if (mCurrentTouch.pointerCount == 1) { Loading Loading @@ -4067,7 +4062,9 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, #if DEBUG_GESTURES LOGD("Gestures: HOVER"); #endif if (mPointerGesture.lastGestureMode != PointerGesture::HOVER) { *outFinishPreviousGesture = true; } mPointerGesture.activeGestureId = 0; down = false; } Loading Loading @@ -4102,7 +4099,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, 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) Loading Loading @@ -4131,8 +4127,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; Loading @@ -4153,8 +4149,8 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, // for the gesture. Other spots will be positioned relative to this one. #if DEBUG_GESTURES LOGD("Gestures: Using active spot as reference for MULTITOUCH, " "settle time expired %0.3fms ago", (when - mPointerGesture.firstTouchTime - MULTITOUCH_SETTLE_INTERVAL) "settle time expired %0.3fms ago", (when - mPointerGesture.firstTouchTime - mConfig->pointerGestureMultitouchSettleInterval) * 0.000001f); #endif const PointerData& d = mLastTouch.pointers[mLastTouch.idToIndex[ Loading @@ -4169,8 +4165,8 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, // 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) "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime + mConfig->pointerGestureMultitouchSettleInterval - when) * 0.000001f); #endif mCurrentTouch.getCentroid(&mPointerGesture.referenceTouchX, Loading @@ -4180,7 +4176,59 @@ 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; // 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 { commonDeltaX = calculateCommonVector(commonDeltaX, delta.dx); commonDeltaY = calculateCommonVector(commonDeltaY, delta.dy); } } // Consider transitions from PRESS to SWIPE or MULTITOUCH. if (mPointerGesture.currentGestureMode == PointerGesture::PRESS) { 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. Loading @@ -4194,7 +4242,8 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, 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. // 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); Loading @@ -4206,45 +4255,45 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, // 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. 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). float dot = vx1 * vx2 + vy1 * vy2; float cosine = dot / (speed1 * speed2); // denominator always > 0 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, " "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, " "cosine %0.3f >= %0.3f", speed1, MULTITOUCH_MIN_SPEED, speed2, MULTITOUCH_MIN_SPEED, cosine, SWIPE_TRANSITION_ANGLE_COSINE); dist1, mConfig->pointerGestureMultitouchMinDistance, dist2, mConfig->pointerGestureMultitouchMinDistance, cosine, mConfig->pointerGestureSwipeTransitionAngleCosine); #endif 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, " "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, " "cosine %0.3f < %0.3f", speed1, MULTITOUCH_MIN_SPEED, speed2, MULTITOUCH_MIN_SPEED, cosine, SWIPE_TRANSITION_ANGLE_COSINE); dist1, mConfig->pointerGestureMultitouchMinDistance, dist2, mConfig->pointerGestureMultitouchMinDistance, cosine, mConfig->pointerGestureSwipeTransitionAngleCosine); #endif *outCancelPreviousGesture = true; mPointerGesture.currentGestureMode = PointerGesture::FREEFORM; } } } } } else if (mPointerGesture.currentGestureMode == PointerGesture::SWIPE) { // Switch from SWIPE to FREEFORM if additional pointers go down. // Cancel previous gesture. Loading @@ -4258,45 +4307,11 @@ 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); 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); } } if (commonDeltaX || commonDeltaY) { for (BitSet32 idBits(commonIdBits); !idBits.isEmpty(); ) { // 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); Loading @@ -4314,11 +4329,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, mPointerGesture.referenceGestureX += commonDeltaX; mPointerGesture.referenceGestureY += commonDeltaY; clampPositionUsingPointerBounds(mPointerController, &mPointerGesture.referenceGestureX, &mPointerGesture.referenceGestureY); } } // Report gestures. Loading Loading @@ -4482,9 +4492,10 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, } // 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) { #if SPOT_FOLLOWS_FINGER // Use the same calculation as we do to calculate the gesture pointers // for FREEFORM so that the spots smoothly track fingers across gestures. mPointerGesture.spotIdBits.clear(); for (uint32_t i = 0; i < mCurrentTouch.pointerCount; i++) { uint32_t id = mCurrentTouch.pointers[i].id; Loading @@ -4501,7 +4512,19 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, mPointerGesture.spotCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, y); mPointerGesture.spotCoords[i].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f); } moveSpotsLocked(); #else // Show one spot per generated touch point. // This may cause apparent discontinuities in spot motion when transitioning // from PRESS to FREEFORM. mPointerGesture.spotIdBits = mPointerGesture.currentGestureIdBits; for (BitSet32 idBits(mPointerGesture.currentGestureIdBits); !idBits.isEmpty(); ) { uint32_t id = idBits.firstMarkedBit(); idBits.clearBit(id); uint32_t index = mPointerGesture.currentGestureIdToIndex[id]; mPointerGesture.spotIdToIndex[id] = index; mPointerGesture.spotCoords[index] = mPointerGesture.currentGestureCoords[index]; } #endif } } Loading Loading @@ -4544,11 +4567,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, Loading services/input/InputReader.h +6 −7 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading @@ -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) { } }; Loading Loading @@ -1219,7 +1219,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 Loading services/java/com/android/server/wm/InputManager.java +7 −7 Original line number Diff line number Diff line Loading @@ -617,8 +617,13 @@ public class InputManager { } @SuppressWarnings("unused") public int getTapTimeout() { return ViewConfiguration.getTapTimeout(); public int getHoverTapTimeout() { return ViewConfiguration.getHoverTapTimeout(); } @SuppressWarnings("unused") public int getHoverTapSlop() { return ViewConfiguration.getHoverTapSlop(); } @SuppressWarnings("unused") Loading @@ -631,11 +636,6 @@ public class InputManager { return ViewConfiguration.getLongPressTimeout(); } @SuppressWarnings("unused") public int getTouchSlop() { return ViewConfiguration.get(mContext).getScaledTouchSlop(); } @SuppressWarnings("unused") public int getMaxEventsPerSecond() { int result = 0; Loading Loading
core/java/android/view/ViewConfiguration.java +37 −3 Original line number Diff line number Diff line Loading @@ -111,6 +111,20 @@ public class ViewConfiguration { */ private static final int DOUBLE_TAP_TIMEOUT = 300; /** * Defines the maximum duration in milliseconds between a touch pad * touch and release for a given touch to be considered a tap (click) as * opposed to a hover movement gesture. */ private static final int HOVER_TAP_TIMEOUT = 150; /** * Defines the maximum distance in pixels that a touch pad touch can move * before being released for it to be considered a tap (click) as opposed * to a hover movement gesture. */ private static final int HOVER_TAP_SLOP = 20; /** * Defines the duration in milliseconds we want to display zoom controls in response * to a user panning within an application. Loading Loading @@ -388,6 +402,26 @@ public class ViewConfiguration { return DOUBLE_TAP_TIMEOUT; } /** * @return the maximum duration in milliseconds between a touch pad * touch and release for a given touch to be considered a tap (click) as * opposed to a hover movement gesture. * @hide */ public static int getHoverTapTimeout() { return HOVER_TAP_TIMEOUT; } /** * @return the maximum distance in pixels that a touch pad touch can move * before being released for it to be considered a tap (click) as opposed * to a hover movement gesture. * @hide */ public static int getHoverTapSlop() { return HOVER_TAP_SLOP; } /** * @return Inset in pixels to look for touchable content when the user touches the edge of the * screen Loading
services/input/InputReader.cpp +173 −155 Original line number Diff line number Diff line Loading @@ -36,6 +36,12 @@ // Log debug messages about gesture detection. #define DEBUG_GESTURES 0 // Specifies whether spots follow fingers or touch points. // If 1, show exactly one spot per finger in multitouch gestures. // If 0, show exactly one spot per generated touch point in multitouch gestures, so the // spots indicate exactly which points on screen are being touched. #define SPOT_FOLLOWS_FINGER 0 #include "InputReader.h" #include <cutils/atomic.h> Loading Loading @@ -200,23 +206,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; Loading Loading @@ -787,8 +776,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", Loading Loading @@ -3509,11 +3498,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.spotGesture, mPointerGesture.spotCoords, mPointerGesture.spotIdToIndex, mPointerGesture.spotIdBits); } else { mPointerController->setPresentation(PointerControllerInterface::PRESENTATION_POINTER); } // Show or hide the pointer if needed. switch (mPointerGesture.currentGestureMode) { Loading Loading @@ -3716,7 +3712,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) { mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_NEUTRAL; mPointerGesture.spotIdBits.clear(); moveSpotsLocked(); } return true; } Loading Loading @@ -3798,10 +3793,12 @@ 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 if (mPointerGesture.lastGestureMode != PointerGesture::QUIET) { *outFinishPreviousGesture = true; } mPointerGesture.activeGestureId = -1; mPointerGesture.currentGestureMode = PointerGesture::QUIET; Loading @@ -3812,7 +3809,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, 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) Loading Loading @@ -3920,11 +3916,12 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, 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) 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. Loading Loading @@ -3971,7 +3968,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, mPointerGesture.spotIdBits.markBit(lastActiveTouchId); mPointerGesture.spotIdToIndex[lastActiveTouchId] = 0; mPointerGesture.spotCoords[0] = mPointerGesture.currentGestureCoords[0]; moveSpotsLocked(); } tapped = true; Loading Loading @@ -4003,7 +3999,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) { mPointerGesture.spotGesture = PointerControllerInterface::SPOT_GESTURE_NEUTRAL; mPointerGesture.spotIdBits.clear(); moveSpotsLocked(); } } } else if (mCurrentTouch.pointerCount == 1) { Loading Loading @@ -4067,7 +4062,9 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, #if DEBUG_GESTURES LOGD("Gestures: HOVER"); #endif if (mPointerGesture.lastGestureMode != PointerGesture::HOVER) { *outFinishPreviousGesture = true; } mPointerGesture.activeGestureId = 0; down = false; } Loading Loading @@ -4102,7 +4099,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, 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) Loading Loading @@ -4131,8 +4127,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; Loading @@ -4153,8 +4149,8 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, // for the gesture. Other spots will be positioned relative to this one. #if DEBUG_GESTURES LOGD("Gestures: Using active spot as reference for MULTITOUCH, " "settle time expired %0.3fms ago", (when - mPointerGesture.firstTouchTime - MULTITOUCH_SETTLE_INTERVAL) "settle time expired %0.3fms ago", (when - mPointerGesture.firstTouchTime - mConfig->pointerGestureMultitouchSettleInterval) * 0.000001f); #endif const PointerData& d = mLastTouch.pointers[mLastTouch.idToIndex[ Loading @@ -4169,8 +4165,8 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, // 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) "settle time remaining %0.3fms", (mPointerGesture.firstTouchTime + mConfig->pointerGestureMultitouchSettleInterval - when) * 0.000001f); #endif mCurrentTouch.getCentroid(&mPointerGesture.referenceTouchX, Loading @@ -4180,7 +4176,59 @@ 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; // 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 { commonDeltaX = calculateCommonVector(commonDeltaX, delta.dx); commonDeltaY = calculateCommonVector(commonDeltaY, delta.dy); } } // Consider transitions from PRESS to SWIPE or MULTITOUCH. if (mPointerGesture.currentGestureMode == PointerGesture::PRESS) { 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. Loading @@ -4194,7 +4242,8 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, 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. // 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); Loading @@ -4206,45 +4255,45 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, // 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. 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). float dot = vx1 * vx2 + vy1 * vy2; float cosine = dot / (speed1 * speed2); // denominator always > 0 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, " "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, " "cosine %0.3f >= %0.3f", speed1, MULTITOUCH_MIN_SPEED, speed2, MULTITOUCH_MIN_SPEED, cosine, SWIPE_TRANSITION_ANGLE_COSINE); dist1, mConfig->pointerGestureMultitouchMinDistance, dist2, mConfig->pointerGestureMultitouchMinDistance, cosine, mConfig->pointerGestureSwipeTransitionAngleCosine); #endif 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, " "dist1 %0.3f >= %0.3f, dist2 %0.3f >= %0.3f, " "cosine %0.3f < %0.3f", speed1, MULTITOUCH_MIN_SPEED, speed2, MULTITOUCH_MIN_SPEED, cosine, SWIPE_TRANSITION_ANGLE_COSINE); dist1, mConfig->pointerGestureMultitouchMinDistance, dist2, mConfig->pointerGestureMultitouchMinDistance, cosine, mConfig->pointerGestureSwipeTransitionAngleCosine); #endif *outCancelPreviousGesture = true; mPointerGesture.currentGestureMode = PointerGesture::FREEFORM; } } } } } else if (mPointerGesture.currentGestureMode == PointerGesture::SWIPE) { // Switch from SWIPE to FREEFORM if additional pointers go down. // Cancel previous gesture. Loading @@ -4258,45 +4307,11 @@ 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); 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); } } if (commonDeltaX || commonDeltaY) { for (BitSet32 idBits(commonIdBits); !idBits.isEmpty(); ) { // 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); Loading @@ -4314,11 +4329,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, mPointerGesture.referenceGestureX += commonDeltaX; mPointerGesture.referenceGestureY += commonDeltaY; clampPositionUsingPointerBounds(mPointerController, &mPointerGesture.referenceGestureX, &mPointerGesture.referenceGestureY); } } // Report gestures. Loading Loading @@ -4482,9 +4492,10 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, } // 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) { #if SPOT_FOLLOWS_FINGER // Use the same calculation as we do to calculate the gesture pointers // for FREEFORM so that the spots smoothly track fingers across gestures. mPointerGesture.spotIdBits.clear(); for (uint32_t i = 0; i < mCurrentTouch.pointerCount; i++) { uint32_t id = mCurrentTouch.pointers[i].id; Loading @@ -4501,7 +4512,19 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, mPointerGesture.spotCoords[i].setAxisValue(AMOTION_EVENT_AXIS_Y, y); mPointerGesture.spotCoords[i].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f); } moveSpotsLocked(); #else // Show one spot per generated touch point. // This may cause apparent discontinuities in spot motion when transitioning // from PRESS to FREEFORM. mPointerGesture.spotIdBits = mPointerGesture.currentGestureIdBits; for (BitSet32 idBits(mPointerGesture.currentGestureIdBits); !idBits.isEmpty(); ) { uint32_t id = idBits.firstMarkedBit(); idBits.clearBit(id); uint32_t index = mPointerGesture.currentGestureIdToIndex[id]; mPointerGesture.spotIdToIndex[id] = index; mPointerGesture.spotCoords[index] = mPointerGesture.currentGestureCoords[index]; } #endif } } Loading Loading @@ -4544,11 +4567,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, Loading
services/input/InputReader.h +6 −7 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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 Loading @@ -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) { } }; Loading Loading @@ -1219,7 +1219,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 Loading
services/java/com/android/server/wm/InputManager.java +7 −7 Original line number Diff line number Diff line Loading @@ -617,8 +617,13 @@ public class InputManager { } @SuppressWarnings("unused") public int getTapTimeout() { return ViewConfiguration.getTapTimeout(); public int getHoverTapTimeout() { return ViewConfiguration.getHoverTapTimeout(); } @SuppressWarnings("unused") public int getHoverTapSlop() { return ViewConfiguration.getHoverTapSlop(); } @SuppressWarnings("unused") Loading @@ -631,11 +636,6 @@ public class InputManager { return ViewConfiguration.getLongPressTimeout(); } @SuppressWarnings("unused") public int getTouchSlop() { return ViewConfiguration.get(mContext).getScaledTouchSlop(); } @SuppressWarnings("unused") public int getMaxEventsPerSecond() { int result = 0; Loading