summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
authorJeff Brown <jeffbrown@google.com>2011-06-14 20:22:50 -0700
committerJeff Brown <jeffbrown@google.com>2011-06-14 22:07:31 -0700
commit474dcb5c3ddff737c4ac9fc44a1f7be569605e5f (patch)
tree5fc1710768966b240ded5e6e62e51f77d7e57c55 /services
parent93fa9b30b91f75ee161d0791ff17f98d1a603812 (diff)
downloadframeworks_base-474dcb5c3ddff737c4ac9fc44a1f7be569605e5f.zip
frameworks_base-474dcb5c3ddff737c4ac9fc44a1f7be569605e5f.tar.gz
frameworks_base-474dcb5c3ddff737c4ac9fc44a1f7be569605e5f.tar.bz2
Add support for disabling pointer gestures.
Made it possible for individual windows to disable pointer gestures while the window has focus using a private API. Cleaned up the InputReader configuration code to enable in-place reconfiguration of input devices without having to reopen them all. This change makes changing the pointer speed somewhat nicer since the pointer doesn't jump back to the origin after each change. Change-Id: I9727419c2f4cb39e16acb4b15fd7fd84526b1239
Diffstat (limited to 'services')
-rw-r--r--services/input/InputDispatcher.cpp1
-rw-r--r--services/input/InputReader.cpp455
-rw-r--r--services/input/InputReader.h45
-rw-r--r--services/input/InputWindow.h5
-rw-r--r--services/input/tests/InputReader_test.cpp19
-rw-r--r--services/java/com/android/server/wm/InputMonitor.java5
-rw-r--r--services/java/com/android/server/wm/InputWindow.java3
-rw-r--r--services/jni/com_android_server_InputManager.cpp37
-rw-r--r--services/jni/com_android_server_InputWindow.cpp6
9 files changed, 344 insertions, 232 deletions
diff --git a/services/input/InputDispatcher.cpp b/services/input/InputDispatcher.cpp
index 28df3fb..4a50d8a 100644
--- a/services/input/InputDispatcher.cpp
+++ b/services/input/InputDispatcher.cpp
@@ -3395,6 +3395,7 @@ void InputDispatcher::dumpDispatchStateLocked(String8& dump) {
window.frameRight, window.frameBottom,
window.scaleFactor);
dumpRegion(dump, window.touchableRegion);
+ dump.appendFormat(", inputFeatures=0x%08x", window.inputFeatures);
dump.appendFormat(", ownerPid=%d, ownerUid=%d, dispatchingTimeout=%0.3fms\n",
window.ownerPid, window.ownerUid,
window.dispatchingTimeout / 1000000.0);
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index 2b61570..3e4c666 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -38,7 +38,6 @@
#include "InputReader.h"
-#include <cutils/atomic.h>
#include <cutils/log.h>
#include <ui/Keyboard.h>
#include <ui/VirtualKeyMap.h>
@@ -245,8 +244,8 @@ InputReader::InputReader(const sp<EventHubInterface>& eventHub,
const sp<InputDispatcherInterface>& dispatcher) :
mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher),
mGlobalMetaState(0), mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),
- mRefreshConfiguration(0) {
- configure(true /*firstTime*/);
+ mConfigurationChangesToRefresh(0) {
+ refreshConfiguration(0);
updateGlobalMetaState();
updateInputConfiguration();
}
@@ -258,9 +257,16 @@ InputReader::~InputReader() {
}
void InputReader::loopOnce() {
- if (android_atomic_acquire_load(&mRefreshConfiguration)) {
- android_atomic_release_store(0, &mRefreshConfiguration);
- configure(false /*firstTime*/);
+ uint32_t changes;
+ { // acquire lock
+ AutoMutex _l(mStateLock);
+
+ changes = mConfigurationChangesToRefresh;
+ mConfigurationChangesToRefresh = 0;
+ } // release lock
+
+ if (changes) {
+ refreshConfiguration(changes);
}
int32_t timeoutMillis = -1;
@@ -326,7 +332,7 @@ void InputReader::addDevice(int32_t deviceId) {
uint32_t classes = mEventHub->getDeviceClasses(deviceId);
InputDevice* device = createDevice(deviceId, name, classes);
- device->configure();
+ device->configure(&mConfig, 0);
if (device->isIgnored()) {
LOGI("Device added: id=%d, name='%s' (ignored non-input device)", deviceId, name.string());
@@ -483,12 +489,25 @@ void InputReader::handleConfigurationChanged(nsecs_t when) {
mDispatcher->notifyConfigurationChanged(when);
}
-void InputReader::configure(bool firstTime) {
+void InputReader::refreshConfiguration(uint32_t changes) {
mPolicy->getReaderConfiguration(&mConfig);
mEventHub->setExcludedDevices(mConfig.excludedDeviceNames);
- if (!firstTime) {
- mEventHub->requestReopenDevices();
+ if (changes) {
+ LOGI("Reconfiguring input devices. changes=0x%08x", changes);
+
+ if (changes & InputReaderConfiguration::CHANGE_MUST_REOPEN) {
+ mEventHub->requestReopenDevices();
+ } else {
+ { // acquire device registry reader lock
+ RWLock::AutoRLock _rl(mDeviceRegistryLock);
+
+ for (size_t i = 0; i < mDevices.size(); i++) {
+ InputDevice* device = mDevices.valueAt(i);
+ device->configure(&mConfig, changes);
+ }
+ } // release device registry reader lock
+ }
}
}
@@ -709,10 +728,20 @@ bool InputReader::markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, s
} // release device registy reader lock
}
-void InputReader::refreshConfiguration() {
- android_atomic_release_store(1, &mRefreshConfiguration);
+void InputReader::requestRefreshConfiguration(uint32_t changes) {
+ if (changes) {
+ bool needWake;
+ { // acquire lock
+ AutoMutex _l(mStateLock);
+
+ needWake = !mConfigurationChangesToRefresh;
+ mConfigurationChangesToRefresh |= changes;
+ } // release lock
- mEventHub->wake();
+ if (needWake) {
+ mEventHub->wake();
+ }
+ }
}
void InputReader::dump(String8& dump) {
@@ -760,6 +789,8 @@ void InputReader::dump(String8& dump) {
mConfig.wheelVelocityControlParameters.acceleration);
dump.appendFormat(INDENT2 "PointerGesture:\n");
+ dump.appendFormat(INDENT3 "Enabled: %s\n",
+ toString(mConfig.pointerGesturesEnabled));
dump.appendFormat(INDENT3 "QuietInterval: %0.1fms\n",
mConfig.pointerGestureQuietInterval * 0.000001f);
dump.appendFormat(INDENT3 "DragMinSwitchSpeed: %0.1fpx/s\n",
@@ -855,18 +886,20 @@ void InputDevice::addMapper(InputMapper* mapper) {
mMappers.add(mapper);
}
-void InputDevice::configure() {
- if (! isIgnored()) {
- mContext->getEventHub()->getConfiguration(mId, &mConfiguration);
- }
-
+void InputDevice::configure(const InputReaderConfiguration* config, uint32_t changes) {
mSources = 0;
- size_t numMappers = mMappers.size();
- for (size_t i = 0; i < numMappers; i++) {
- InputMapper* mapper = mMappers[i];
- mapper->configure();
- mSources |= mapper->getSources();
+ if (!isIgnored()) {
+ if (!changes) { // first time only
+ mContext->getEventHub()->getConfiguration(mId, &mConfiguration);
+ }
+
+ size_t numMappers = mMappers.size();
+ for (size_t i = 0; i < numMappers; i++) {
+ InputMapper* mapper = mMappers[i];
+ mapper->configure(config, changes);
+ mSources |= mapper->getSources();
+ }
}
}
@@ -1010,7 +1043,7 @@ void InputMapper::populateDeviceInfo(InputDeviceInfo* info) {
void InputMapper::dump(String8& dump) {
}
-void InputMapper::configure() {
+void InputMapper::configure(const InputReaderConfiguration* config, uint32_t changes) {
}
void InputMapper::reset() {
@@ -1124,16 +1157,18 @@ void KeyboardInputMapper::dump(String8& dump) {
}
-void KeyboardInputMapper::configure() {
- InputMapper::configure();
+void KeyboardInputMapper::configure(const InputReaderConfiguration* config, uint32_t changes) {
+ InputMapper::configure(config, changes);
- // Configure basic parameters.
- configureParameters();
+ if (!changes) { // first time only
+ // Configure basic parameters.
+ configureParameters();
- // Reset LEDs.
- {
- AutoMutex _l(mLock);
- resetLedStateLocked();
+ // Reset LEDs.
+ {
+ AutoMutex _l(mLock);
+ resetLedStateLocked();
+ }
}
}
@@ -1411,40 +1446,44 @@ void CursorInputMapper::dump(String8& dump) {
} // release lock
}
-void CursorInputMapper::configure() {
- InputMapper::configure();
+void CursorInputMapper::configure(const InputReaderConfiguration* config, uint32_t changes) {
+ InputMapper::configure(config, changes);
- // Configure basic parameters.
- configureParameters();
+ if (!changes) { // first time only
+ // Configure basic parameters.
+ configureParameters();
- // Configure device mode.
- switch (mParameters.mode) {
- case Parameters::MODE_POINTER:
- mSource = AINPUT_SOURCE_MOUSE;
- mXPrecision = 1.0f;
- mYPrecision = 1.0f;
- mXScale = 1.0f;
- mYScale = 1.0f;
- mPointerController = getPolicy()->obtainPointerController(getDeviceId());
- break;
- case Parameters::MODE_NAVIGATION:
- mSource = AINPUT_SOURCE_TRACKBALL;
- mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
- mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
- mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
- mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
- break;
- }
+ // Configure device mode.
+ switch (mParameters.mode) {
+ case Parameters::MODE_POINTER:
+ mSource = AINPUT_SOURCE_MOUSE;
+ mXPrecision = 1.0f;
+ mYPrecision = 1.0f;
+ mXScale = 1.0f;
+ mYScale = 1.0f;
+ mPointerController = getPolicy()->obtainPointerController(getDeviceId());
+ break;
+ case Parameters::MODE_NAVIGATION:
+ mSource = AINPUT_SOURCE_TRACKBALL;
+ mXPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
+ mYPrecision = TRACKBALL_MOVEMENT_THRESHOLD;
+ mXScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
+ mYScale = 1.0f / TRACKBALL_MOVEMENT_THRESHOLD;
+ break;
+ }
- mVWheelScale = 1.0f;
- mHWheelScale = 1.0f;
+ mVWheelScale = 1.0f;
+ mHWheelScale = 1.0f;
- mHaveVWheel = getEventHub()->hasRelativeAxis(getDeviceId(), REL_WHEEL);
- mHaveHWheel = getEventHub()->hasRelativeAxis(getDeviceId(), REL_HWHEEL);
+ mHaveVWheel = getEventHub()->hasRelativeAxis(getDeviceId(), REL_WHEEL);
+ mHaveHWheel = getEventHub()->hasRelativeAxis(getDeviceId(), REL_HWHEEL);
+ }
- mPointerVelocityControl.setParameters(getConfig()->pointerVelocityControlParameters);
- mWheelXVelocityControl.setParameters(getConfig()->wheelVelocityControlParameters);
- mWheelYVelocityControl.setParameters(getConfig()->wheelVelocityControlParameters);
+ if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
+ mPointerVelocityControl.setParameters(config->pointerVelocityControlParameters);
+ mWheelXVelocityControl.setParameters(config->wheelVelocityControlParameters);
+ mWheelYVelocityControl.setParameters(config->wheelVelocityControlParameters);
+ }
}
void CursorInputMapper::configureParameters() {
@@ -1787,8 +1826,6 @@ void CursorInputMapper::fadePointer() {
TouchInputMapper::TouchInputMapper(InputDevice* device) :
InputMapper(device) {
- mConfig = getConfig();
-
mLocked.surfaceOrientation = -1;
mLocked.surfaceWidth = -1;
mLocked.surfaceHeight = -1;
@@ -1925,52 +1962,65 @@ void TouchInputMapper::initializeLocked() {
mLocked.orientedRanges.haveDistance = false;
mPointerGesture.reset();
- mPointerGesture.pointerVelocityControl.setParameters(mConfig->pointerVelocityControlParameters);
}
-void TouchInputMapper::configure() {
- InputMapper::configure();
+void TouchInputMapper::configure(const InputReaderConfiguration* config, uint32_t changes) {
+ InputMapper::configure(config, changes);
- // Configure basic parameters.
- configureParameters();
+ mConfig = *config;
- // Configure sources.
- switch (mParameters.deviceType) {
- case Parameters::DEVICE_TYPE_TOUCH_SCREEN:
- mTouchSource = AINPUT_SOURCE_TOUCHSCREEN;
- mPointerSource = 0;
- break;
- case Parameters::DEVICE_TYPE_TOUCH_PAD:
- mTouchSource = AINPUT_SOURCE_TOUCHPAD;
- mPointerSource = 0;
- break;
- case Parameters::DEVICE_TYPE_POINTER:
- mTouchSource = AINPUT_SOURCE_TOUCHPAD;
- mPointerSource = AINPUT_SOURCE_MOUSE;
- break;
- default:
- LOG_ASSERT(false);
- }
+ if (!changes) { // first time only
+ // Configure basic parameters.
+ configureParameters();
+
+ // Configure sources.
+ switch (mParameters.deviceType) {
+ case Parameters::DEVICE_TYPE_TOUCH_SCREEN:
+ mTouchSource = AINPUT_SOURCE_TOUCHSCREEN;
+ mPointerSource = 0;
+ break;
+ case Parameters::DEVICE_TYPE_TOUCH_PAD:
+ mTouchSource = AINPUT_SOURCE_TOUCHPAD;
+ mPointerSource = 0;
+ break;
+ case Parameters::DEVICE_TYPE_POINTER:
+ mTouchSource = AINPUT_SOURCE_TOUCHPAD;
+ mPointerSource = AINPUT_SOURCE_MOUSE;
+ break;
+ default:
+ LOG_ASSERT(false);
+ }
- // Configure absolute axis information.
- configureRawAxes();
+ // Configure absolute axis information.
+ configureRawAxes();
- // Prepare input device calibration.
- parseCalibration();
- resolveCalibration();
+ // Prepare input device calibration.
+ parseCalibration();
+ resolveCalibration();
- { // acquire lock
- AutoMutex _l(mLock);
+ { // acquire lock
+ AutoMutex _l(mLock);
- // Configure surface dimensions and orientation.
- configureSurfaceLocked();
- } // release lock
+ // Configure surface dimensions and orientation.
+ configureSurfaceLocked();
+ } // release lock
+ }
+
+ if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
+ mPointerGesture.pointerVelocityControl.setParameters(
+ mConfig.pointerVelocityControlParameters);
+ }
+
+ if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_GESTURE_ENABLEMENT)) {
+ // Reset the touch screen when pointer gesture enablement changes.
+ reset();
+ }
}
void TouchInputMapper::configureParameters() {
- mParameters.useBadTouchFilter = mConfig->filterTouchEvents;
- mParameters.useAveragingTouchFilter = mConfig->filterTouchEvents;
- mParameters.useJumpyTouchFilter = mConfig->filterJumpyTouchEvents;
+ mParameters.useBadTouchFilter = mConfig.filterTouchEvents;
+ mParameters.useAveragingTouchFilter = mConfig.filterTouchEvents;
+ mParameters.useJumpyTouchFilter = mConfig.filterJumpyTouchEvents;
// Use the pointer presentation mode for devices that do not support distinct
// multitouch. The spot-based presentation relies on being able to accurately
@@ -2401,14 +2451,14 @@ bool TouchInputMapper::configureSurfaceLocked() {
// is applied.
// Assume that the touch pad has a square aspect ratio such that movements in
// X and Y of the same number of raw units cover the same physical distance.
- mLocked.pointerGestureXMovementScale = mConfig->pointerGestureMovementSpeedRatio
+ mLocked.pointerGestureXMovementScale = mConfig.pointerGestureMovementSpeedRatio
* displayDiagonal / rawDiagonal;
mLocked.pointerGestureYMovementScale = mLocked.pointerGestureXMovementScale;
// Scale zooms to cover a smaller range of the display than movements do.
// This value determines the area around the pointer that is affected by freeform
// pointer gestures.
- mLocked.pointerGestureXZoomScale = mConfig->pointerGestureZoomSpeedRatio
+ mLocked.pointerGestureXZoomScale = mConfig.pointerGestureZoomSpeedRatio
* displayDiagonal / rawDiagonal;
mLocked.pointerGestureYZoomScale = mLocked.pointerGestureXZoomScale;
@@ -2416,7 +2466,7 @@ bool TouchInputMapper::configureSurfaceLocked() {
// of the diagonal axis of the touch pad. Touches that are wider than this are
// translated into freeform gestures.
mLocked.pointerGestureMaxSwipeWidth =
- mConfig->pointerGestureSwipeMaxWidthRatio * rawDiagonal;
+ mConfig.pointerGestureSwipeMaxWidthRatio * rawDiagonal;
// Reset the current pointer gesture.
mPointerGesture.reset();
@@ -2902,6 +2952,7 @@ void TouchInputMapper::reset() {
if (mPointerController != NULL
&& mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
+ mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
mPointerController->clearSpots();
}
} // release lock
@@ -2982,7 +3033,7 @@ void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
touchResult = consumeOffScreenTouches(when, policyFlags);
if (touchResult == DISPATCH_TOUCH) {
suppressSwipeOntoVirtualKeys(when);
- if (mPointerController != NULL) {
+ if (mPointerController != NULL && mConfig.pointerGesturesEnabled) {
dispatchPointerGestures(when, policyFlags, false /*isTimeout*/);
}
dispatchTouches(when, policyFlags);
@@ -3139,8 +3190,8 @@ void TouchInputMapper::suppressSwipeOntoVirtualKeys(nsecs_t when) {
// area and accidentally triggers a virtual key. This often happens when virtual keys
// are layed out below the screen near to where the on screen keyboard's space bar
// is displayed.
- if (mConfig->virtualKeyQuietTime > 0 && mCurrentTouch.pointerCount != 0) {
- mContext->disableVirtualKeysUntil(when + mConfig->virtualKeyQuietTime);
+ if (mConfig.virtualKeyQuietTime > 0 && mCurrentTouch.pointerCount != 0) {
+ mContext->disableVirtualKeysUntil(when + mConfig.virtualKeyQuietTime);
}
}
@@ -3688,10 +3739,10 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
#endif
if (mPointerGesture.lastGestureMode == PointerGesture::TAP) {
- if (when <= mPointerGesture.tapUpTime + mConfig->pointerGestureTapDragInterval) {
+ if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) {
// The tap/drag timeout has not yet expired.
getContext()->requestTimeoutAtTime(mPointerGesture.tapUpTime
- + mConfig->pointerGestureTapDragInterval);
+ + mConfig.pointerGestureTapDragInterval);
} else {
// The tap is finished.
#if DEBUG_GESTURES
@@ -3756,7 +3807,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
if (activeTouchId < 0) {
mPointerGesture.resetQuietTime();
} else {
- isQuietTime = when < mPointerGesture.quietTime + mConfig->pointerGestureQuietInterval;
+ isQuietTime = when < mPointerGesture.quietTime + mConfig.pointerGestureQuietInterval;
if (!isQuietTime) {
if ((mPointerGesture.lastGestureMode == PointerGesture::PRESS
|| mPointerGesture.lastGestureMode == PointerGesture::SWIPE
@@ -3785,7 +3836,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
// Case 1: Quiet time. (QUIET)
#if DEBUG_GESTURES
LOGD("Gestures: QUIET for next %0.3fms", (mPointerGesture.quietTime
- + mConfig->pointerGestureQuietInterval - when) * 0.000001f);
+ + mConfig.pointerGestureQuietInterval - when) * 0.000001f);
#endif
if (mPointerGesture.lastGestureMode != PointerGesture::QUIET) {
*outFinishPreviousGesture = true;
@@ -3824,7 +3875,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
// Find the fastest pointer and follow it.
if (activeTouchId >= 0 && mCurrentTouch.pointerCount > 1) {
int32_t bestId = -1;
- float bestSpeed = mConfig->pointerGestureDragMinSwitchSpeed;
+ float bestSpeed = mConfig.pointerGestureDragMinSwitchSpeed;
for (uint32_t i = 0; i < mCurrentTouch.pointerCount; i++) {
uint32_t id = mCurrentTouch.pointers[i].id;
float vx, vy;
@@ -3893,18 +3944,18 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
if ((mPointerGesture.lastGestureMode == PointerGesture::HOVER
|| mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG)
&& mLastTouch.pointerCount == 1) {
- if (when <= mPointerGesture.tapDownTime + mConfig->pointerGestureTapInterval) {
+ if (when <= mPointerGesture.tapDownTime + mConfig.pointerGestureTapInterval) {
float x, y;
mPointerController->getPosition(&x, &y);
- if (fabs(x - mPointerGesture.tapX) <= mConfig->pointerGestureTapSlop
- && fabs(y - mPointerGesture.tapY) <= mConfig->pointerGestureTapSlop) {
+ if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop
+ && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) {
#if DEBUG_GESTURES
LOGD("Gestures: TAP");
#endif
mPointerGesture.tapUpTime = when;
getContext()->requestTimeoutAtTime(when
- + mConfig->pointerGestureTapDragInterval);
+ + mConfig.pointerGestureTapDragInterval);
mPointerGesture.activeGestureId = 0;
mPointerGesture.currentGestureMode = PointerGesture::TAP;
@@ -3961,11 +4012,11 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.currentGestureMode = PointerGesture::HOVER;
if (mPointerGesture.lastGestureMode == PointerGesture::TAP) {
- if (when <= mPointerGesture.tapUpTime + mConfig->pointerGestureTapDragInterval) {
+ if (when <= mPointerGesture.tapUpTime + mConfig.pointerGestureTapDragInterval) {
float x, y;
mPointerController->getPosition(&x, &y);
- if (fabs(x - mPointerGesture.tapX) <= mConfig->pointerGestureTapSlop
- && fabs(y - mPointerGesture.tapY) <= mConfig->pointerGestureTapSlop) {
+ if (fabs(x - mPointerGesture.tapX) <= mConfig.pointerGestureTapSlop
+ && fabs(y - mPointerGesture.tapY) <= mConfig.pointerGestureTapSlop) {
mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG;
} else {
#if DEBUG_GESTURES
@@ -4059,7 +4110,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
LOG_ASSERT(activeTouchId >= 0);
bool settled = when >= mPointerGesture.firstTouchTime
- + mConfig->pointerGestureMultitouchSettleInterval;
+ + mConfig.pointerGestureMultitouchSettleInterval;
if (mPointerGesture.lastGestureMode != PointerGesture::PRESS
&& mPointerGesture.lastGestureMode != PointerGesture::SWIPE
&& mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) {
@@ -4070,7 +4121,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
#if DEBUG_GESTURES
LOGD("Gestures: Resetting gesture since additional pointers went down for MULTITOUCH, "
"settle time remaining %0.3fms", (mPointerGesture.firstTouchTime
- + mConfig->pointerGestureMultitouchSettleInterval - when)
+ + mConfig.pointerGestureMultitouchSettleInterval - when)
* 0.000001f);
#endif
*outCancelPreviousGesture = true;
@@ -4089,7 +4140,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
#if DEBUG_GESTURES
LOGD("Gestures: Using centroid as reference for MULTITOUCH, "
"settle time remaining %0.3fms", (mPointerGesture.firstTouchTime
- + mConfig->pointerGestureMultitouchSettleInterval - when)
+ + mConfig.pointerGestureMultitouchSettleInterval - when)
* 0.000001f);
#endif
mCurrentTouch.getCentroid(&mPointerGesture.referenceTouchX,
@@ -4143,7 +4194,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
dist[id] = hypotf(delta.dx * mLocked.pointerGestureXZoomScale,
delta.dy * mLocked.pointerGestureYZoomScale);
- if (dist[id] > mConfig->pointerGestureMultitouchMinDistance) {
+ if (dist[id] > mConfig.pointerGestureMultitouchMinDistance) {
distOverThreshold += 1;
}
}
@@ -4179,8 +4230,8 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
uint32_t id2 = mCurrentTouch.pointers[1].id;
float dist1 = dist[id1];
float dist2 = dist[id2];
- if (dist1 >= mConfig->pointerGestureMultitouchMinDistance
- && dist2 >= mConfig->pointerGestureMultitouchMinDistance) {
+ 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
@@ -4193,15 +4244,15 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
float dy2 = delta2.dy * mLocked.pointerGestureYZoomScale;
float dot = dx1 * dx2 + dy1 * dy2;
float cosine = dot / (dist1 * dist2); // denominator always > 0
- if (cosine >= mConfig->pointerGestureSwipeTransitionAngleCosine) {
+ if (cosine >= mConfig.pointerGestureSwipeTransitionAngleCosine) {
// Pointers are moving in the same direction. Switch to SWIPE.
#if DEBUG_GESTURES
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);
+ dist1, mConfig.pointerGestureMultitouchMinDistance,
+ dist2, mConfig.pointerGestureMultitouchMinDistance,
+ cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
#endif
mPointerGesture.currentGestureMode = PointerGesture::SWIPE;
} else {
@@ -4210,9 +4261,9 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
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);
+ dist1, mConfig.pointerGestureMultitouchMinDistance,
+ dist2, mConfig.pointerGestureMultitouchMinDistance,
+ cosine, mConfig.pointerGestureSwipeTransitionAngleCosine);
#endif
*outCancelPreviousGesture = true;
mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
@@ -5665,85 +5716,87 @@ void JoystickInputMapper::dump(String8& dump) {
}
}
-void JoystickInputMapper::configure() {
- InputMapper::configure();
+void JoystickInputMapper::configure(const InputReaderConfiguration* config, uint32_t changes) {
+ InputMapper::configure(config, changes);
- // Collect all axes.
- for (int32_t abs = 0; abs <= ABS_MAX; abs++) {
- RawAbsoluteAxisInfo rawAxisInfo;
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), abs, &rawAxisInfo);
- if (rawAxisInfo.valid) {
- // Map axis.
- AxisInfo axisInfo;
- bool explicitlyMapped = !getEventHub()->mapAxis(getDeviceId(), abs, &axisInfo);
- if (!explicitlyMapped) {
- // Axis is not explicitly mapped, will choose a generic axis later.
- axisInfo.mode = AxisInfo::MODE_NORMAL;
- axisInfo.axis = -1;
- }
+ if (!changes) { // first time only
+ // Collect all axes.
+ for (int32_t abs = 0; abs <= ABS_MAX; abs++) {
+ RawAbsoluteAxisInfo rawAxisInfo;
+ getEventHub()->getAbsoluteAxisInfo(getDeviceId(), abs, &rawAxisInfo);
+ if (rawAxisInfo.valid) {
+ // Map axis.
+ AxisInfo axisInfo;
+ bool explicitlyMapped = !getEventHub()->mapAxis(getDeviceId(), abs, &axisInfo);
+ if (!explicitlyMapped) {
+ // Axis is not explicitly mapped, will choose a generic axis later.
+ axisInfo.mode = AxisInfo::MODE_NORMAL;
+ axisInfo.axis = -1;
+ }
- // Apply flat override.
- int32_t rawFlat = axisInfo.flatOverride < 0
- ? rawAxisInfo.flat : axisInfo.flatOverride;
-
- // Calculate scaling factors and limits.
- Axis axis;
- if (axisInfo.mode == AxisInfo::MODE_SPLIT) {
- float scale = 1.0f / (axisInfo.splitValue - rawAxisInfo.minValue);
- float highScale = 1.0f / (rawAxisInfo.maxValue - axisInfo.splitValue);
- axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
- scale, 0.0f, highScale, 0.0f,
- 0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale);
- } else if (isCenteredAxis(axisInfo.axis)) {
- float scale = 2.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
- float offset = avg(rawAxisInfo.minValue, rawAxisInfo.maxValue) * -scale;
- axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
- scale, offset, scale, offset,
- -1.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale);
- } else {
- float scale = 1.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
- axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
- scale, 0.0f, scale, 0.0f,
- 0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale);
- }
+ // Apply flat override.
+ int32_t rawFlat = axisInfo.flatOverride < 0
+ ? rawAxisInfo.flat : axisInfo.flatOverride;
+
+ // Calculate scaling factors and limits.
+ Axis axis;
+ if (axisInfo.mode == AxisInfo::MODE_SPLIT) {
+ float scale = 1.0f / (axisInfo.splitValue - rawAxisInfo.minValue);
+ float highScale = 1.0f / (rawAxisInfo.maxValue - axisInfo.splitValue);
+ axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
+ scale, 0.0f, highScale, 0.0f,
+ 0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale);
+ } else if (isCenteredAxis(axisInfo.axis)) {
+ float scale = 2.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
+ float offset = avg(rawAxisInfo.minValue, rawAxisInfo.maxValue) * -scale;
+ axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
+ scale, offset, scale, offset,
+ -1.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale);
+ } else {
+ float scale = 1.0f / (rawAxisInfo.maxValue - rawAxisInfo.minValue);
+ axis.initialize(rawAxisInfo, axisInfo, explicitlyMapped,
+ scale, 0.0f, scale, 0.0f,
+ 0.0f, 1.0f, rawFlat * scale, rawAxisInfo.fuzz * scale);
+ }
- // To eliminate noise while the joystick is at rest, filter out small variations
- // in axis values up front.
- axis.filter = axis.flat * 0.25f;
+ // To eliminate noise while the joystick is at rest, filter out small variations
+ // in axis values up front.
+ axis.filter = axis.flat * 0.25f;
- mAxes.add(abs, axis);
+ mAxes.add(abs, axis);
+ }
}
- }
- // If there are too many axes, start dropping them.
- // Prefer to keep explicitly mapped axes.
- if (mAxes.size() > PointerCoords::MAX_AXES) {
- LOGI("Joystick '%s' has %d axes but the framework only supports a maximum of %d.",
- getDeviceName().string(), mAxes.size(), PointerCoords::MAX_AXES);
- pruneAxes(true);
- pruneAxes(false);
- }
-
- // Assign generic axis ids to remaining axes.
- int32_t nextGenericAxisId = AMOTION_EVENT_AXIS_GENERIC_1;
- size_t numAxes = mAxes.size();
- for (size_t i = 0; i < numAxes; i++) {
- Axis& axis = mAxes.editValueAt(i);
- if (axis.axisInfo.axis < 0) {
- while (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16
- && haveAxis(nextGenericAxisId)) {
- nextGenericAxisId += 1;
- }
+ // If there are too many axes, start dropping them.
+ // Prefer to keep explicitly mapped axes.
+ if (mAxes.size() > PointerCoords::MAX_AXES) {
+ LOGI("Joystick '%s' has %d axes but the framework only supports a maximum of %d.",
+ getDeviceName().string(), mAxes.size(), PointerCoords::MAX_AXES);
+ pruneAxes(true);
+ pruneAxes(false);
+ }
+
+ // Assign generic axis ids to remaining axes.
+ int32_t nextGenericAxisId = AMOTION_EVENT_AXIS_GENERIC_1;
+ size_t numAxes = mAxes.size();
+ for (size_t i = 0; i < numAxes; i++) {
+ Axis& axis = mAxes.editValueAt(i);
+ if (axis.axisInfo.axis < 0) {
+ while (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16
+ && haveAxis(nextGenericAxisId)) {
+ nextGenericAxisId += 1;
+ }
- if (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16) {
- axis.axisInfo.axis = nextGenericAxisId;
- nextGenericAxisId += 1;
- } else {
- LOGI("Ignoring joystick '%s' axis %d because all of the generic axis ids "
- "have already been assigned to other axes.",
- getDeviceName().string(), mAxes.keyAt(i));
- mAxes.removeItemsAt(i--);
- numAxes -= 1;
+ if (nextGenericAxisId <= AMOTION_EVENT_AXIS_GENERIC_16) {
+ axis.axisInfo.axis = nextGenericAxisId;
+ nextGenericAxisId += 1;
+ } else {
+ LOGI("Ignoring joystick '%s' axis %d because all of the generic axis ids "
+ "have already been assigned to other axes.",
+ getDeviceName().string(), mAxes.keyAt(i));
+ mAxes.removeItemsAt(i--);
+ numAxes -= 1;
+ }
}
}
}
diff --git a/services/input/InputReader.h b/services/input/InputReader.h
index 55315f7..288ff4e 100644
--- a/services/input/InputReader.h
+++ b/services/input/InputReader.h
@@ -45,6 +45,18 @@ class InputMapper;
* Specifies various options that modify the behavior of the input reader.
*/
struct InputReaderConfiguration {
+ // Describes changes that have occurred.
+ enum {
+ // The pointer speed changed.
+ CHANGE_POINTER_SPEED = 1 << 0,
+
+ // The pointer gesture control changed.
+ CHANGE_POINTER_GESTURE_ENABLEMENT = 1 << 1,
+
+ // All devices must be reopened.
+ CHANGE_MUST_REOPEN = 1 << 31,
+ };
+
// Determines whether to turn on some hacks we have to improve the touch interaction with a
// certain device whose screen currently is not all that good.
bool filterTouchEvents;
@@ -68,6 +80,9 @@ struct InputReaderConfiguration {
// Velocity control parameters for mouse wheel movements.
VelocityControlParameters wheelVelocityControlParameters;
+ // True if pointer gestures are enabled.
+ bool pointerGesturesEnabled;
+
// Quiet time between certain pointer gesture transitions.
// Time to allow for all fingers or buttons to settle into a stable state before
// starting a new gesture.
@@ -136,6 +151,7 @@ struct InputReaderConfiguration {
virtualKeyQuietTime(0),
pointerVelocityControlParameters(1.0f, 500.0f, 3000.0f, 3.0f),
wheelVelocityControlParameters(1.0f, 15.0f, 50.0f, 4.0f),
+ pointerGesturesEnabled(true),
pointerGestureQuietInterval(100 * 1000000LL), // 100 ms
pointerGestureDragMinSwitchSpeed(50), // 50 pixels per second
pointerGestureTapInterval(150 * 1000000LL), // 150 ms
@@ -235,8 +251,10 @@ public:
virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) = 0;
- /* Reopens and reconfigures all input devices. */
- virtual void refreshConfiguration() = 0;
+ /* Requests that a reconfiguration of all input devices.
+ * The changes flag is a bitfield that indicates what has changed and whether
+ * the input devices must all be reopened. */
+ virtual void requestRefreshConfiguration(uint32_t changes) = 0;
};
@@ -260,7 +278,6 @@ public:
virtual void requestTimeoutAtTime(nsecs_t when) = 0;
virtual InputReaderPolicyInterface* getPolicy() = 0;
- virtual const InputReaderConfiguration* getConfig() = 0;
virtual InputDispatcherInterface* getDispatcher() = 0;
virtual EventHubInterface* getEventHub() = 0;
};
@@ -301,7 +318,7 @@ public:
virtual bool hasKeys(int32_t deviceId, uint32_t sourceMask,
size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags);
- virtual void refreshConfiguration();
+ virtual void requestRefreshConfiguration(uint32_t changes);
protected:
// These methods are protected virtual so they can be overridden and instrumented
@@ -316,7 +333,6 @@ private:
InputReaderConfiguration mConfig;
virtual InputReaderPolicyInterface* getPolicy() { return mPolicy.get(); }
- virtual const InputReaderConfiguration* getConfig() { return &mConfig; }
virtual InputDispatcherInterface* getDispatcher() { return mDispatcher.get(); }
virtual EventHubInterface* getEventHub() { return mEventHub.get(); }
@@ -365,8 +381,8 @@ private:
nsecs_t mNextTimeout; // only accessed by reader thread, not guarded
virtual void requestTimeoutAtTime(nsecs_t when);
- volatile int32_t mRefreshConfiguration; // atomic
- void configure(bool firstTime);
+ uint32_t mConfigurationChangesToRefresh; // guarded by mStateLock
+ void refreshConfiguration(uint32_t changes);
// state queries
typedef int32_t (InputDevice::*GetStateFunc)(uint32_t sourceMask, int32_t code);
@@ -408,7 +424,7 @@ public:
void dump(String8& dump);
void addMapper(InputMapper* mapper);
- void configure();
+ void configure(const InputReaderConfiguration* config, uint32_t changes);
void reset();
void process(const RawEvent* rawEvents, size_t count);
void timeoutExpired(nsecs_t when);
@@ -460,14 +476,13 @@ public:
inline const String8 getDeviceName() { return mDevice->getName(); }
inline InputReaderContext* getContext() { return mContext; }
inline InputReaderPolicyInterface* getPolicy() { return mContext->getPolicy(); }
- inline const InputReaderConfiguration* getConfig() { return mContext->getConfig(); }
inline InputDispatcherInterface* getDispatcher() { return mContext->getDispatcher(); }
inline EventHubInterface* getEventHub() { return mContext->getEventHub(); }
virtual uint32_t getSources() = 0;
virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
virtual void dump(String8& dump);
- virtual void configure();
+ virtual void configure(const InputReaderConfiguration* config, uint32_t changes);
virtual void reset();
virtual void process(const RawEvent* rawEvent) = 0;
virtual void timeoutExpired(nsecs_t when);
@@ -514,7 +529,7 @@ public:
virtual uint32_t getSources();
virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
virtual void dump(String8& dump);
- virtual void configure();
+ virtual void configure(const InputReaderConfiguration* config, uint32_t changes);
virtual void reset();
virtual void process(const RawEvent* rawEvent);
@@ -584,7 +599,7 @@ public:
virtual uint32_t getSources();
virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
virtual void dump(String8& dump);
- virtual void configure();
+ virtual void configure(const InputReaderConfiguration* config, uint32_t changes);
virtual void reset();
virtual void process(const RawEvent* rawEvent);
@@ -675,7 +690,7 @@ public:
virtual uint32_t getSources();
virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
virtual void dump(String8& dump);
- virtual void configure();
+ virtual void configure(const InputReaderConfiguration* config, uint32_t changes);
virtual void reset();
virtual int32_t getKeyCodeState(uint32_t sourceMask, int32_t keyCode);
@@ -783,7 +798,7 @@ protected:
uint32_t mPointerSource; // sources when reporting pointer gestures
// The reader's configuration.
- const InputReaderConfiguration* mConfig;
+ InputReaderConfiguration mConfig;
// Immutable configuration parameters.
struct Parameters {
@@ -1400,7 +1415,7 @@ public:
virtual uint32_t getSources();
virtual void populateDeviceInfo(InputDeviceInfo* deviceInfo);
virtual void dump(String8& dump);
- virtual void configure();
+ virtual void configure(const InputReaderConfiguration* config, uint32_t changes);
virtual void reset();
virtual void process(const RawEvent* rawEvent);
diff --git a/services/input/InputWindow.h b/services/input/InputWindow.h
index 93c9b5f..d166ad4 100644
--- a/services/input/InputWindow.h
+++ b/services/input/InputWindow.h
@@ -127,6 +127,10 @@ struct InputWindow {
LAST_SYSTEM_WINDOW = 2999,
};
+ enum {
+ INPUT_FEATURE_DISABLE_TOUCH_PAD_GESTURES = 0x00000001,
+ };
+
sp<InputWindowHandle> inputWindowHandle;
sp<InputChannel> inputChannel;
String8 name;
@@ -147,6 +151,7 @@ struct InputWindow {
int32_t layer;
int32_t ownerPid;
int32_t ownerUid;
+ int32_t inputFeatures;
bool touchableRegionContainsPoint(int32_t x, int32_t y) const;
bool frameContainsPoint(int32_t x, int32_t y) const;
diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp
index 4a32341..e349248 100644
--- a/services/input/tests/InputReader_test.cpp
+++ b/services/input/tests/InputReader_test.cpp
@@ -747,8 +747,6 @@ class FakeInputReaderContext : public InputReaderContext {
int32_t mGlobalMetaState;
bool mUpdateGlobalMetaStateWasCalled;
- InputReaderConfiguration mConfig;
-
public:
FakeInputReaderContext(const sp<EventHubInterface>& eventHub,
const sp<InputReaderPolicyInterface>& policy,
@@ -786,11 +784,6 @@ private:
return mPolicy.get();
}
- virtual const InputReaderConfiguration* getConfig() {
- mPolicy->getReaderConfiguration(&mConfig);
- return &mConfig;
- }
-
virtual InputDispatcherInterface* getDispatcher() {
return mDispatcher.get();
}
@@ -895,7 +888,7 @@ private:
}
}
- virtual void configure() {
+ virtual void configure(const InputReaderConfiguration* config, uint32_t changes) {
mConfigureWasCalled = true;
}
@@ -1359,7 +1352,8 @@ TEST_F(InputDeviceTest, ImmutableProperties) {
TEST_F(InputDeviceTest, WhenNoMappersAreRegistered_DeviceIsIgnored) {
// Configuration.
- mDevice->configure();
+ InputReaderConfiguration config;
+ mDevice->configure(&config, 0);
// Metadata.
ASSERT_TRUE(mDevice->isIgnored());
@@ -1413,7 +1407,8 @@ TEST_F(InputDeviceTest, WhenMappersAreRegistered_DeviceIsNotIgnoredAndForwardsRe
mapper2->setMetaState(AMETA_SHIFT_ON);
mDevice->addMapper(mapper2);
- mDevice->configure();
+ InputReaderConfiguration config;
+ mDevice->configure(&config, 0);
String8 propertyValue;
ASSERT_TRUE(mDevice->getConfiguration().tryGetProperty(String8("key"), propertyValue))
@@ -1519,8 +1514,10 @@ protected:
}
void addMapperAndConfigure(InputMapper* mapper) {
+ InputReaderConfiguration config;
+
mDevice->addMapper(mapper);
- mDevice->configure();
+ mDevice->configure(&config, 0);
}
static void process(InputMapper* mapper, nsecs_t when, int32_t deviceId, int32_t type,
diff --git a/services/java/com/android/server/wm/InputMonitor.java b/services/java/com/android/server/wm/InputMonitor.java
index 9dc92d3..3be8af6 100644
--- a/services/java/com/android/server/wm/InputMonitor.java
+++ b/services/java/com/android/server/wm/InputMonitor.java
@@ -128,6 +128,8 @@ final class InputMonitor {
inputWindow.layer = mService.mDragState.getDragLayerLw();
inputWindow.ownerPid = Process.myPid();
inputWindow.ownerUid = Process.myUid();
+ inputWindow.inputFeatures = 0;
+ inputWindow.scaleFactor = 1.0f;
// The drag window covers the entire display
inputWindow.frameLeft = 0;
@@ -204,7 +206,8 @@ final class InputMonitor {
inputWindow.layer = child.mLayer;
inputWindow.ownerPid = child.mSession.mPid;
inputWindow.ownerUid = child.mSession.mUid;
-
+ inputWindow.inputFeatures = child.mAttrs.inputFeatures;
+
final Rect frame = child.mFrame;
inputWindow.frameLeft = frame.left;
inputWindow.frameTop = frame.top;
diff --git a/services/java/com/android/server/wm/InputWindow.java b/services/java/com/android/server/wm/InputWindow.java
index 578120e..655d734 100644
--- a/services/java/com/android/server/wm/InputWindow.java
+++ b/services/java/com/android/server/wm/InputWindow.java
@@ -75,6 +75,9 @@ public final class InputWindow {
public int ownerPid;
public int ownerUid;
+ // Window input features.
+ public int inputFeatures;
+
public void recycle() {
inputWindowHandle = null;
inputChannel = null;
diff --git a/services/jni/com_android_server_InputManager.cpp b/services/jni/com_android_server_InputManager.cpp
index 7c5084f..8a46ab0 100644
--- a/services/jni/com_android_server_InputManager.cpp
+++ b/services/jni/com_android_server_InputManager.cpp
@@ -234,6 +234,9 @@ private:
// Pointer speed.
int32_t pointerSpeed;
+ // True if pointer gestures are enabled.
+ bool pointerGesturesEnabled;
+
// Sprite controller singleton, created on first use.
sp<SpriteController> spriteController;
@@ -274,6 +277,7 @@ NativeInputManager::NativeInputManager(jobject contextObj,
mLocked.systemUiVisibility = ASYSTEM_UI_VISIBILITY_STATUS_BAR_VISIBLE;
mLocked.pointerSpeed = 0;
+ mLocked.pointerGesturesEnabled = true;
}
sp<EventHub> eventHub = new EventHub();
@@ -443,6 +447,7 @@ void NativeInputManager::getReaderConfiguration(InputReaderConfiguration* outCon
outConfig->pointerVelocityControlParameters.scale = exp2f(mLocked.pointerSpeed
* POINTER_SPEED_EXPONENT);
+ outConfig->pointerGesturesEnabled = mLocked.pointerGesturesEnabled;
} // release lock
}
@@ -594,6 +599,7 @@ bool NativeInputManager::isKeyRepeatEnabled() {
void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArray) {
Vector<InputWindow> windows;
+ bool newPointerGesturesEnabled = true;
jsize length = env->GetArrayLength(windowObjArray);
for (jsize i = 0; i < length; i++) {
jobject windowObj = env->GetObjectArrayElement(windowObjArray, i);
@@ -606,11 +612,29 @@ void NativeInputManager::setInputWindows(JNIEnv* env, jobjectArray windowObjArra
android_server_InputWindow_toNative(env, windowObj, &window);
if (window.inputChannel == NULL) {
windows.pop();
+ } else if (window.hasFocus) {
+ if (window.inputFeatures & InputWindow::INPUT_FEATURE_DISABLE_TOUCH_PAD_GESTURES) {
+ newPointerGesturesEnabled = false;
+ }
}
env->DeleteLocalRef(windowObj);
}
mInputManager->getDispatcher()->setInputWindows(windows);
+
+ uint32_t changes = 0;
+ { // acquire lock
+ AutoMutex _l(mLock);
+
+ if (mLocked.pointerGesturesEnabled != newPointerGesturesEnabled) {
+ mLocked.pointerGesturesEnabled = newPointerGesturesEnabled;
+ changes |= InputReaderConfiguration::CHANGE_POINTER_GESTURE_ENABLEMENT;
+ }
+ } // release lock
+
+ if (changes) {
+ mInputManager->getReader()->requestRefreshConfiguration(changes);
+ }
}
void NativeInputManager::setFocusedApplication(JNIEnv* env, jobject applicationObj) {
@@ -650,14 +674,19 @@ void NativeInputManager::updateInactivityTimeoutLocked(const sp<PointerControlle
}
void NativeInputManager::setPointerSpeed(int32_t speed) {
- AutoMutex _l(mLock);
+ { // acquire lock
+ AutoMutex _l(mLock);
+
+ if (mLocked.pointerSpeed == speed) {
+ return;
+ }
- if (mLocked.pointerSpeed != speed) {
LOGI("Setting pointer speed to %d.", speed);
mLocked.pointerSpeed = speed;
+ } // release lock
- mInputManager->getReader()->refreshConfiguration();
- }
+ mInputManager->getReader()->requestRefreshConfiguration(
+ InputReaderConfiguration::CHANGE_POINTER_SPEED);
}
bool NativeInputManager::isScreenOn() {
diff --git a/services/jni/com_android_server_InputWindow.cpp b/services/jni/com_android_server_InputWindow.cpp
index 012ce21..0426f63 100644
--- a/services/jni/com_android_server_InputWindow.cpp
+++ b/services/jni/com_android_server_InputWindow.cpp
@@ -48,6 +48,7 @@ static struct {
jfieldID layer;
jfieldID ownerPid;
jfieldID ownerUid;
+ jfieldID inputFeatures;
} gInputWindowClassInfo;
@@ -130,6 +131,8 @@ void android_server_InputWindow_toNative(
gInputWindowClassInfo.ownerPid);
outInputWindow->ownerUid = env->GetIntField(inputWindowObj,
gInputWindowClassInfo.ownerUid);
+ outInputWindow->inputFeatures = env->GetIntField(inputWindowObj,
+ gInputWindowClassInfo.inputFeatures);
}
@@ -206,6 +209,9 @@ int register_android_server_InputWindow(JNIEnv* env) {
GET_FIELD_ID(gInputWindowClassInfo.ownerUid, clazz,
"ownerUid", "I");
+
+ GET_FIELD_ID(gInputWindowClassInfo.inputFeatures, clazz,
+ "inputFeatures", "I");
return 0;
}