diff options
author | Jeff Brown <jeffbrown@android.com> | 2011-05-25 19:15:24 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2011-05-25 19:15:24 -0700 |
commit | fa574c0e0ce7f84eea34e96dededea35329dbd18 (patch) | |
tree | f9b620d98b9703e032e57e467abaf0c8e5f93c0f /services | |
parent | 5665770bc4449a96f2365bec71fb012ca2e7bc81 (diff) | |
parent | 538881e18323a0c983bd8809f8c3b1cdeeeab8a6 (diff) | |
download | frameworks_base-fa574c0e0ce7f84eea34e96dededea35329dbd18.zip frameworks_base-fa574c0e0ce7f84eea34e96dededea35329dbd18.tar.gz frameworks_base-fa574c0e0ce7f84eea34e96dededea35329dbd18.tar.bz2 |
Merge "Touch pad UX improvements." into honeycomb-mr2
Diffstat (limited to 'services')
-rw-r--r-- | services/input/InputReader.cpp | 123 | ||||
-rw-r--r-- | services/input/InputReader.h | 8 | ||||
-rw-r--r-- | services/input/PointerController.cpp | 56 | ||||
-rw-r--r-- | services/input/PointerController.h | 19 | ||||
-rw-r--r-- | services/input/tests/InputReader_test.cpp | 4 |
5 files changed, 158 insertions, 52 deletions
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp index 853ceb3..cb69008 100644 --- a/services/input/InputReader.cpp +++ b/services/input/InputReader.cpp @@ -1627,7 +1627,7 @@ void CursorInputMapper::sync(nsecs_t when) { mPointerController->setButtonState(mLocked.buttonState); } - mPointerController->unfade(); + mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE); } float x, y; @@ -1686,7 +1686,7 @@ void CursorInputMapper::fadePointer() { { // acquire lock AutoMutex _l(mLock); if (mPointerController != NULL) { - mPointerController->fade(); + mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL); } } // release lock } @@ -1873,10 +1873,22 @@ void TouchInputMapper::configureParameters() { mParameters.useJumpyTouchFilter = getPolicy()->filterJumpyTouchEvents(); mParameters.virtualKeyQuietTime = getPolicy()->getVirtualKeyQuietTime(); - // TODO: Make this configurable. - //mParameters.gestureMode = Parameters::GESTURE_MODE_POINTER; + // TODO: select the default gesture mode based on whether the device supports + // distinct multitouch mParameters.gestureMode = Parameters::GESTURE_MODE_SPOTS; + String8 gestureModeString; + if (getDevice()->getConfiguration().tryGetProperty(String8("touch.gestureMode"), + gestureModeString)) { + if (gestureModeString == "pointer") { + mParameters.gestureMode = Parameters::GESTURE_MODE_POINTER; + } else if (gestureModeString == "spots") { + mParameters.gestureMode = Parameters::GESTURE_MODE_SPOTS; + } else if (gestureModeString != "default") { + LOGW("Invalid value for touch.gestureMode: '%s'", gestureModeString.string()); + } + } + if (getEventHub()->hasRelativeAxis(getDeviceId(), REL_X) || getEventHub()->hasRelativeAxis(getDeviceId(), REL_Y)) { // The device is a cursor device with a touch pad attached. @@ -1897,7 +1909,7 @@ void TouchInputMapper::configureParameters() { mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_PAD; } else if (deviceTypeString == "pointer") { mParameters.deviceType = Parameters::DEVICE_TYPE_POINTER; - } else { + } else if (deviceTypeString != "default") { LOGW("Invalid value for touch.deviceType: '%s'", deviceTypeString.string()); } } @@ -1915,6 +1927,17 @@ void TouchInputMapper::configureParameters() { void TouchInputMapper::dumpParameters(String8& dump) { dump.append(INDENT3 "Parameters:\n"); + switch (mParameters.gestureMode) { + case Parameters::GESTURE_MODE_POINTER: + dump.append(INDENT4 "GestureMode: pointer\n"); + break; + case Parameters::GESTURE_MODE_SPOTS: + dump.append(INDENT4 "GestureMode: spots\n"); + break; + default: + assert(false); + } + switch (mParameters.deviceType) { case Parameters::DEVICE_TYPE_TOUCH_SCREEN: dump.append(INDENT4 "DeviceType: touchScreen\n"); @@ -3251,10 +3274,36 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag return; } - // Show the pointer if needed. - if (mPointerGesture.currentGestureMode != PointerGesture::NEUTRAL - && mPointerGesture.currentGestureMode != PointerGesture::QUIET) { - mPointerController->unfade(); + // Show or hide the pointer if needed. + switch (mPointerGesture.currentGestureMode) { + case PointerGesture::NEUTRAL: + case PointerGesture::QUIET: + if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS + && (mPointerGesture.lastGestureMode == PointerGesture::SWIPE + || mPointerGesture.lastGestureMode == PointerGesture::FREEFORM)) { + // Remind the user of where the pointer is after finishing a gesture with spots. + mPointerController->unfade(PointerControllerInterface::TRANSITION_GRADUAL); + } + break; + case PointerGesture::TAP: + case PointerGesture::TAP_DRAG: + case PointerGesture::BUTTON_CLICK_OR_DRAG: + case PointerGesture::HOVER: + case PointerGesture::PRESS: + // Unfade the pointer when the current gesture manipulates the + // area directly under the pointer. + mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE); + break; + case PointerGesture::SWIPE: + case PointerGesture::FREEFORM: + // Fade the pointer when the current gesture manipulates a different + // area and there are spots to guide the user experience. + if (mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) { + mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL); + } else { + mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE); + } + break; } // Send events! @@ -3808,6 +3857,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, *outFinishPreviousGesture = true; mPointerGesture.currentGestureMode = PointerGesture::PRESS; mPointerGesture.activeGestureId = 0; + mPointerGesture.referenceIdBits.clear(); if (settled && mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS && mLastTouch.idBits.hasBit(mPointerGesture.activeTouchId)) { @@ -3938,6 +3988,17 @@ 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. @@ -3951,27 +4012,39 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when, const PointerData& cpd = mCurrentTouch.pointers[mCurrentTouch.idToIndex[id]]; const PointerData& lpd = mLastTouch.pointers[mLastTouch.idToIndex[id]]; - float deltaX = cpd.x - lpd.x; - float deltaY = cpd.y - lpd.y; + PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id]; + delta.dx += cpd.x - lpd.x; + delta.dy += cpd.y - lpd.y; if (first) { - commonDeltaX = deltaX; - commonDeltaY = deltaY; + commonDeltaX = delta.dx; + commonDeltaY = delta.dy; } else { - commonDeltaX = calculateCommonVector(commonDeltaX, deltaX); - commonDeltaY = calculateCommonVector(commonDeltaY, deltaY); + commonDeltaX = calculateCommonVector(commonDeltaX, delta.dx); + commonDeltaY = calculateCommonVector(commonDeltaY, delta.dy); } } - mPointerGesture.referenceTouchX += commonDeltaX; - mPointerGesture.referenceTouchY += commonDeltaY; - mPointerGesture.referenceGestureX += - commonDeltaX * mLocked.pointerGestureXMovementScale; - mPointerGesture.referenceGestureY += - commonDeltaY * mLocked.pointerGestureYMovementScale; - clampPositionUsingPointerBounds(mPointerController, - &mPointerGesture.referenceGestureX, - &mPointerGesture.referenceGestureY); + 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.referenceGestureX += + commonDeltaX * mLocked.pointerGestureXMovementScale; + mPointerGesture.referenceGestureY += + commonDeltaY * mLocked.pointerGestureYMovementScale; + clampPositionUsingPointerBounds(mPointerController, + &mPointerGesture.referenceGestureX, + &mPointerGesture.referenceGestureY); + } } // Report gestures. @@ -4255,7 +4328,7 @@ void TouchInputMapper::fadePointer() { { // acquire lock AutoMutex _l(mLock); if (mPointerController != NULL) { - mPointerController->fade(); + mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL); } } // release lock } diff --git a/services/input/InputReader.h b/services/input/InputReader.h index 0485617..0fbc93c 100644 --- a/services/input/InputReader.h +++ b/services/input/InputReader.h @@ -1021,6 +1021,14 @@ private: float referenceGestureX; // reference gesture X/Y coordinates in pixels float referenceGestureY; + // Distance that each pointer has traveled which has not yet been + // subsumed into the reference gesture position. + BitSet32 referenceIdBits; + struct Delta { + float dx, dy; + }; + Delta referenceDeltas[MAX_POINTER_ID + 1]; + // Describes how touch ids are mapped to gesture ids for freeform gestures. uint32_t freeformTouchToGestureIdMap[MAX_POINTER_ID + 1]; diff --git a/services/input/PointerController.cpp b/services/input/PointerController.cpp index ffef720..eecb76f 100644 --- a/services/input/PointerController.cpp +++ b/services/input/PointerController.cpp @@ -69,10 +69,10 @@ PointerController::PointerController(const sp<PointerControllerPolicyInterface>& mLocked.inactivityTimeout = INACTIVITY_TIMEOUT_NORMAL; - mLocked.pointerIsFading = true; // keep the pointer initially faded + mLocked.pointerFadeDirection = 0; mLocked.pointerX = 0; mLocked.pointerY = 0; - mLocked.pointerAlpha = 0.0f; + mLocked.pointerAlpha = 0.0f; // pointer is initially faded mLocked.pointerSprite = mSpriteController->createSprite(); mLocked.pointerIconChanged = false; @@ -191,23 +191,37 @@ void PointerController::getPosition(float* outX, float* outY) const { *outY = mLocked.pointerY; } -void PointerController::fade() { +void PointerController::fade(Transition transition) { AutoMutex _l(mLock); - sendImmediateInactivityTimeoutLocked(); + // Remove the inactivity timeout, since we are fading now. + removeInactivityTimeoutLocked(); + + // Start fading. + if (transition == TRANSITION_IMMEDIATE) { + mLocked.pointerFadeDirection = 0; + mLocked.pointerAlpha = 0.0f; + updatePointerLocked(); + } else { + mLocked.pointerFadeDirection = -1; + startAnimationLocked(); + } } -void PointerController::unfade() { +void PointerController::unfade(Transition transition) { AutoMutex _l(mLock); // Always reset the inactivity timer. resetInactivityTimeoutLocked(); - // Unfade immediately if needed. - if (mLocked.pointerIsFading) { - mLocked.pointerIsFading = false; + // Start unfading. + if (transition == TRANSITION_IMMEDIATE) { + mLocked.pointerFadeDirection = 0; mLocked.pointerAlpha = 1.0f; updatePointerLocked(); + } else { + mLocked.pointerFadeDirection = 1; + startAnimationLocked(); } } @@ -401,10 +415,20 @@ void PointerController::doAnimate() { nsecs_t frameDelay = systemTime(SYSTEM_TIME_MONOTONIC) - mLocked.animationTime; // Animate pointer fade. - if (mLocked.pointerIsFading) { + if (mLocked.pointerFadeDirection < 0) { mLocked.pointerAlpha -= float(frameDelay) / POINTER_FADE_DURATION; - if (mLocked.pointerAlpha <= 0) { - mLocked.pointerAlpha = 0; + if (mLocked.pointerAlpha <= 0.0f) { + mLocked.pointerAlpha = 0.0f; + mLocked.pointerFadeDirection = 0; + } else { + keepAnimating = true; + } + updatePointerLocked(); + } else if (mLocked.pointerFadeDirection > 0) { + mLocked.pointerAlpha += float(frameDelay) / POINTER_FADE_DURATION; + if (mLocked.pointerAlpha >= 1.0f) { + mLocked.pointerAlpha = 1.0f; + mLocked.pointerFadeDirection = 0; } else { keepAnimating = true; } @@ -432,12 +456,7 @@ void PointerController::doAnimate() { } void PointerController::doInactivityTimeout() { - AutoMutex _l(mLock); - - if (!mLocked.pointerIsFading) { - mLocked.pointerIsFading = true; - startAnimationLocked(); - } + fade(TRANSITION_GRADUAL); } void PointerController::startAnimationLocked() { @@ -456,9 +475,8 @@ void PointerController::resetInactivityTimeoutLocked() { mLooper->sendMessageDelayed(timeout, mHandler, MSG_INACTIVITY_TIMEOUT); } -void PointerController::sendImmediateInactivityTimeoutLocked() { +void PointerController::removeInactivityTimeoutLocked() { mLooper->removeMessages(mHandler, MSG_INACTIVITY_TIMEOUT); - mLooper->sendMessage(mHandler, MSG_INACTIVITY_TIMEOUT); } void PointerController::updatePointerLocked() { diff --git a/services/input/PointerController.h b/services/input/PointerController.h index b9184ac..d6e58c2 100644 --- a/services/input/PointerController.h +++ b/services/input/PointerController.h @@ -64,14 +64,21 @@ public: /* Gets the absolute location of the pointer. */ virtual void getPosition(float* outX, float* outY) const = 0; + enum Transition { + // Fade/unfade immediately. + TRANSITION_IMMEDIATE, + // Fade/unfade gradually. + TRANSITION_GRADUAL, + }; + /* Fades the pointer out now. */ - virtual void fade() = 0; + virtual void fade(Transition transition) = 0; /* Makes the pointer visible if it has faded out. * The pointer never unfades itself automatically. This method must be called * by the client whenever the pointer is moved or a button is pressed and it * wants to ensure that the pointer becomes visible again. */ - virtual void unfade() = 0; + virtual void unfade(Transition transition) = 0; enum Presentation { // Show the mouse pointer. @@ -187,8 +194,8 @@ public: virtual uint32_t getButtonState() const; virtual void setPosition(float x, float y); virtual void getPosition(float* outX, float* outY) const; - virtual void fade(); - virtual void unfade(); + virtual void fade(Transition transition); + virtual void unfade(Transition transition); virtual void setPresentation(Presentation presentation); virtual void setSpots(SpotGesture spotGesture, @@ -250,7 +257,7 @@ private: Presentation presentation; bool presentationChanged; - bool pointerIsFading; + int32_t pointerFadeDirection; float pointerX; float pointerY; float pointerAlpha; @@ -274,7 +281,7 @@ private: void startAnimationLocked(); void resetInactivityTimeoutLocked(); - void sendImmediateInactivityTimeoutLocked(); + void removeInactivityTimeoutLocked(); void updatePointerLocked(); Spot* getSpotLocked(uint32_t id); diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp index 1596e54..8b3e731 100644 --- a/services/input/tests/InputReader_test.cpp +++ b/services/input/tests/InputReader_test.cpp @@ -92,10 +92,10 @@ private: *outY = 0; } - virtual void fade() { + virtual void fade(Transition transition) { } - virtual void unfade() { + virtual void unfade(Transition transition) { } virtual void setPresentation(Presentation presentation) { |