am f4368c95
: Merge "Filter virtual keys after touches." into honeycomb
* commit 'f4368c959fa9436d75feb2543cb65da0d46521e5': Filter virtual keys after touches.
This commit is contained in:
@ -433,7 +433,14 @@
|
|||||||
from the touch driver. This code exists for one particular device,
|
from the touch driver. This code exists for one particular device,
|
||||||
and should not be enabled for any others. -->
|
and should not be enabled for any others. -->
|
||||||
<bool name="config_filterJumpyTouchEvents">false</bool>
|
<bool name="config_filterJumpyTouchEvents">false</bool>
|
||||||
|
|
||||||
|
<!-- Specifies the amount of time to disable virtual keys after the screen is touched
|
||||||
|
in order to filter out accidental virtual key presses due to swiping gestures
|
||||||
|
or taps near the edge of the display. May be 0 to disable the feature.
|
||||||
|
It is recommended that this value be no more than 250 ms.
|
||||||
|
This feature should be disabled for most devices. -->
|
||||||
|
<integer name="config_virtualKeyQuietTimeMillis">0</integer>
|
||||||
|
|
||||||
<!-- Component name of the default wallpaper. This will be ImageWallpaper if not
|
<!-- Component name of the default wallpaper. This will be ImageWallpaper if not
|
||||||
specified -->
|
specified -->
|
||||||
<string name="default_wallpaper_component">@null</string>
|
<string name="default_wallpaper_component">@null</string>
|
||||||
|
@ -121,7 +121,7 @@ InputReader::InputReader(const sp<EventHubInterface>& eventHub,
|
|||||||
const sp<InputReaderPolicyInterface>& policy,
|
const sp<InputReaderPolicyInterface>& policy,
|
||||||
const sp<InputDispatcherInterface>& dispatcher) :
|
const sp<InputDispatcherInterface>& dispatcher) :
|
||||||
mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher),
|
mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher),
|
||||||
mGlobalMetaState(0) {
|
mGlobalMetaState(0), mDisableVirtualKeysTimeout(-1) {
|
||||||
configureExcludedDevices();
|
configureExcludedDevices();
|
||||||
updateGlobalMetaState();
|
updateGlobalMetaState();
|
||||||
updateInputConfiguration();
|
updateInputConfiguration();
|
||||||
@ -373,6 +373,24 @@ void InputReader::updateInputConfiguration() {
|
|||||||
} // release state lock
|
} // release state lock
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InputReader::disableVirtualKeysUntil(nsecs_t time) {
|
||||||
|
mDisableVirtualKeysTimeout = time;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputReader::shouldDropVirtualKey(nsecs_t now,
|
||||||
|
InputDevice* device, int32_t keyCode, int32_t scanCode) {
|
||||||
|
if (now < mDisableVirtualKeysTimeout) {
|
||||||
|
LOGI("Dropping virtual key from device %s because virtual keys are "
|
||||||
|
"temporarily disabled for the next %0.3fms. keyCode=%d, scanCode=%d",
|
||||||
|
device->getName().string(),
|
||||||
|
(mDisableVirtualKeysTimeout - now) * 0.000001,
|
||||||
|
keyCode, scanCode);
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void InputReader::getInputConfiguration(InputConfiguration* outConfiguration) {
|
void InputReader::getInputConfiguration(InputConfiguration* outConfiguration) {
|
||||||
{ // acquire state lock
|
{ // acquire state lock
|
||||||
AutoMutex _l(mStateLock);
|
AutoMutex _l(mStateLock);
|
||||||
@ -889,6 +907,12 @@ void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
|
|||||||
keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode;
|
keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode;
|
||||||
} else {
|
} else {
|
||||||
// key down
|
// key down
|
||||||
|
if ((policyFlags & POLICY_FLAG_VIRTUAL)
|
||||||
|
&& mContext->shouldDropVirtualKey(when,
|
||||||
|
getDevice(), keyCode, scanCode)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
mLocked.keyDowns.push();
|
mLocked.keyDowns.push();
|
||||||
KeyDown& keyDown = mLocked.keyDowns.editTop();
|
KeyDown& keyDown = mLocked.keyDowns.editTop();
|
||||||
keyDown.keyCode = keyCode;
|
keyDown.keyCode = keyCode;
|
||||||
@ -1428,6 +1452,7 @@ void TouchInputMapper::configureParameters() {
|
|||||||
mParameters.useBadTouchFilter = getPolicy()->filterTouchEvents();
|
mParameters.useBadTouchFilter = getPolicy()->filterTouchEvents();
|
||||||
mParameters.useAveragingTouchFilter = getPolicy()->filterTouchEvents();
|
mParameters.useAveragingTouchFilter = getPolicy()->filterTouchEvents();
|
||||||
mParameters.useJumpyTouchFilter = getPolicy()->filterJumpyTouchEvents();
|
mParameters.useJumpyTouchFilter = getPolicy()->filterJumpyTouchEvents();
|
||||||
|
mParameters.virtualKeyQuietTime = getPolicy()->getVirtualKeyQuietTime();
|
||||||
|
|
||||||
String8 deviceTypeString;
|
String8 deviceTypeString;
|
||||||
mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
|
mParameters.deviceType = Parameters::DEVICE_TYPE_TOUCH_SCREEN;
|
||||||
@ -2219,6 +2244,7 @@ void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
|
|||||||
|
|
||||||
TouchResult touchResult = consumeOffScreenTouches(when, policyFlags);
|
TouchResult touchResult = consumeOffScreenTouches(when, policyFlags);
|
||||||
if (touchResult == DISPATCH_TOUCH) {
|
if (touchResult == DISPATCH_TOUCH) {
|
||||||
|
detectGestures(when);
|
||||||
dispatchTouches(when, policyFlags);
|
dispatchTouches(when, policyFlags);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2304,6 +2330,11 @@ TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches(
|
|||||||
if (mCurrentTouch.pointerCount == 1) {
|
if (mCurrentTouch.pointerCount == 1) {
|
||||||
const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
|
const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
|
||||||
if (virtualKey) {
|
if (virtualKey) {
|
||||||
|
if (mContext->shouldDropVirtualKey(when, getDevice(),
|
||||||
|
virtualKey->keyCode, virtualKey->scanCode)) {
|
||||||
|
return DROP_STROKE;
|
||||||
|
}
|
||||||
|
|
||||||
mLocked.currentVirtualKey.down = true;
|
mLocked.currentVirtualKey.down = true;
|
||||||
mLocked.currentVirtualKey.downTime = when;
|
mLocked.currentVirtualKey.downTime = when;
|
||||||
mLocked.currentVirtualKey.keyCode = virtualKey->keyCode;
|
mLocked.currentVirtualKey.keyCode = virtualKey->keyCode;
|
||||||
@ -2341,6 +2372,26 @@ TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches(
|
|||||||
return touchResult;
|
return touchResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TouchInputMapper::detectGestures(nsecs_t when) {
|
||||||
|
// Disable all virtual key touches that happen within a short time interval of the
|
||||||
|
// most recent touch. The idea is to filter out stray virtual key presses when
|
||||||
|
// interacting with the touch screen.
|
||||||
|
//
|
||||||
|
// Problems we're trying to solve:
|
||||||
|
//
|
||||||
|
// 1. While scrolling a list or dragging the window shade, the user swipes down into a
|
||||||
|
// virtual key area that is implemented by a separate touch panel and accidentally
|
||||||
|
// triggers a virtual key.
|
||||||
|
//
|
||||||
|
// 2. While typing in the on screen keyboard, the user taps slightly outside the screen
|
||||||
|
// 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 (mParameters.virtualKeyQuietTime > 0 && mCurrentTouch.pointerCount != 0) {
|
||||||
|
mContext->disableVirtualKeysUntil(when + mParameters.virtualKeyQuietTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
|
void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
|
||||||
uint32_t currentPointerCount = mCurrentTouch.pointerCount;
|
uint32_t currentPointerCount = mCurrentTouch.pointerCount;
|
||||||
uint32_t lastPointerCount = mLastTouch.pointerCount;
|
uint32_t lastPointerCount = mLastTouch.pointerCount;
|
||||||
|
@ -78,6 +78,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual bool filterJumpyTouchEvents() = 0;
|
virtual bool filterJumpyTouchEvents() = 0;
|
||||||
|
|
||||||
|
/* Gets the amount of time to disable virtual keys after the screen is touched
|
||||||
|
* in order to filter out accidental virtual key presses due to swiping gestures
|
||||||
|
* or taps near the edge of the display. May be 0 to disable the feature.
|
||||||
|
*/
|
||||||
|
virtual nsecs_t getVirtualKeyQuietTime() = 0;
|
||||||
|
|
||||||
/* Gets the excluded device names for the platform. */
|
/* Gets the excluded device names for the platform. */
|
||||||
virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) = 0;
|
virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) = 0;
|
||||||
|
|
||||||
@ -147,6 +153,10 @@ public:
|
|||||||
virtual void updateGlobalMetaState() = 0;
|
virtual void updateGlobalMetaState() = 0;
|
||||||
virtual int32_t getGlobalMetaState() = 0;
|
virtual int32_t getGlobalMetaState() = 0;
|
||||||
|
|
||||||
|
virtual void disableVirtualKeysUntil(nsecs_t time) = 0;
|
||||||
|
virtual bool shouldDropVirtualKey(nsecs_t now,
|
||||||
|
InputDevice* device, int32_t keyCode, int32_t scanCode) = 0;
|
||||||
|
|
||||||
virtual InputReaderPolicyInterface* getPolicy() = 0;
|
virtual InputReaderPolicyInterface* getPolicy() = 0;
|
||||||
virtual InputDispatcherInterface* getDispatcher() = 0;
|
virtual InputDispatcherInterface* getDispatcher() = 0;
|
||||||
virtual EventHubInterface* getEventHub() = 0;
|
virtual EventHubInterface* getEventHub() = 0;
|
||||||
@ -234,6 +244,11 @@ private:
|
|||||||
InputConfiguration mInputConfiguration;
|
InputConfiguration mInputConfiguration;
|
||||||
void updateInputConfiguration();
|
void updateInputConfiguration();
|
||||||
|
|
||||||
|
nsecs_t mDisableVirtualKeysTimeout;
|
||||||
|
virtual void disableVirtualKeysUntil(nsecs_t time);
|
||||||
|
virtual bool shouldDropVirtualKey(nsecs_t now,
|
||||||
|
InputDevice* device, int32_t keyCode, int32_t scanCode);
|
||||||
|
|
||||||
// state queries
|
// state queries
|
||||||
typedef int32_t (InputDevice::*GetStateFunc)(uint32_t sourceMask, int32_t code);
|
typedef int32_t (InputDevice::*GetStateFunc)(uint32_t sourceMask, int32_t code);
|
||||||
int32_t getState(int32_t deviceId, uint32_t sourceMask, int32_t code,
|
int32_t getState(int32_t deviceId, uint32_t sourceMask, int32_t code,
|
||||||
@ -603,6 +618,7 @@ protected:
|
|||||||
bool useBadTouchFilter;
|
bool useBadTouchFilter;
|
||||||
bool useJumpyTouchFilter;
|
bool useJumpyTouchFilter;
|
||||||
bool useAveragingTouchFilter;
|
bool useAveragingTouchFilter;
|
||||||
|
nsecs_t virtualKeyQuietTime;
|
||||||
} mParameters;
|
} mParameters;
|
||||||
|
|
||||||
// Immutable calibration parameters in parsed form.
|
// Immutable calibration parameters in parsed form.
|
||||||
@ -839,6 +855,7 @@ private:
|
|||||||
void dispatchTouch(nsecs_t when, uint32_t policyFlags, TouchData* touch,
|
void dispatchTouch(nsecs_t when, uint32_t policyFlags, TouchData* touch,
|
||||||
BitSet32 idBits, uint32_t changedId, uint32_t pointerCount,
|
BitSet32 idBits, uint32_t changedId, uint32_t pointerCount,
|
||||||
int32_t motionEventAction);
|
int32_t motionEventAction);
|
||||||
|
void detectGestures(nsecs_t when);
|
||||||
|
|
||||||
bool isPointInsideSurfaceLocked(int32_t x, int32_t y);
|
bool isPointInsideSurfaceLocked(int32_t x, int32_t y);
|
||||||
const VirtualKey* findVirtualKeyHitLocked(int32_t x, int32_t y);
|
const VirtualKey* findVirtualKeyHitLocked(int32_t x, int32_t y);
|
||||||
|
@ -127,6 +127,10 @@ public:
|
|||||||
mFilterJumpyTouchEvents = enabled;
|
mFilterJumpyTouchEvents = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual nsecs_t getVirtualKeyQuietTime() {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
void addExcludedDeviceName(const String8& deviceName) {
|
void addExcludedDeviceName(const String8& deviceName) {
|
||||||
mExcludedDeviceNames.push(deviceName);
|
mExcludedDeviceNames.push(deviceName);
|
||||||
}
|
}
|
||||||
@ -722,6 +726,14 @@ private:
|
|||||||
virtual InputDispatcherInterface* getDispatcher() {
|
virtual InputDispatcherInterface* getDispatcher() {
|
||||||
return mDispatcher.get();
|
return mDispatcher.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void disableVirtualKeysUntil(nsecs_t time) {
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual bool shouldDropVirtualKey(nsecs_t now,
|
||||||
|
InputDevice* device, int32_t keyCode, int32_t scanCode) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -481,7 +481,13 @@ public class InputManager {
|
|||||||
return mContext.getResources().getBoolean(
|
return mContext.getResources().getBoolean(
|
||||||
com.android.internal.R.bool.config_filterJumpyTouchEvents);
|
com.android.internal.R.bool.config_filterJumpyTouchEvents);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
public int getVirtualKeyQuietTimeMillis() {
|
||||||
|
return mContext.getResources().getInteger(
|
||||||
|
com.android.internal.R.integer.config_virtualKeyQuietTimeMillis);
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
public String[] getExcludedDeviceNames() {
|
public String[] getExcludedDeviceNames() {
|
||||||
ArrayList<String> names = new ArrayList<String>();
|
ArrayList<String> names = new ArrayList<String>();
|
||||||
|
@ -62,6 +62,7 @@ static struct {
|
|||||||
jmethodID checkInjectEventsPermission;
|
jmethodID checkInjectEventsPermission;
|
||||||
jmethodID filterTouchEvents;
|
jmethodID filterTouchEvents;
|
||||||
jmethodID filterJumpyTouchEvents;
|
jmethodID filterJumpyTouchEvents;
|
||||||
|
jmethodID getVirtualKeyQuietTimeMillis;
|
||||||
jmethodID getExcludedDeviceNames;
|
jmethodID getExcludedDeviceNames;
|
||||||
jmethodID getMaxEventsPerSecond;
|
jmethodID getMaxEventsPerSecond;
|
||||||
jmethodID getPointerLayer;
|
jmethodID getPointerLayer;
|
||||||
@ -159,6 +160,7 @@ public:
|
|||||||
int32_t* width, int32_t* height, int32_t* orientation);
|
int32_t* width, int32_t* height, int32_t* orientation);
|
||||||
virtual bool filterTouchEvents();
|
virtual bool filterTouchEvents();
|
||||||
virtual bool filterJumpyTouchEvents();
|
virtual bool filterJumpyTouchEvents();
|
||||||
|
virtual nsecs_t getVirtualKeyQuietTime();
|
||||||
virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
|
virtual void getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames);
|
||||||
virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId);
|
virtual sp<PointerControllerInterface> obtainPointerController(int32_t deviceId);
|
||||||
|
|
||||||
@ -191,6 +193,7 @@ private:
|
|||||||
// Cached filtering policies.
|
// Cached filtering policies.
|
||||||
int32_t mFilterTouchEvents;
|
int32_t mFilterTouchEvents;
|
||||||
int32_t mFilterJumpyTouchEvents;
|
int32_t mFilterJumpyTouchEvents;
|
||||||
|
nsecs_t mVirtualKeyQuietTime;
|
||||||
|
|
||||||
// Cached throttling policy.
|
// Cached throttling policy.
|
||||||
int32_t mMaxEventsPerSecond;
|
int32_t mMaxEventsPerSecond;
|
||||||
@ -219,7 +222,7 @@ private:
|
|||||||
|
|
||||||
|
|
||||||
NativeInputManager::NativeInputManager(jobject callbacksObj) :
|
NativeInputManager::NativeInputManager(jobject callbacksObj) :
|
||||||
mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1),
|
mFilterTouchEvents(-1), mFilterJumpyTouchEvents(-1), mVirtualKeyQuietTime(-1),
|
||||||
mMaxEventsPerSecond(-1) {
|
mMaxEventsPerSecond(-1) {
|
||||||
JNIEnv* env = jniEnv();
|
JNIEnv* env = jniEnv();
|
||||||
|
|
||||||
@ -355,6 +358,24 @@ bool NativeInputManager::filterJumpyTouchEvents() {
|
|||||||
return mFilterJumpyTouchEvents;
|
return mFilterJumpyTouchEvents;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsecs_t NativeInputManager::getVirtualKeyQuietTime() {
|
||||||
|
if (mVirtualKeyQuietTime < 0) {
|
||||||
|
JNIEnv* env = jniEnv();
|
||||||
|
|
||||||
|
jint result = env->CallIntMethod(mCallbacksObj,
|
||||||
|
gCallbacksClassInfo.getVirtualKeyQuietTimeMillis);
|
||||||
|
if (checkAndClearExceptionFromCallback(env, "getVirtualKeyQuietTimeMillis")) {
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
if (result < 0) {
|
||||||
|
result = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
mVirtualKeyQuietTime = milliseconds_to_nanoseconds(result);
|
||||||
|
}
|
||||||
|
return mVirtualKeyQuietTime;
|
||||||
|
}
|
||||||
|
|
||||||
void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
|
void NativeInputManager::getExcludedDeviceNames(Vector<String8>& outExcludedDeviceNames) {
|
||||||
outExcludedDeviceNames.clear();
|
outExcludedDeviceNames.clear();
|
||||||
|
|
||||||
@ -1155,6 +1176,9 @@ int register_android_server_InputManager(JNIEnv* env) {
|
|||||||
GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, gCallbacksClassInfo.clazz,
|
GET_METHOD_ID(gCallbacksClassInfo.filterJumpyTouchEvents, gCallbacksClassInfo.clazz,
|
||||||
"filterJumpyTouchEvents", "()Z");
|
"filterJumpyTouchEvents", "()Z");
|
||||||
|
|
||||||
|
GET_METHOD_ID(gCallbacksClassInfo.getVirtualKeyQuietTimeMillis, gCallbacksClassInfo.clazz,
|
||||||
|
"getVirtualKeyQuietTimeMillis", "()I");
|
||||||
|
|
||||||
GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, gCallbacksClassInfo.clazz,
|
GET_METHOD_ID(gCallbacksClassInfo.getExcludedDeviceNames, gCallbacksClassInfo.clazz,
|
||||||
"getExcludedDeviceNames", "()[Ljava/lang/String;");
|
"getExcludedDeviceNames", "()[Ljava/lang/String;");
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user