summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
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;
}