summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@android.com>2011-05-25 19:15:24 -0700
committerAndroid (Google) Code Review <android-gerrit@google.com>2011-05-25 19:15:24 -0700
commitfa574c0e0ce7f84eea34e96dededea35329dbd18 (patch)
treef9b620d98b9703e032e57e467abaf0c8e5f93c0f /services
parent5665770bc4449a96f2365bec71fb012ca2e7bc81 (diff)
parent538881e18323a0c983bd8809f8c3b1cdeeeab8a6 (diff)
downloadframeworks_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.cpp123
-rw-r--r--services/input/InputReader.h8
-rw-r--r--services/input/PointerController.cpp56
-rw-r--r--services/input/PointerController.h19
-rw-r--r--services/input/tests/InputReader_test.cpp4
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) {