summaryrefslogtreecommitdiff
path: root/services/input/InputReader.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'services/input/InputReader.cpp')
-rw-r--r--services/input/InputReader.cpp3022
1 files changed, 1550 insertions, 1472 deletions
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index db312ad3652e..8786c24da624 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -180,8 +180,9 @@ static void synthesizeButtonKey(InputReaderContext* context, int32_t action,
|| (action == AKEY_EVENT_ACTION_UP
&& (lastButtonState & buttonState)
&& !(currentButtonState & buttonState))) {
- context->getDispatcher()->notifyKey(when, deviceId, source, policyFlags,
+ NotifyKeyArgs args(when, deviceId, source, policyFlags,
action, 0, keyCode, 0, context->getGlobalMetaState(), when);
+ context->getListener()->notifyKey(&args);
}
}
@@ -201,13 +202,19 @@ static void synthesizeButtonKeys(InputReaderContext* context, int32_t action,
InputReader::InputReader(const sp<EventHubInterface>& eventHub,
const sp<InputReaderPolicyInterface>& policy,
- const sp<InputDispatcherInterface>& dispatcher) :
- mEventHub(eventHub), mPolicy(policy), mDispatcher(dispatcher),
+ const sp<InputListenerInterface>& listener) :
+ mContext(this), mEventHub(eventHub), mPolicy(policy),
mGlobalMetaState(0), mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX),
mConfigurationChangesToRefresh(0) {
- refreshConfiguration(0);
- updateGlobalMetaState();
- updateInputConfiguration();
+ mQueuedListener = new QueuedInputListener(listener);
+
+ { // acquire lock
+ AutoMutex _l(mLock);
+
+ refreshConfigurationLocked(0);
+ updateGlobalMetaStateLocked();
+ updateInputConfigurationLocked();
+ } // release lock
}
InputReader::~InputReader() {
@@ -217,39 +224,52 @@ InputReader::~InputReader() {
}
void InputReader::loopOnce() {
- uint32_t changes;
+ int32_t timeoutMillis;
{ // acquire lock
- AutoMutex _l(mStateLock);
+ AutoMutex _l(mLock);
+
+ uint32_t changes = mConfigurationChangesToRefresh;
+ if (changes) {
+ mConfigurationChangesToRefresh = 0;
+ refreshConfigurationLocked(changes);
+ }
- changes = mConfigurationChangesToRefresh;
- mConfigurationChangesToRefresh = 0;
+ timeoutMillis = -1;
+ if (mNextTimeout != LLONG_MAX) {
+ nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+ timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
+ }
} // release lock
- if (changes) {
- refreshConfiguration(changes);
- }
+ size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
- int32_t timeoutMillis = -1;
- if (mNextTimeout != LLONG_MAX) {
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
- timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout);
- }
+ { // acquire lock
+ AutoMutex _l(mLock);
- size_t count = mEventHub->getEvents(timeoutMillis, mEventBuffer, EVENT_BUFFER_SIZE);
- if (count) {
- processEvents(mEventBuffer, count);
- }
- if (!count || timeoutMillis == 0) {
- nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+ if (count) {
+ processEventsLocked(mEventBuffer, count);
+ }
+ if (!count || timeoutMillis == 0) {
+ nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC);
#if DEBUG_RAW_EVENTS
- LOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
+ LOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
#endif
- mNextTimeout = LLONG_MAX;
- timeoutExpired(now);
- }
+ mNextTimeout = LLONG_MAX;
+ timeoutExpiredLocked(now);
+ }
+ } // release lock
+
+ // Flush queued events out to the listener.
+ // This must happen outside of the lock because the listener could potentially call
+ // back into the InputReader's methods, such as getScanCodeState, or become blocked
+ // on another thread similarly waiting to acquire the InputReader lock thereby
+ // resulting in a deadlock. This situation is actually quite plausible because the
+ // listener is actually the input dispatcher, which calls into the window manager,
+ // which occasionally calls into the input reader.
+ mQueuedListener->flush();
}
-void InputReader::processEvents(const RawEvent* rawEvents, size_t count) {
+void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
for (const RawEvent* rawEvent = rawEvents; count;) {
int32_t type = rawEvent->type;
size_t batchSize = 1;
@@ -265,17 +285,17 @@ void InputReader::processEvents(const RawEvent* rawEvents, size_t count) {
#if DEBUG_RAW_EVENTS
LOGD("BatchSize: %d Count: %d", batchSize, count);
#endif
- processEventsForDevice(deviceId, rawEvent, batchSize);
+ processEventsForDeviceLocked(deviceId, rawEvent, batchSize);
} else {
switch (rawEvent->type) {
case EventHubInterface::DEVICE_ADDED:
- addDevice(rawEvent->deviceId);
+ addDeviceLocked(rawEvent->deviceId);
break;
case EventHubInterface::DEVICE_REMOVED:
- removeDevice(rawEvent->deviceId);
+ removeDeviceLocked(rawEvent->deviceId);
break;
case EventHubInterface::FINISHED_DEVICE_SCAN:
- handleConfigurationChanged(rawEvent->when);
+ handleConfigurationChangedLocked(rawEvent->when);
break;
default:
LOG_ASSERT(false); // can't happen
@@ -287,11 +307,11 @@ void InputReader::processEvents(const RawEvent* rawEvents, size_t count) {
}
}
-void InputReader::addDevice(int32_t deviceId) {
+void InputReader::addDeviceLocked(int32_t deviceId) {
String8 name = mEventHub->getDeviceName(deviceId);
uint32_t classes = mEventHub->getDeviceClasses(deviceId);
- InputDevice* device = createDevice(deviceId, name, classes);
+ InputDevice* device = createDeviceLocked(deviceId, name, classes);
device->configure(&mConfig, 0);
if (device->isIgnored()) {
@@ -301,39 +321,23 @@ void InputReader::addDevice(int32_t deviceId) {
device->getSources());
}
- bool added = false;
- { // acquire device registry writer lock
- RWLock::AutoWLock _wl(mDeviceRegistryLock);
-
- ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex < 0) {
- mDevices.add(deviceId, device);
- added = true;
- }
- } // release device registry writer lock
-
- if (! added) {
+ ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+ if (deviceIndex < 0) {
+ mDevices.add(deviceId, device);
+ } else {
LOGW("Ignoring spurious device added event for deviceId %d.", deviceId);
delete device;
return;
}
}
-void InputReader::removeDevice(int32_t deviceId) {
- bool removed = false;
+void InputReader::removeDeviceLocked(int32_t deviceId) {
InputDevice* device = NULL;
- { // acquire device registry writer lock
- RWLock::AutoWLock _wl(mDeviceRegistryLock);
-
- ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex >= 0) {
- device = mDevices.valueAt(deviceIndex);
- mDevices.removeItemsAt(deviceIndex, 1);
- removed = true;
- }
- } // release device registry writer lock
-
- if (! removed) {
+ ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+ if (deviceIndex >= 0) {
+ device = mDevices.valueAt(deviceIndex);
+ mDevices.removeItemsAt(deviceIndex, 1);
+ } else {
LOGW("Ignoring spurious device removed event for deviceId %d.", deviceId);
return;
}
@@ -351,8 +355,9 @@ void InputReader::removeDevice(int32_t deviceId) {
delete device;
}
-InputDevice* InputReader::createDevice(int32_t deviceId, const String8& name, uint32_t classes) {
- InputDevice* device = new InputDevice(this, deviceId, name);
+InputDevice* InputReader::createDeviceLocked(int32_t deviceId,
+ const String8& name, uint32_t classes) {
+ InputDevice* device = new InputDevice(&mContext, deviceId, name);
// External devices.
if (classes & INPUT_DEVICE_CLASS_EXTERNAL) {
@@ -404,52 +409,45 @@ InputDevice* InputReader::createDevice(int32_t deviceId, const String8& name, ui
return device;
}
-void InputReader::processEventsForDevice(int32_t deviceId,
+void InputReader::processEventsForDeviceLocked(int32_t deviceId,
const RawEvent* rawEvents, size_t count) {
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
- ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex < 0) {
- LOGW("Discarding event for unknown deviceId %d.", deviceId);
- return;
- }
+ ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+ if (deviceIndex < 0) {
+ LOGW("Discarding event for unknown deviceId %d.", deviceId);
+ return;
+ }
- InputDevice* device = mDevices.valueAt(deviceIndex);
- if (device->isIgnored()) {
- //LOGD("Discarding event for ignored deviceId %d.", deviceId);
- return;
- }
+ InputDevice* device = mDevices.valueAt(deviceIndex);
+ if (device->isIgnored()) {
+ //LOGD("Discarding event for ignored deviceId %d.", deviceId);
+ return;
+ }
- device->process(rawEvents, count);
- } // release device registry reader lock
+ device->process(rawEvents, count);
}
-void InputReader::timeoutExpired(nsecs_t when) {
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
- for (size_t i = 0; i < mDevices.size(); i++) {
- InputDevice* device = mDevices.valueAt(i);
- if (!device->isIgnored()) {
- device->timeoutExpired(when);
- }
+void InputReader::timeoutExpiredLocked(nsecs_t when) {
+ for (size_t i = 0; i < mDevices.size(); i++) {
+ InputDevice* device = mDevices.valueAt(i);
+ if (!device->isIgnored()) {
+ device->timeoutExpired(when);
}
- } // release device registry reader lock
+ }
}
-void InputReader::handleConfigurationChanged(nsecs_t when) {
+void InputReader::handleConfigurationChangedLocked(nsecs_t when) {
// Reset global meta state because it depends on the list of all configured devices.
- updateGlobalMetaState();
+ updateGlobalMetaStateLocked();
// Update input configuration.
- updateInputConfiguration();
+ updateInputConfigurationLocked();
// Enqueue configuration changed.
- mDispatcher->notifyConfigurationChanged(when);
+ NotifyConfigurationChangedArgs args(when);
+ mQueuedListener->notifyConfigurationChanged(&args);
}
-void InputReader::refreshConfiguration(uint32_t changes) {
+void InputReader::refreshConfigurationLocked(uint32_t changes) {
mPolicy->getReaderConfiguration(&mConfig);
mEventHub->setExcludedDevices(mConfig.excludedDeviceNames);
@@ -459,84 +457,60 @@ void InputReader::refreshConfiguration(uint32_t 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
- }
- }
-}
-
-void InputReader::updateGlobalMetaState() {
- { // acquire state lock
- AutoMutex _l(mStateLock);
-
- mGlobalMetaState = 0;
-
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
for (size_t i = 0; i < mDevices.size(); i++) {
InputDevice* device = mDevices.valueAt(i);
- mGlobalMetaState |= device->getMetaState();
+ device->configure(&mConfig, changes);
}
- } // release device registry reader lock
- } // release state lock
+ }
+ }
}
-int32_t InputReader::getGlobalMetaState() {
- { // acquire state lock
- AutoMutex _l(mStateLock);
+void InputReader::updateGlobalMetaStateLocked() {
+ mGlobalMetaState = 0;
- return mGlobalMetaState;
- } // release state lock
+ for (size_t i = 0; i < mDevices.size(); i++) {
+ InputDevice* device = mDevices.valueAt(i);
+ mGlobalMetaState |= device->getMetaState();
+ }
}
-void InputReader::updateInputConfiguration() {
- { // acquire state lock
- AutoMutex _l(mStateLock);
-
- int32_t touchScreenConfig = InputConfiguration::TOUCHSCREEN_NOTOUCH;
- int32_t keyboardConfig = InputConfiguration::KEYBOARD_NOKEYS;
- int32_t navigationConfig = InputConfiguration::NAVIGATION_NONAV;
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
+int32_t InputReader::getGlobalMetaStateLocked() {
+ return mGlobalMetaState;
+}
- InputDeviceInfo deviceInfo;
- for (size_t i = 0; i < mDevices.size(); i++) {
- InputDevice* device = mDevices.valueAt(i);
- device->getDeviceInfo(& deviceInfo);
- uint32_t sources = deviceInfo.getSources();
+void InputReader::updateInputConfigurationLocked() {
+ int32_t touchScreenConfig = InputConfiguration::TOUCHSCREEN_NOTOUCH;
+ int32_t keyboardConfig = InputConfiguration::KEYBOARD_NOKEYS;
+ int32_t navigationConfig = InputConfiguration::NAVIGATION_NONAV;
+ InputDeviceInfo deviceInfo;
+ for (size_t i = 0; i < mDevices.size(); i++) {
+ InputDevice* device = mDevices.valueAt(i);
+ device->getDeviceInfo(& deviceInfo);
+ uint32_t sources = deviceInfo.getSources();
- if ((sources & AINPUT_SOURCE_TOUCHSCREEN) == AINPUT_SOURCE_TOUCHSCREEN) {
- touchScreenConfig = InputConfiguration::TOUCHSCREEN_FINGER;
- }
- if ((sources & AINPUT_SOURCE_TRACKBALL) == AINPUT_SOURCE_TRACKBALL) {
- navigationConfig = InputConfiguration::NAVIGATION_TRACKBALL;
- } else if ((sources & AINPUT_SOURCE_DPAD) == AINPUT_SOURCE_DPAD) {
- navigationConfig = InputConfiguration::NAVIGATION_DPAD;
- }
- if (deviceInfo.getKeyboardType() == AINPUT_KEYBOARD_TYPE_ALPHABETIC) {
- keyboardConfig = InputConfiguration::KEYBOARD_QWERTY;
- }
- }
- } // release device registry reader lock
+ if ((sources & AINPUT_SOURCE_TOUCHSCREEN) == AINPUT_SOURCE_TOUCHSCREEN) {
+ touchScreenConfig = InputConfiguration::TOUCHSCREEN_FINGER;
+ }
+ if ((sources & AINPUT_SOURCE_TRACKBALL) == AINPUT_SOURCE_TRACKBALL) {
+ navigationConfig = InputConfiguration::NAVIGATION_TRACKBALL;
+ } else if ((sources & AINPUT_SOURCE_DPAD) == AINPUT_SOURCE_DPAD) {
+ navigationConfig = InputConfiguration::NAVIGATION_DPAD;
+ }
+ if (deviceInfo.getKeyboardType() == AINPUT_KEYBOARD_TYPE_ALPHABETIC) {
+ keyboardConfig = InputConfiguration::KEYBOARD_QWERTY;
+ }
+ }
- mInputConfiguration.touchScreen = touchScreenConfig;
- mInputConfiguration.keyboard = keyboardConfig;
- mInputConfiguration.navigation = navigationConfig;
- } // release state lock
+ mInputConfiguration.touchScreen = touchScreenConfig;
+ mInputConfiguration.keyboard = keyboardConfig;
+ mInputConfiguration.navigation = navigationConfig;
}
-void InputReader::disableVirtualKeysUntil(nsecs_t time) {
+void InputReader::disableVirtualKeysUntilLocked(nsecs_t time) {
mDisableVirtualKeysTimeout = time;
}
-bool InputReader::shouldDropVirtualKey(nsecs_t now,
+bool InputReader::shouldDropVirtualKeyLocked(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 "
@@ -550,153 +524,141 @@ bool InputReader::shouldDropVirtualKey(nsecs_t now,
}
}
-void InputReader::fadePointer() {
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
- for (size_t i = 0; i < mDevices.size(); i++) {
- InputDevice* device = mDevices.valueAt(i);
- device->fadePointer();
- }
- } // release device registry reader lock
+void InputReader::fadePointerLocked() {
+ for (size_t i = 0; i < mDevices.size(); i++) {
+ InputDevice* device = mDevices.valueAt(i);
+ device->fadePointer();
+ }
}
-void InputReader::requestTimeoutAtTime(nsecs_t when) {
+void InputReader::requestTimeoutAtTimeLocked(nsecs_t when) {
if (when < mNextTimeout) {
mNextTimeout = when;
}
}
void InputReader::getInputConfiguration(InputConfiguration* outConfiguration) {
- { // acquire state lock
- AutoMutex _l(mStateLock);
+ AutoMutex _l(mLock);
- *outConfiguration = mInputConfiguration;
- } // release state lock
+ *outConfiguration = mInputConfiguration;
}
status_t InputReader::getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo) {
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
+ AutoMutex _l(mLock);
- ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex < 0) {
- return NAME_NOT_FOUND;
- }
+ ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+ if (deviceIndex < 0) {
+ return NAME_NOT_FOUND;
+ }
- InputDevice* device = mDevices.valueAt(deviceIndex);
- if (device->isIgnored()) {
- return NAME_NOT_FOUND;
- }
+ InputDevice* device = mDevices.valueAt(deviceIndex);
+ if (device->isIgnored()) {
+ return NAME_NOT_FOUND;
+ }
- device->getDeviceInfo(outDeviceInfo);
- return OK;
- } // release device registy reader lock
+ device->getDeviceInfo(outDeviceInfo);
+ return OK;
}
void InputReader::getInputDeviceIds(Vector<int32_t>& outDeviceIds) {
- outDeviceIds.clear();
+ AutoMutex _l(mLock);
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
+ outDeviceIds.clear();
- size_t numDevices = mDevices.size();
- for (size_t i = 0; i < numDevices; i++) {
- InputDevice* device = mDevices.valueAt(i);
- if (! device->isIgnored()) {
- outDeviceIds.add(device->getId());
- }
+ size_t numDevices = mDevices.size();
+ for (size_t i = 0; i < numDevices; i++) {
+ InputDevice* device = mDevices.valueAt(i);
+ if (!device->isIgnored()) {
+ outDeviceIds.add(device->getId());
}
- } // release device registy reader lock
+ }
}
int32_t InputReader::getKeyCodeState(int32_t deviceId, uint32_t sourceMask,
int32_t keyCode) {
- return getState(deviceId, sourceMask, keyCode, & InputDevice::getKeyCodeState);
+ AutoMutex _l(mLock);
+
+ return getStateLocked(deviceId, sourceMask, keyCode, &InputDevice::getKeyCodeState);
}
int32_t InputReader::getScanCodeState(int32_t deviceId, uint32_t sourceMask,
int32_t scanCode) {
- return getState(deviceId, sourceMask, scanCode, & InputDevice::getScanCodeState);
+ AutoMutex _l(mLock);
+
+ return getStateLocked(deviceId, sourceMask, scanCode, &InputDevice::getScanCodeState);
}
int32_t InputReader::getSwitchState(int32_t deviceId, uint32_t sourceMask, int32_t switchCode) {
- return getState(deviceId, sourceMask, switchCode, & InputDevice::getSwitchState);
+ AutoMutex _l(mLock);
+
+ return getStateLocked(deviceId, sourceMask, switchCode, &InputDevice::getSwitchState);
}
-int32_t InputReader::getState(int32_t deviceId, uint32_t sourceMask, int32_t code,
+int32_t InputReader::getStateLocked(int32_t deviceId, uint32_t sourceMask, int32_t code,
GetStateFunc getStateFunc) {
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
- int32_t result = AKEY_STATE_UNKNOWN;
- if (deviceId >= 0) {
- ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex >= 0) {
- InputDevice* device = mDevices.valueAt(deviceIndex);
- if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
- result = (device->*getStateFunc)(sourceMask, code);
- }
+ int32_t result = AKEY_STATE_UNKNOWN;
+ if (deviceId >= 0) {
+ ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+ if (deviceIndex >= 0) {
+ InputDevice* device = mDevices.valueAt(deviceIndex);
+ if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
+ result = (device->*getStateFunc)(sourceMask, code);
}
- } else {
- size_t numDevices = mDevices.size();
- for (size_t i = 0; i < numDevices; i++) {
- InputDevice* device = mDevices.valueAt(i);
- if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
- result = (device->*getStateFunc)(sourceMask, code);
- if (result >= AKEY_STATE_DOWN) {
- return result;
- }
+ }
+ } else {
+ size_t numDevices = mDevices.size();
+ for (size_t i = 0; i < numDevices; i++) {
+ InputDevice* device = mDevices.valueAt(i);
+ if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
+ result = (device->*getStateFunc)(sourceMask, code);
+ if (result >= AKEY_STATE_DOWN) {
+ return result;
}
}
}
- return result;
- } // release device registy reader lock
+ }
+ return result;
}
bool InputReader::hasKeys(int32_t deviceId, uint32_t sourceMask,
size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
+ AutoMutex _l(mLock);
+
memset(outFlags, 0, numCodes);
- return markSupportedKeyCodes(deviceId, sourceMask, numCodes, keyCodes, outFlags);
+ return markSupportedKeyCodesLocked(deviceId, sourceMask, numCodes, keyCodes, outFlags);
}
-bool InputReader::markSupportedKeyCodes(int32_t deviceId, uint32_t sourceMask, size_t numCodes,
- const int32_t* keyCodes, uint8_t* outFlags) {
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
- bool result = false;
- if (deviceId >= 0) {
- ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
- if (deviceIndex >= 0) {
- InputDevice* device = mDevices.valueAt(deviceIndex);
- if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
- result = device->markSupportedKeyCodes(sourceMask,
- numCodes, keyCodes, outFlags);
- }
+bool InputReader::markSupportedKeyCodesLocked(int32_t deviceId, uint32_t sourceMask,
+ size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) {
+ bool result = false;
+ if (deviceId >= 0) {
+ ssize_t deviceIndex = mDevices.indexOfKey(deviceId);
+ if (deviceIndex >= 0) {
+ InputDevice* device = mDevices.valueAt(deviceIndex);
+ if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
+ result = device->markSupportedKeyCodes(sourceMask,
+ numCodes, keyCodes, outFlags);
}
- } else {
- size_t numDevices = mDevices.size();
- for (size_t i = 0; i < numDevices; i++) {
- InputDevice* device = mDevices.valueAt(i);
- if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
- result |= device->markSupportedKeyCodes(sourceMask,
- numCodes, keyCodes, outFlags);
- }
+ }
+ } else {
+ size_t numDevices = mDevices.size();
+ for (size_t i = 0; i < numDevices; i++) {
+ InputDevice* device = mDevices.valueAt(i);
+ if (! device->isIgnored() && sourcesMatchMask(device->getSources(), sourceMask)) {
+ result |= device->markSupportedKeyCodes(sourceMask,
+ numCodes, keyCodes, outFlags);
}
}
- return result;
- } // release device registy reader lock
+ }
+ return result;
}
void InputReader::requestRefreshConfiguration(uint32_t changes) {
- if (changes) {
- bool needWake;
- { // acquire lock
- AutoMutex _l(mStateLock);
+ AutoMutex _l(mLock);
- needWake = !mConfigurationChangesToRefresh;
- mConfigurationChangesToRefresh |= changes;
- } // release lock
+ if (changes) {
+ bool needWake = !mConfigurationChangesToRefresh;
+ mConfigurationChangesToRefresh |= changes;
if (needWake) {
mEventHub->wake();
@@ -705,18 +667,16 @@ void InputReader::requestRefreshConfiguration(uint32_t changes) {
}
void InputReader::dump(String8& dump) {
+ AutoMutex _l(mLock);
+
mEventHub->dump(dump);
dump.append("\n");
dump.append("Input Reader State:\n");
- { // acquire device registry reader lock
- RWLock::AutoRLock _rl(mDeviceRegistryLock);
-
- for (size_t i = 0; i < mDevices.size(); i++) {
- mDevices.valueAt(i)->dump(dump);
- }
- } // release device registy reader lock
+ for (size_t i = 0; i < mDevices.size(); i++) {
+ mDevices.valueAt(i)->dump(dump);
+ }
dump.append(INDENT "Configuration:\n");
dump.append(INDENT2 "ExcludedDeviceNames: [");
@@ -772,6 +732,56 @@ void InputReader::dump(String8& dump) {
}
+// --- InputReader::ContextImpl ---
+
+InputReader::ContextImpl::ContextImpl(InputReader* reader) :
+ mReader(reader) {
+}
+
+void InputReader::ContextImpl::updateGlobalMetaState() {
+ // lock is already held by the input loop
+ mReader->updateGlobalMetaStateLocked();
+}
+
+int32_t InputReader::ContextImpl::getGlobalMetaState() {
+ // lock is already held by the input loop
+ return mReader->getGlobalMetaStateLocked();
+}
+
+void InputReader::ContextImpl::disableVirtualKeysUntil(nsecs_t time) {
+ // lock is already held by the input loop
+ mReader->disableVirtualKeysUntilLocked(time);
+}
+
+bool InputReader::ContextImpl::shouldDropVirtualKey(nsecs_t now,
+ InputDevice* device, int32_t keyCode, int32_t scanCode) {
+ // lock is already held by the input loop
+ return mReader->shouldDropVirtualKeyLocked(now, device, keyCode, scanCode);
+}
+
+void InputReader::ContextImpl::fadePointer() {
+ // lock is already held by the input loop
+ mReader->fadePointerLocked();
+}
+
+void InputReader::ContextImpl::requestTimeoutAtTime(nsecs_t when) {
+ // lock is already held by the input loop
+ mReader->requestTimeoutAtTimeLocked(when);
+}
+
+InputReaderPolicyInterface* InputReader::ContextImpl::getPolicy() {
+ return mReader->mPolicy.get();
+}
+
+InputListenerInterface* InputReader::ContextImpl::getListener() {
+ return mReader->mQueuedListener.get();
+}
+
+EventHubInterface* InputReader::ContextImpl::getEventHub() {
+ return mReader->mEventHub.get();
+}
+
+
// --- InputReaderThread ---
InputReaderThread::InputReaderThread(const sp<InputReaderInterface>& reader) :
@@ -1170,6 +1180,96 @@ bool TouchButtonAccumulator::isHovering() const {
}
+// --- RawPointerAxes ---
+
+RawPointerAxes::RawPointerAxes() {
+ clear();
+}
+
+void RawPointerAxes::clear() {
+ x.clear();
+ y.clear();
+ pressure.clear();
+ touchMajor.clear();
+ touchMinor.clear();
+ toolMajor.clear();
+ toolMinor.clear();
+ orientation.clear();
+ distance.clear();
+ trackingId.clear();
+ slot.clear();
+}
+
+
+// --- RawPointerData ---
+
+RawPointerData::RawPointerData() {
+ clear();
+}
+
+void RawPointerData::clear() {
+ pointerCount = 0;
+ clearIdBits();
+}
+
+void RawPointerData::copyFrom(const RawPointerData& other) {
+ pointerCount = other.pointerCount;
+ hoveringIdBits = other.hoveringIdBits;
+ touchingIdBits = other.touchingIdBits;
+
+ for (uint32_t i = 0; i < pointerCount; i++) {
+ pointers[i] = other.pointers[i];
+
+ int id = pointers[i].id;
+ idToIndex[id] = other.idToIndex[id];
+ }
+}
+
+void RawPointerData::getCentroidOfTouchingPointers(float* outX, float* outY) const {
+ float x = 0, y = 0;
+ uint32_t count = touchingIdBits.count();
+ if (count) {
+ for (BitSet32 idBits(touchingIdBits); !idBits.isEmpty(); ) {
+ uint32_t id = idBits.clearFirstMarkedBit();
+ const Pointer& pointer = pointerForId(id);
+ x += pointer.x;
+ y += pointer.y;
+ }
+ x /= count;
+ y /= count;
+ }
+ *outX = x;
+ *outY = y;
+}
+
+
+// --- CookedPointerData ---
+
+CookedPointerData::CookedPointerData() {
+ clear();
+}
+
+void CookedPointerData::clear() {
+ pointerCount = 0;
+ hoveringIdBits.clear();
+ touchingIdBits.clear();
+}
+
+void CookedPointerData::copyFrom(const CookedPointerData& other) {
+ pointerCount = other.pointerCount;
+ hoveringIdBits = other.hoveringIdBits;
+ touchingIdBits = other.touchingIdBits;
+
+ for (uint32_t i = 0; i < pointerCount; i++) {
+ pointerProperties[i].copyFrom(other.pointerProperties[i]);
+ pointerCoords[i].copyFrom(other.pointerCoords[i]);
+
+ int id = pointerProperties[i].id;
+ idToIndex[id] = other.idToIndex[id];
+ }
+}
+
+
// --- SingleTouchMotionAccumulator ---
SingleTouchMotionAccumulator::SingleTouchMotionAccumulator() {
@@ -1298,6 +1398,10 @@ void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) {
slot->mInUse = true;
slot->mAbsMTPressure = rawEvent->value;
break;
+ case ABS_MT_DISTANCE:
+ slot->mInUse = true;
+ slot->mAbsMTDistance = rawEvent->value;
+ break;
case ABS_MT_TOOL_TYPE:
slot->mInUse = true;
slot->mAbsMTToolType = rawEvent->value;
@@ -1338,8 +1442,8 @@ void MultiTouchMotionAccumulator::Slot::clear() {
mAbsMTOrientation = 0;
mAbsMTTrackingId = -1;
mAbsMTPressure = 0;
- mAbsMTToolType = 0;
mAbsMTDistance = 0;
+ mAbsMTToolType = 0;
}
int32_t MultiTouchMotionAccumulator::Slot::getToolType() const {
@@ -1404,6 +1508,10 @@ int32_t InputMapper::getMetaState() {
void InputMapper::fadePointer() {
}
+status_t InputMapper::getAbsoluteAxisInfo(int32_t axis, RawAbsoluteAxisInfo* axisInfo) {
+ return getEventHub()->getAbsoluteAxisInfo(getDeviceId(), axis, axisInfo);
+}
+
void InputMapper::dumpRawAbsoluteAxisInfo(String8& dump,
const RawAbsoluteAxisInfo& axis, const char* name) {
if (axis.valid) {
@@ -1437,7 +1545,8 @@ void SwitchInputMapper::process(const RawEvent* rawEvent) {
}
void SwitchInputMapper::processSwitch(nsecs_t when, int32_t switchCode, int32_t switchValue) {
- getDispatcher()->notifySwitch(when, switchCode, switchValue, 0);
+ NotifySwitchArgs args(when, 0, switchCode, switchValue);
+ getListener()->notifySwitch(&args);
}
int32_t SwitchInputMapper::getSwitchState(uint32_t sourceMask, int32_t switchCode) {
@@ -1451,15 +1560,15 @@ KeyboardInputMapper::KeyboardInputMapper(InputDevice* device,
uint32_t source, int32_t keyboardType) :
InputMapper(device), mSource(source),
mKeyboardType(keyboardType) {
- initializeLocked();
+ initialize();
}
KeyboardInputMapper::~KeyboardInputMapper() {
}
-void KeyboardInputMapper::initializeLocked() {
- mLocked.metaState = AMETA_NONE;
- mLocked.downTime = 0;
+void KeyboardInputMapper::initialize() {
+ mMetaState = AMETA_NONE;
+ mDownTime = 0;
}
uint32_t KeyboardInputMapper::getSources() {
@@ -1473,15 +1582,12 @@ void KeyboardInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
}
void KeyboardInputMapper::dump(String8& dump) {
- { // acquire lock
- AutoMutex _l(mLock);
- dump.append(INDENT2 "Keyboard Input Mapper:\n");
- dumpParameters(dump);
- dump.appendFormat(INDENT3 "KeyboardType: %d\n", mKeyboardType);
- dump.appendFormat(INDENT3 "KeyDowns: %d keys currently down\n", mLocked.keyDowns.size());
- dump.appendFormat(INDENT3 "MetaState: 0x%0x\n", mLocked.metaState);
- dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime);
- } // release lock
+ dump.append(INDENT2 "Keyboard Input Mapper:\n");
+ dumpParameters(dump);
+ dump.appendFormat(INDENT3 "KeyboardType: %d\n", mKeyboardType);
+ dump.appendFormat(INDENT3 "KeyDowns: %d keys currently down\n", mKeyDowns.size());
+ dump.appendFormat(INDENT3 "MetaState: 0x%0x\n", mMetaState);
+ dump.appendFormat(INDENT3 "DownTime: %lld\n", mDownTime);
}
@@ -1493,10 +1599,7 @@ void KeyboardInputMapper::configure(const InputReaderConfiguration* config, uint
configureParameters();
// Reset LEDs.
- {
- AutoMutex _l(mLock);
- resetLedStateLocked();
- }
+ resetLedState();
}
}
@@ -1520,27 +1623,16 @@ void KeyboardInputMapper::dumpParameters(String8& dump) {
}
void KeyboardInputMapper::reset() {
- for (;;) {
- int32_t keyCode, scanCode;
- { // acquire lock
- AutoMutex _l(mLock);
-
- // Synthesize key up event on reset if keys are currently down.
- if (mLocked.keyDowns.isEmpty()) {
- initializeLocked();
- resetLedStateLocked();
- break; // done
- }
-
- const KeyDown& keyDown = mLocked.keyDowns.top();
- keyCode = keyDown.keyCode;
- scanCode = keyDown.scanCode;
- } // release lock
-
+ // Synthesize key up event on reset if keys are currently down.
+ while (!mKeyDowns.isEmpty()) {
+ const KeyDown& keyDown = mKeyDowns.top();
nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
- processKey(when, false, keyCode, scanCode, 0);
+ processKey(when, false, keyDown.keyCode, keyDown.scanCode, 0);
}
+ initialize();
+ resetLedState();
+
InputMapper::reset();
getContext()->updateGlobalMetaState();
}
@@ -1567,72 +1659,66 @@ bool KeyboardInputMapper::isKeyboardOrGamepadKey(int32_t scanCode) {
void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
int32_t scanCode, uint32_t policyFlags) {
- int32_t newMetaState;
- nsecs_t downTime;
- bool metaStateChanged = false;
-
- { // acquire lock
- AutoMutex _l(mLock);
-
- if (down) {
- // Rotate key codes according to orientation if needed.
- // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
- if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0) {
- int32_t orientation;
- if (!getPolicy()->getDisplayInfo(mParameters.associatedDisplayId,
- false /*external*/, NULL, NULL, & orientation)) {
- orientation = DISPLAY_ORIENTATION_0;
- }
- keyCode = rotateKeyCode(keyCode, orientation);
+ if (down) {
+ // Rotate key codes according to orientation if needed.
+ // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
+ if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0) {
+ int32_t orientation;
+ if (!getPolicy()->getDisplayInfo(mParameters.associatedDisplayId,
+ false /*external*/, NULL, NULL, & orientation)) {
+ orientation = DISPLAY_ORIENTATION_0;
}
- // Add key down.
- ssize_t keyDownIndex = findKeyDownLocked(scanCode);
- if (keyDownIndex >= 0) {
- // key repeat, be sure to use same keycode as before in case of rotation
- keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode;
- } else {
- // key down
- if ((policyFlags & POLICY_FLAG_VIRTUAL)
- && mContext->shouldDropVirtualKey(when,
- getDevice(), keyCode, scanCode)) {
- return;
- }
-
- mLocked.keyDowns.push();
- KeyDown& keyDown = mLocked.keyDowns.editTop();
- keyDown.keyCode = keyCode;
- keyDown.scanCode = scanCode;
- }
+ keyCode = rotateKeyCode(keyCode, orientation);
+ }
- mLocked.downTime = when;
+ // Add key down.
+ ssize_t keyDownIndex = findKeyDown(scanCode);
+ if (keyDownIndex >= 0) {
+ // key repeat, be sure to use same keycode as before in case of rotation
+ keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
} else {
- // Remove key down.
- ssize_t keyDownIndex = findKeyDownLocked(scanCode);
- if (keyDownIndex >= 0) {
- // key up, be sure to use same keycode as before in case of rotation
- keyCode = mLocked.keyDowns.itemAt(keyDownIndex).keyCode;
- mLocked.keyDowns.removeAt(size_t(keyDownIndex));
- } else {
- // key was not actually down
- LOGI("Dropping key up from device %s because the key was not down. "
- "keyCode=%d, scanCode=%d",
- getDeviceName().string(), keyCode, scanCode);
+ // key down
+ if ((policyFlags & POLICY_FLAG_VIRTUAL)
+ && mContext->shouldDropVirtualKey(when,
+ getDevice(), keyCode, scanCode)) {
return;
}
+
+ mKeyDowns.push();
+ KeyDown& keyDown = mKeyDowns.editTop();
+ keyDown.keyCode = keyCode;
+ keyDown.scanCode = scanCode;
}
- int32_t oldMetaState = mLocked.metaState;
- newMetaState = updateMetaState(keyCode, down, oldMetaState);
- if (oldMetaState != newMetaState) {
- mLocked.metaState = newMetaState;
- metaStateChanged = true;
- updateLedStateLocked(false);
+ mDownTime = when;
+ } else {
+ // Remove key down.
+ ssize_t keyDownIndex = findKeyDown(scanCode);
+ if (keyDownIndex >= 0) {
+ // key up, be sure to use same keycode as before in case of rotation
+ keyCode = mKeyDowns.itemAt(keyDownIndex).keyCode;
+ mKeyDowns.removeAt(size_t(keyDownIndex));
+ } else {
+ // key was not actually down
+ LOGI("Dropping key up from device %s because the key was not down. "
+ "keyCode=%d, scanCode=%d",
+ getDeviceName().string(), keyCode, scanCode);
+ return;
}
+ }
- downTime = mLocked.downTime;
- } // release lock
+ bool metaStateChanged = false;
+ int32_t oldMetaState = mMetaState;
+ int32_t newMetaState = updateMetaState(keyCode, down, oldMetaState);
+ if (oldMetaState != newMetaState) {
+ mMetaState = newMetaState;
+ metaStateChanged = true;
+ updateLedState(false);
+ }
+
+ nsecs_t downTime = mDownTime;
// Key down on external an keyboard should wake the device.
// We don't do this for internal keyboards to prevent them from waking up in your pocket.
@@ -1652,15 +1738,16 @@ void KeyboardInputMapper::processKey(nsecs_t when, bool down, int32_t keyCode,
getContext()->fadePointer();
}
- getDispatcher()->notifyKey(when, getDeviceId(), mSource, policyFlags,
+ NotifyKeyArgs args(when, getDeviceId(), mSource, policyFlags,
down ? AKEY_EVENT_ACTION_DOWN : AKEY_EVENT_ACTION_UP,
AKEY_EVENT_FLAG_FROM_SYSTEM, keyCode, scanCode, newMetaState, downTime);
+ getListener()->notifyKey(&args);
}
-ssize_t KeyboardInputMapper::findKeyDownLocked(int32_t scanCode) {
- size_t n = mLocked.keyDowns.size();
+ssize_t KeyboardInputMapper::findKeyDown(int32_t scanCode) {
+ size_t n = mKeyDowns.size();
for (size_t i = 0; i < n; i++) {
- if (mLocked.keyDowns[i].scanCode == scanCode) {
+ if (mKeyDowns[i].scanCode == scanCode) {
return i;
}
}
@@ -1681,38 +1768,35 @@ bool KeyboardInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numC
}
int32_t KeyboardInputMapper::getMetaState() {
- { // acquire lock
- AutoMutex _l(mLock);
- return mLocked.metaState;
- } // release lock
+ return mMetaState;
}
-void KeyboardInputMapper::resetLedStateLocked() {
- initializeLedStateLocked(mLocked.capsLockLedState, LED_CAPSL);
- initializeLedStateLocked(mLocked.numLockLedState, LED_NUML);
- initializeLedStateLocked(mLocked.scrollLockLedState, LED_SCROLLL);
+void KeyboardInputMapper::resetLedState() {
+ initializeLedState(mCapsLockLedState, LED_CAPSL);
+ initializeLedState(mNumLockLedState, LED_NUML);
+ initializeLedState(mScrollLockLedState, LED_SCROLLL);
- updateLedStateLocked(true);
+ updateLedState(true);
}
-void KeyboardInputMapper::initializeLedStateLocked(LockedState::LedState& ledState, int32_t led) {
+void KeyboardInputMapper::initializeLedState(LedState& ledState, int32_t led) {
ledState.avail = getEventHub()->hasLed(getDeviceId(), led);
ledState.on = false;
}
-void KeyboardInputMapper::updateLedStateLocked(bool reset) {
- updateLedStateForModifierLocked(mLocked.capsLockLedState, LED_CAPSL,
+void KeyboardInputMapper::updateLedState(bool reset) {
+ updateLedStateForModifier(mCapsLockLedState, LED_CAPSL,
AMETA_CAPS_LOCK_ON, reset);
- updateLedStateForModifierLocked(mLocked.numLockLedState, LED_NUML,
+ updateLedStateForModifier(mNumLockLedState, LED_NUML,
AMETA_NUM_LOCK_ON, reset);
- updateLedStateForModifierLocked(mLocked.scrollLockLedState, LED_SCROLLL,
+ updateLedStateForModifier(mScrollLockLedState, LED_SCROLLL,
AMETA_SCROLL_LOCK_ON, reset);
}
-void KeyboardInputMapper::updateLedStateForModifierLocked(LockedState::LedState& ledState,
+void KeyboardInputMapper::updateLedStateForModifier(LedState& ledState,
int32_t led, int32_t modifier, bool reset) {
if (ledState.avail) {
- bool desiredState = (mLocked.metaState & modifier) != 0;
+ bool desiredState = (mMetaState & modifier) != 0;
if (reset || ledState.on != desiredState) {
getEventHub()->setLedState(getDeviceId(), led, desiredState);
ledState.on = desiredState;
@@ -1725,7 +1809,7 @@ void KeyboardInputMapper::updateLedStateForModifierLocked(LockedState::LedState&
CursorInputMapper::CursorInputMapper(InputDevice* device) :
InputMapper(device) {
- initializeLocked();
+ initialize();
}
CursorInputMapper::~CursorInputMapper() {
@@ -1759,24 +1843,21 @@ void CursorInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
}
void CursorInputMapper::dump(String8& dump) {
- { // acquire lock
- AutoMutex _l(mLock);
- dump.append(INDENT2 "Cursor Input Mapper:\n");
- dumpParameters(dump);
- dump.appendFormat(INDENT3 "XScale: %0.3f\n", mXScale);
- dump.appendFormat(INDENT3 "YScale: %0.3f\n", mYScale);
- dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mXPrecision);
- dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mYPrecision);
- dump.appendFormat(INDENT3 "HaveVWheel: %s\n",
- toString(mCursorMotionAccumulator.haveRelativeVWheel()));
- dump.appendFormat(INDENT3 "HaveHWheel: %s\n",
- toString(mCursorMotionAccumulator.haveRelativeHWheel()));
- dump.appendFormat(INDENT3 "VWheelScale: %0.3f\n", mVWheelScale);
- dump.appendFormat(INDENT3 "HWheelScale: %0.3f\n", mHWheelScale);
- dump.appendFormat(INDENT3 "ButtonState: 0x%08x\n", mLocked.buttonState);
- dump.appendFormat(INDENT3 "Down: %s\n", toString(isPointerDown(mLocked.buttonState)));
- dump.appendFormat(INDENT3 "DownTime: %lld\n", mLocked.downTime);
- } // release lock
+ dump.append(INDENT2 "Cursor Input Mapper:\n");
+ dumpParameters(dump);
+ dump.appendFormat(INDENT3 "XScale: %0.3f\n", mXScale);
+ dump.appendFormat(INDENT3 "YScale: %0.3f\n", mYScale);
+ dump.appendFormat(INDENT3 "XPrecision: %0.3f\n", mXPrecision);
+ dump.appendFormat(INDENT3 "YPrecision: %0.3f\n", mYPrecision);
+ dump.appendFormat(INDENT3 "HaveVWheel: %s\n",
+ toString(mCursorMotionAccumulator.haveRelativeVWheel()));
+ dump.appendFormat(INDENT3 "HaveHWheel: %s\n",
+ toString(mCursorMotionAccumulator.haveRelativeHWheel()));
+ dump.appendFormat(INDENT3 "VWheelScale: %0.3f\n", mVWheelScale);
+ dump.appendFormat(INDENT3 "HWheelScale: %0.3f\n", mHWheelScale);
+ dump.appendFormat(INDENT3 "ButtonState: 0x%08x\n", mButtonState);
+ dump.appendFormat(INDENT3 "Down: %s\n", toString(isPointerDown(mButtonState)));
+ dump.appendFormat(INDENT3 "DownTime: %lld\n", mDownTime);
}
void CursorInputMapper::configure(const InputReaderConfiguration* config, uint32_t changes) {
@@ -1859,38 +1940,27 @@ void CursorInputMapper::dumpParameters(String8& dump) {
toString(mParameters.orientationAware));
}
-void CursorInputMapper::initializeLocked() {
+void CursorInputMapper::initialize() {
mCursorButtonAccumulator.clearButtons();
mCursorMotionAccumulator.clearRelativeAxes();
- mLocked.buttonState = 0;
- mLocked.downTime = 0;
+ mButtonState = 0;
+ mDownTime = 0;
}
void CursorInputMapper::reset() {
- for (;;) {
- int32_t buttonState;
- { // acquire lock
- AutoMutex _l(mLock);
-
- buttonState = mLocked.buttonState;
- if (!buttonState) {
- initializeLocked();
- break; // done
- }
- } // release lock
+ // Reset velocity.
+ mPointerVelocityControl.reset();
+ mWheelXVelocityControl.reset();
+ mWheelYVelocityControl.reset();
- // Reset velocity.
- mPointerVelocityControl.reset();
- mWheelXVelocityControl.reset();
- mWheelYVelocityControl.reset();
+ // Synthesize button up event on reset.
+ nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
+ mCursorButtonAccumulator.clearButtons();
+ mCursorMotionAccumulator.clearRelativeAxes();
+ sync(when);
- // Synthesize button up event on reset.
- nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
- mCursorButtonAccumulator.clearButtons();
- mCursorMotionAccumulator.clearRelativeAxes();
- sync(when);
- }
+ initialize();
InputMapper::reset();
}
@@ -1905,98 +1975,84 @@ void CursorInputMapper::process(const RawEvent* rawEvent) {
}
void CursorInputMapper::sync(nsecs_t when) {
- int32_t motionEventAction;
- int32_t lastButtonState, currentButtonState;
- PointerProperties pointerProperties;
- PointerCoords pointerCoords;
- nsecs_t downTime;
- float vscroll, hscroll;
- { // acquire lock
- AutoMutex _l(mLock);
-
- lastButtonState = mLocked.buttonState;
- currentButtonState = mCursorButtonAccumulator.getButtonState();
- mLocked.buttonState = currentButtonState;
-
- bool wasDown = isPointerDown(lastButtonState);
- bool down = isPointerDown(currentButtonState);
- bool downChanged;
- if (!wasDown && down) {
- mLocked.downTime = when;
- downChanged = true;
- } else if (wasDown && !down) {
- downChanged = true;
- } else {
- downChanged = false;
- }
- downTime = mLocked.downTime;
-
- if (downChanged) {
- motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
- } else if (down || mPointerController == NULL) {
- motionEventAction = AMOTION_EVENT_ACTION_MOVE;
- } else {
- motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE;
- }
-
- float deltaX = mCursorMotionAccumulator.getRelativeX() * mXScale;
- float deltaY = mCursorMotionAccumulator.getRelativeY() * mYScale;
+ int32_t lastButtonState = mButtonState;
+ int32_t currentButtonState = mCursorButtonAccumulator.getButtonState();
+ mButtonState = currentButtonState;
+
+ bool wasDown = isPointerDown(lastButtonState);
+ bool down = isPointerDown(currentButtonState);
+ bool downChanged;
+ if (!wasDown && down) {
+ mDownTime = when;
+ downChanged = true;
+ } else if (wasDown && !down) {
+ downChanged = true;
+ } else {
+ downChanged = false;
+ }
+ nsecs_t downTime = mDownTime;
+ bool buttonsChanged = currentButtonState != lastButtonState;
- if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0
- && (deltaX != 0.0f || deltaY != 0.0f)) {
- // Rotate motion based on display orientation if needed.
- // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
- int32_t orientation;
- if (! getPolicy()->getDisplayInfo(mParameters.associatedDisplayId,
- false /*external*/, NULL, NULL, & orientation)) {
- orientation = DISPLAY_ORIENTATION_0;
- }
+ float deltaX = mCursorMotionAccumulator.getRelativeX() * mXScale;
+ float deltaY = mCursorMotionAccumulator.getRelativeY() * mYScale;
+ bool moved = deltaX != 0 || deltaY != 0;
- rotateDelta(orientation, &deltaX, &deltaY);
+ if (mParameters.orientationAware && mParameters.associatedDisplayId >= 0
+ && (deltaX != 0.0f || deltaY != 0.0f)) {
+ // Rotate motion based on display orientation if needed.
+ // Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
+ int32_t orientation;
+ if (! getPolicy()->getDisplayInfo(mParameters.associatedDisplayId,
+ false /*external*/, NULL, NULL, & orientation)) {
+ orientation = DISPLAY_ORIENTATION_0;
}
- pointerProperties.clear();
- pointerProperties.id = 0;
- pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE;
+ rotateDelta(orientation, &deltaX, &deltaY);
+ }
- pointerCoords.clear();
+ PointerProperties pointerProperties;
+ pointerProperties.clear();
+ pointerProperties.id = 0;
+ pointerProperties.toolType = AMOTION_EVENT_TOOL_TYPE_MOUSE;
- vscroll = mCursorMotionAccumulator.getRelativeVWheel();
- hscroll = mCursorMotionAccumulator.getRelativeHWheel();
+ PointerCoords pointerCoords;
+ pointerCoords.clear();
- mWheelYVelocityControl.move(when, NULL, &vscroll);
- mWheelXVelocityControl.move(when, &hscroll, NULL);
+ float vscroll = mCursorMotionAccumulator.getRelativeVWheel();
+ float hscroll = mCursorMotionAccumulator.getRelativeHWheel();
+ bool scrolled = vscroll != 0 || hscroll != 0;
- mPointerVelocityControl.move(when, &deltaX, &deltaY);
+ mWheelYVelocityControl.move(when, NULL, &vscroll);
+ mWheelXVelocityControl.move(when, &hscroll, NULL);
- if (mPointerController != NULL) {
- if (deltaX != 0 || deltaY != 0 || vscroll != 0 || hscroll != 0
- || currentButtonState != lastButtonState) {
- mPointerController->setPresentation(
- PointerControllerInterface::PRESENTATION_POINTER);
+ mPointerVelocityControl.move(when, &deltaX, &deltaY);
- if (deltaX != 0 || deltaY != 0) {
- mPointerController->move(deltaX, deltaY);
- }
+ if (mPointerController != NULL) {
+ if (moved || scrolled || buttonsChanged) {
+ mPointerController->setPresentation(
+ PointerControllerInterface::PRESENTATION_POINTER);
- if (currentButtonState != lastButtonState) {
- mPointerController->setButtonState(currentButtonState);
- }
+ if (moved) {
+ mPointerController->move(deltaX, deltaY);
+ }
- mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
+ if (buttonsChanged) {
+ mPointerController->setButtonState(currentButtonState);
}
- float x, y;
- mPointerController->getPosition(&x, &y);
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
- } else {
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
+ mPointerController->unfade(PointerControllerInterface::TRANSITION_IMMEDIATE);
}
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);
- } // release lock
+ float x, y;
+ mPointerController->getPosition(&x, &y);
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
+ } else {
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, deltaX);
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, deltaY);
+ }
+
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, down ? 1.0f : 0.0f);
// Moving an external trackball or mouse should wake the device.
// We don't do this for internal cursor devices to prevent them from waking up
@@ -2012,29 +2068,43 @@ void CursorInputMapper::sync(nsecs_t when) {
policyFlags, lastButtonState, currentButtonState);
// Send motion event.
- int32_t metaState = mContext->getGlobalMetaState();
- getDispatcher()->notifyMotion(when, getDeviceId(), mSource, policyFlags,
- motionEventAction, 0, metaState, currentButtonState, 0,
- 1, &pointerProperties, &pointerCoords, mXPrecision, mYPrecision, downTime);
-
- // Send hover move after UP to tell the application that the mouse is hovering now.
- if (motionEventAction == AMOTION_EVENT_ACTION_UP
- && mPointerController != NULL) {
- getDispatcher()->notifyMotion(when, getDeviceId(), mSource, policyFlags,
- AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
- metaState, currentButtonState, AMOTION_EVENT_EDGE_FLAG_NONE,
+ if (downChanged || moved || scrolled || buttonsChanged) {
+ int32_t metaState = mContext->getGlobalMetaState();
+ int32_t motionEventAction;
+ if (downChanged) {
+ motionEventAction = down ? AMOTION_EVENT_ACTION_DOWN : AMOTION_EVENT_ACTION_UP;
+ } else if (down || mPointerController == NULL) {
+ motionEventAction = AMOTION_EVENT_ACTION_MOVE;
+ } else {
+ motionEventAction = AMOTION_EVENT_ACTION_HOVER_MOVE;
+ }
+
+ NotifyMotionArgs args(when, getDeviceId(), mSource, policyFlags,
+ motionEventAction, 0, metaState, currentButtonState, 0,
1, &pointerProperties, &pointerCoords, mXPrecision, mYPrecision, downTime);
- }
+ getListener()->notifyMotion(&args);
+
+ // Send hover move after UP to tell the application that the mouse is hovering now.
+ if (motionEventAction == AMOTION_EVENT_ACTION_UP
+ && mPointerController != NULL) {
+ NotifyMotionArgs hoverArgs(when, getDeviceId(), mSource, policyFlags,
+ AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
+ metaState, currentButtonState, AMOTION_EVENT_EDGE_FLAG_NONE,
+ 1, &pointerProperties, &pointerCoords, mXPrecision, mYPrecision, downTime);
+ getListener()->notifyMotion(&hoverArgs);
+ }
- // Send scroll events.
- if (vscroll != 0 || hscroll != 0) {
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
- pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
+ // Send scroll events.
+ if (scrolled) {
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_VSCROLL, vscroll);
+ pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_HSCROLL, hscroll);
- getDispatcher()->notifyMotion(when, getDeviceId(), mSource, policyFlags,
- AMOTION_EVENT_ACTION_SCROLL, 0, metaState, currentButtonState,
- AMOTION_EVENT_EDGE_FLAG_NONE,
- 1, &pointerProperties, &pointerCoords, mXPrecision, mYPrecision, downTime);
+ NotifyMotionArgs scrollArgs(when, getDeviceId(), mSource, policyFlags,
+ AMOTION_EVENT_ACTION_SCROLL, 0, metaState, currentButtonState,
+ AMOTION_EVENT_EDGE_FLAG_NONE,
+ 1, &pointerProperties, &pointerCoords, mXPrecision, mYPrecision, downTime);
+ getListener()->notifyMotion(&scrollArgs);
+ }
}
// Synthesize key up from buttons if needed.
@@ -2053,24 +2123,18 @@ int32_t CursorInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCod
}
void CursorInputMapper::fadePointer() {
- { // acquire lock
- AutoMutex _l(mLock);
- if (mPointerController != NULL) {
- mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
- }
- } // release lock
+ if (mPointerController != NULL) {
+ mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+ }
}
// --- TouchInputMapper ---
TouchInputMapper::TouchInputMapper(InputDevice* device) :
- InputMapper(device) {
- mLocked.surfaceOrientation = -1;
- mLocked.surfaceWidth = -1;
- mLocked.surfaceHeight = -1;
-
- initializeLocked();
+ InputMapper(device),
+ mSurfaceOrientation(-1), mSurfaceWidth(-1), mSurfaceHeight(-1) {
+ initialize();
}
TouchInputMapper::~TouchInputMapper() {
@@ -2083,126 +2147,148 @@ uint32_t TouchInputMapper::getSources() {
void TouchInputMapper::populateDeviceInfo(InputDeviceInfo* info) {
InputMapper::populateDeviceInfo(info);
- { // acquire lock
- AutoMutex _l(mLock);
-
- // Ensure surface information is up to date so that orientation changes are
- // noticed immediately.
- if (!configureSurfaceLocked()) {
- return;
- }
+ // Ensure surface information is up to date so that orientation changes are
+ // noticed immediately.
+ if (!configureSurface()) {
+ return;
+ }
- info->addMotionRange(mLocked.orientedRanges.x);
- info->addMotionRange(mLocked.orientedRanges.y);
+ info->addMotionRange(mOrientedRanges.x);
+ info->addMotionRange(mOrientedRanges.y);
- if (mLocked.orientedRanges.havePressure) {
- info->addMotionRange(mLocked.orientedRanges.pressure);
- }
+ if (mOrientedRanges.havePressure) {
+ info->addMotionRange(mOrientedRanges.pressure);
+ }
- if (mLocked.orientedRanges.haveSize) {
- info->addMotionRange(mLocked.orientedRanges.size);
- }
+ if (mOrientedRanges.haveSize) {
+ info->addMotionRange(mOrientedRanges.size);
+ }
- if (mLocked.orientedRanges.haveTouchSize) {
- info->addMotionRange(mLocked.orientedRanges.touchMajor);
- info->addMotionRange(mLocked.orientedRanges.touchMinor);
- }
+ if (mOrientedRanges.haveTouchSize) {
+ info->addMotionRange(mOrientedRanges.touchMajor);
+ info->addMotionRange(mOrientedRanges.touchMinor);
+ }
- if (mLocked.orientedRanges.haveToolSize) {
- info->addMotionRange(mLocked.orientedRanges.toolMajor);
- info->addMotionRange(mLocked.orientedRanges.toolMinor);
- }
+ if (mOrientedRanges.haveToolSize) {
+ info->addMotionRange(mOrientedRanges.toolMajor);
+ info->addMotionRange(mOrientedRanges.toolMinor);
+ }
- if (mLocked.orientedRanges.haveOrientation) {
- info->addMotionRange(mLocked.orientedRanges.orientation);
- }
+ if (mOrientedRanges.haveOrientation) {
+ info->addMotionRange(mOrientedRanges.orientation);
+ }
- if (mLocked.orientedRanges.haveDistance) {
- info->addMotionRange(mLocked.orientedRanges.distance);
- }
+ if (mOrientedRanges.haveDistance) {
+ info->addMotionRange(mOrientedRanges.distance);
+ }
- if (mPointerController != NULL) {
- float minX, minY, maxX, maxY;
- if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
- info->addMotionRange(AMOTION_EVENT_AXIS_X, mPointerSource,
- minX, maxX, 0.0f, 0.0f);
- info->addMotionRange(AMOTION_EVENT_AXIS_Y, mPointerSource,
- minY, maxY, 0.0f, 0.0f);
- }
- info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mPointerSource,
- 0.0f, 1.0f, 0.0f, 0.0f);
+ if (mPointerController != NULL) {
+ float minX, minY, maxX, maxY;
+ if (mPointerController->getBounds(&minX, &minY, &maxX, &maxY)) {
+ info->addMotionRange(AMOTION_EVENT_AXIS_X, mPointerSource,
+ minX, maxX, 0.0f, 0.0f);
+ info->addMotionRange(AMOTION_EVENT_AXIS_Y, mPointerSource,
+ minY, maxY, 0.0f, 0.0f);
}
- } // release lock
+ info->addMotionRange(AMOTION_EVENT_AXIS_PRESSURE, mPointerSource,
+ 0.0f, 1.0f, 0.0f, 0.0f);
+ }
}
void TouchInputMapper::dump(String8& dump) {
- { // acquire lock
- AutoMutex _l(mLock);
- dump.append(INDENT2 "Touch Input Mapper:\n");
- dumpParameters(dump);
- dumpVirtualKeysLocked(dump);
- dumpRawAxes(dump);
- dumpCalibration(dump);
- dumpSurfaceLocked(dump);
-
- dump.appendFormat(INDENT3 "Translation and Scaling Factors:\n");
- dump.appendFormat(INDENT4 "XScale: %0.3f\n", mLocked.xScale);
- dump.appendFormat(INDENT4 "YScale: %0.3f\n", mLocked.yScale);
- dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mLocked.xPrecision);
- dump.appendFormat(INDENT4 "YPrecision: %0.3f\n", mLocked.yPrecision);
- dump.appendFormat(INDENT4 "GeometricScale: %0.3f\n", mLocked.geometricScale);
- dump.appendFormat(INDENT4 "ToolSizeLinearScale: %0.3f\n", mLocked.toolSizeLinearScale);
- dump.appendFormat(INDENT4 "ToolSizeLinearBias: %0.3f\n", mLocked.toolSizeLinearBias);
- dump.appendFormat(INDENT4 "ToolSizeAreaScale: %0.3f\n", mLocked.toolSizeAreaScale);
- dump.appendFormat(INDENT4 "ToolSizeAreaBias: %0.3f\n", mLocked.toolSizeAreaBias);
- dump.appendFormat(INDENT4 "PressureScale: %0.3f\n", mLocked.pressureScale);
- dump.appendFormat(INDENT4 "SizeScale: %0.3f\n", mLocked.sizeScale);
- dump.appendFormat(INDENT4 "OrientationScale: %0.3f\n", mLocked.orientationScale);
- dump.appendFormat(INDENT4 "DistanceScale: %0.3f\n", mLocked.distanceScale);
-
- dump.appendFormat(INDENT3 "Last Touch:\n");
- dump.appendFormat(INDENT4 "Button State: 0x%08x\n", mLastTouch.buttonState);
- dump.appendFormat(INDENT4 "Pointer Count: %d\n", mLastTouch.pointerCount);
- for (uint32_t i = 0; i < mLastTouch.pointerCount; i++) {
- const PointerData& pointer = mLastTouch.pointers[i];
- dump.appendFormat(INDENT5 "[%d]: id=%d, x=%d, y=%d, pressure=%d, "
- "touchMajor=%d, touchMinor=%d, toolMajor=%d, toolMinor=%d, "
- "orientation=%d, distance=%d, toolType=%d, isHovering=%s\n", i,
- pointer.id, pointer.x, pointer.y, pointer.pressure,
- pointer.touchMajor, pointer.touchMinor, pointer.toolMajor, pointer.toolMinor,
- pointer.orientation, pointer.distance,
- pointer.toolType, toString(pointer.isHovering));
- }
-
- if (mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) {
- dump.appendFormat(INDENT3 "Pointer Gesture Detector:\n");
- dump.appendFormat(INDENT4 "XMovementScale: %0.3f\n",
- mLocked.pointerGestureXMovementScale);
- dump.appendFormat(INDENT4 "YMovementScale: %0.3f\n",
- mLocked.pointerGestureYMovementScale);
- dump.appendFormat(INDENT4 "XZoomScale: %0.3f\n",
- mLocked.pointerGestureXZoomScale);
- dump.appendFormat(INDENT4 "YZoomScale: %0.3f\n",
- mLocked.pointerGestureYZoomScale);
- dump.appendFormat(INDENT4 "MaxSwipeWidth: %f\n",
- mLocked.pointerGestureMaxSwipeWidth);
- }
- } // release lock
-}
-
-void TouchInputMapper::initializeLocked() {
- mCurrentTouch.clear();
- mLastTouch.clear();
+ dump.append(INDENT2 "Touch Input Mapper:\n");
+ dumpParameters(dump);
+ dumpVirtualKeys(dump);
+ dumpRawPointerAxes(dump);
+ dumpCalibration(dump);
+ dumpSurface(dump);
+
+ dump.appendFormat(INDENT3 "Translation and Scaling Factors:\n");
+ dump.appendFormat(INDENT4 "XScale: %0.3f\n", mXScale);
+ dump.appendFormat(INDENT4 "YScale: %0.3f\n", mYScale);
+ dump.appendFormat(INDENT4 "XPrecision: %0.3f\n", mXPrecision);
+ dump.appendFormat(INDENT4 "YPrecision: %0.3f\n", mYPrecision);
+ dump.appendFormat(INDENT4 "GeometricScale: %0.3f\n", mGeometricScale);
+ dump.appendFormat(INDENT4 "ToolSizeLinearScale: %0.3f\n", mToolSizeLinearScale);
+ dump.appendFormat(INDENT4 "ToolSizeLinearBias: %0.3f\n", mToolSizeLinearBias);
+ dump.appendFormat(INDENT4 "ToolSizeAreaScale: %0.3f\n", mToolSizeAreaScale);
+ dump.appendFormat(INDENT4 "ToolSizeAreaBias: %0.3f\n", mToolSizeAreaBias);
+ dump.appendFormat(INDENT4 "PressureScale: %0.3f\n", mPressureScale);
+ dump.appendFormat(INDENT4 "SizeScale: %0.3f\n", mSizeScale);
+ dump.appendFormat(INDENT4 "OrientationScale: %0.3f\n", mOrientationScale);
+ dump.appendFormat(INDENT4 "DistanceScale: %0.3f\n", mDistanceScale);
+
+ dump.appendFormat(INDENT3 "Last Button State: 0x%08x\n", mLastButtonState);
+
+ dump.appendFormat(INDENT3 "Last Raw Touch: pointerCount=%d\n",
+ mLastRawPointerData.pointerCount);
+ for (uint32_t i = 0; i < mLastRawPointerData.pointerCount; i++) {
+ const RawPointerData::Pointer& pointer = mLastRawPointerData.pointers[i];
+ dump.appendFormat(INDENT4 "[%d]: id=%d, x=%d, y=%d, pressure=%d, "
+ "touchMajor=%d, touchMinor=%d, toolMajor=%d, toolMinor=%d, "
+ "orientation=%d, distance=%d, toolType=%d, isHovering=%s\n", i,
+ pointer.id, pointer.x, pointer.y, pointer.pressure,
+ pointer.touchMajor, pointer.touchMinor,
+ pointer.toolMajor, pointer.toolMinor,
+ pointer.orientation, pointer.distance,
+ pointer.toolType, toString(pointer.isHovering));
+ }
+
+ dump.appendFormat(INDENT3 "Last Cooked Touch: pointerCount=%d\n",
+ mLastCookedPointerData.pointerCount);
+ for (uint32_t i = 0; i < mLastCookedPointerData.pointerCount; i++) {
+ const PointerProperties& pointerProperties = mLastCookedPointerData.pointerProperties[i];
+ const PointerCoords& pointerCoords = mLastCookedPointerData.pointerCoords[i];
+ dump.appendFormat(INDENT4 "[%d]: id=%d, x=%0.3f, y=%0.3f, pressure=%0.3f, "
+ "touchMajor=%0.3f, touchMinor=%0.3f, toolMajor=%0.3f, toolMinor=%0.3f, "
+ "orientation=%0.3f, distance=%0.3f, toolType=%d, isHovering=%s\n", i,
+ pointerProperties.id,
+ pointerCoords.getX(),
+ pointerCoords.getY(),
+ pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE),
+ pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MAJOR),
+ pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOUCH_MINOR),
+ pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR),
+ pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR),
+ pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_ORIENTATION),
+ pointerCoords.getAxisValue(AMOTION_EVENT_AXIS_DISTANCE),
+ pointerProperties.toolType,
+ toString(mLastCookedPointerData.isHovering(i)));
+ }
+
+ if (mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) {
+ dump.appendFormat(INDENT3 "Pointer Gesture Detector:\n");
+ dump.appendFormat(INDENT4 "XMovementScale: %0.3f\n",
+ mPointerGestureXMovementScale);
+ dump.appendFormat(INDENT4 "YMovementScale: %0.3f\n",
+ mPointerGestureYMovementScale);
+ dump.appendFormat(INDENT4 "XZoomScale: %0.3f\n",
+ mPointerGestureXZoomScale);
+ dump.appendFormat(INDENT4 "YZoomScale: %0.3f\n",
+ mPointerGestureYZoomScale);
+ dump.appendFormat(INDENT4 "MaxSwipeWidth: %f\n",
+ mPointerGestureMaxSwipeWidth);
+ }
+}
+
+void TouchInputMapper::initialize() {
+ mCurrentRawPointerData.clear();
+ mLastRawPointerData.clear();
+ mCurrentCookedPointerData.clear();
+ mLastCookedPointerData.clear();
+ mCurrentButtonState = 0;
+ mLastButtonState = 0;
+ mSentHoverEnter = false;
mDownTime = 0;
- mLocked.currentVirtualKey.down = false;
+ mCurrentVirtualKey.down = false;
- mLocked.orientedRanges.havePressure = false;
- mLocked.orientedRanges.haveSize = false;
- mLocked.orientedRanges.haveTouchSize = false;
- mLocked.orientedRanges.haveToolSize = false;
- mLocked.orientedRanges.haveOrientation = false;
- mLocked.orientedRanges.haveDistance = false;
+ mOrientedRanges.havePressure = false;
+ mOrientedRanges.haveSize = false;
+ mOrientedRanges.haveTouchSize = false;
+ mOrientedRanges.haveToolSize = false;
+ mOrientedRanges.haveOrientation = false;
+ mOrientedRanges.haveDistance = false;
mPointerGesture.reset();
}
@@ -2235,18 +2321,14 @@ void TouchInputMapper::configure(const InputReaderConfiguration* config, uint32_
}
// Configure absolute axis information.
- configureRawAxes();
+ configureRawPointerAxes();
// Prepare input device calibration.
parseCalibration();
resolveCalibration();
- { // acquire lock
- AutoMutex _l(mLock);
-
- // Configure surface dimensions and orientation.
- configureSurfaceLocked();
- } // release lock
+ // Configure surface dimensions and orientation.
+ configureSurface();
}
if (!changes || (changes & InputReaderConfiguration::CHANGE_POINTER_SPEED)) {
@@ -2359,38 +2441,28 @@ void TouchInputMapper::dumpParameters(String8& dump) {
toString(mParameters.orientationAware));
}
-void TouchInputMapper::configureRawAxes() {
- mRawAxes.x.clear();
- mRawAxes.y.clear();
- mRawAxes.pressure.clear();
- mRawAxes.touchMajor.clear();
- mRawAxes.touchMinor.clear();
- mRawAxes.toolMajor.clear();
- mRawAxes.toolMinor.clear();
- mRawAxes.orientation.clear();
- mRawAxes.distance.clear();
- mRawAxes.trackingId.clear();
- mRawAxes.slot.clear();
-}
-
-void TouchInputMapper::dumpRawAxes(String8& dump) {
- dump.append(INDENT3 "Raw Axes:\n");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.x, "X");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.y, "Y");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.pressure, "Pressure");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.touchMajor, "TouchMajor");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.touchMinor, "TouchMinor");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.toolMajor, "ToolMajor");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.toolMinor, "ToolMinor");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.orientation, "Orientation");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.distance, "Distance");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.trackingId, "TrackingId");
- dumpRawAbsoluteAxisInfo(dump, mRawAxes.slot, "Slot");
-}
-
-bool TouchInputMapper::configureSurfaceLocked() {
+void TouchInputMapper::configureRawPointerAxes() {
+ mRawPointerAxes.clear();
+}
+
+void TouchInputMapper::dumpRawPointerAxes(String8& dump) {
+ dump.append(INDENT3 "Raw Touch Axes:\n");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.x, "X");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.y, "Y");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.pressure, "Pressure");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.touchMajor, "TouchMajor");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.touchMinor, "TouchMinor");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.toolMajor, "ToolMajor");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.toolMinor, "ToolMinor");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.orientation, "Orientation");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.distance, "Distance");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.trackingId, "TrackingId");
+ dumpRawAbsoluteAxisInfo(dump, mRawPointerAxes.slot, "Slot");
+}
+
+bool TouchInputMapper::configureSurface() {
// Ensure we have valid X and Y axes.
- if (!mRawAxes.x.valid || !mRawAxes.y.valid) {
+ if (!mRawPointerAxes.x.valid || !mRawPointerAxes.y.valid) {
LOGW(INDENT "Touch device '%s' did not report support for X or Y axis! "
"The device will be inoperable.", getDeviceName().string());
return false;
@@ -2398,27 +2470,27 @@ bool TouchInputMapper::configureSurfaceLocked() {
// Update orientation and dimensions if needed.
int32_t orientation = DISPLAY_ORIENTATION_0;
- int32_t width = mRawAxes.x.maxValue - mRawAxes.x.minValue + 1;
- int32_t height = mRawAxes.y.maxValue - mRawAxes.y.minValue + 1;
+ int32_t width = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
+ int32_t height = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
if (mParameters.associatedDisplayId >= 0) {
// Note: getDisplayInfo is non-reentrant so we can continue holding the lock.
if (! getPolicy()->getDisplayInfo(mParameters.associatedDisplayId,
mParameters.associatedDisplayIsExternal,
- &mLocked.associatedDisplayWidth, &mLocked.associatedDisplayHeight,
- &mLocked.associatedDisplayOrientation)) {
+ &mAssociatedDisplayWidth, &mAssociatedDisplayHeight,
+ &mAssociatedDisplayOrientation)) {
return false;
}
// A touch screen inherits the dimensions of the display.
if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN) {
- width = mLocked.associatedDisplayWidth;
- height = mLocked.associatedDisplayHeight;
+ width = mAssociatedDisplayWidth;
+ height = mAssociatedDisplayHeight;
}
// The device inherits the orientation of the display if it is orientation aware.
if (mParameters.orientationAware) {
- orientation = mLocked.associatedDisplayOrientation;
+ orientation = mAssociatedDisplayOrientation;
}
}
@@ -2427,118 +2499,120 @@ bool TouchInputMapper::configureSurfaceLocked() {
mPointerController = getPolicy()->obtainPointerController(getDeviceId());
}
- bool orientationChanged = mLocked.surfaceOrientation != orientation;
+ bool orientationChanged = mSurfaceOrientation != orientation;
if (orientationChanged) {
- mLocked.surfaceOrientation = orientation;
+ mSurfaceOrientation = orientation;
}
- bool sizeChanged = mLocked.surfaceWidth != width || mLocked.surfaceHeight != height;
+ bool sizeChanged = mSurfaceWidth != width || mSurfaceHeight != height;
if (sizeChanged) {
LOGI("Device reconfigured: id=%d, name='%s', surface size is now %dx%d",
getDeviceId(), getDeviceName().string(), width, height);
- mLocked.surfaceWidth = width;
- mLocked.surfaceHeight = height;
+ mSurfaceWidth = width;
+ mSurfaceHeight = height;
// Configure X and Y factors.
- mLocked.xScale = float(width) / (mRawAxes.x.maxValue - mRawAxes.x.minValue + 1);
- mLocked.yScale = float(height) / (mRawAxes.y.maxValue - mRawAxes.y.minValue + 1);
- mLocked.xPrecision = 1.0f / mLocked.xScale;
- mLocked.yPrecision = 1.0f / mLocked.yScale;
+ mXScale = float(width) / (mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1);
+ mYScale = float(height) / (mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1);
+ mXPrecision = 1.0f / mXScale;
+ mYPrecision = 1.0f / mYScale;
- mLocked.orientedRanges.x.axis = AMOTION_EVENT_AXIS_X;
- mLocked.orientedRanges.x.source = mTouchSource;
- mLocked.orientedRanges.y.axis = AMOTION_EVENT_AXIS_Y;
- mLocked.orientedRanges.y.source = mTouchSource;
+ mOrientedRanges.x.axis = AMOTION_EVENT_AXIS_X;
+ mOrientedRanges.x.source = mTouchSource;
+ mOrientedRanges.y.axis = AMOTION_EVENT_AXIS_Y;
+ mOrientedRanges.y.source = mTouchSource;
- configureVirtualKeysLocked();
+ configureVirtualKeys();
// Scale factor for terms that are not oriented in a particular axis.
// If the pixels are square then xScale == yScale otherwise we fake it
// by choosing an average.
- mLocked.geometricScale = avg(mLocked.xScale, mLocked.yScale);
+ mGeometricScale = avg(mXScale, mYScale);
// Size of diagonal axis.
float diagonalSize = hypotf(width, height);
// TouchMajor and TouchMinor factors.
if (mCalibration.touchSizeCalibration != Calibration::TOUCH_SIZE_CALIBRATION_NONE) {
- mLocked.orientedRanges.haveTouchSize = true;
+ mOrientedRanges.haveTouchSize = true;
- mLocked.orientedRanges.touchMajor.axis = AMOTION_EVENT_AXIS_TOUCH_MAJOR;
- mLocked.orientedRanges.touchMajor.source = mTouchSource;
- mLocked.orientedRanges.touchMajor.min = 0;
- mLocked.orientedRanges.touchMajor.max = diagonalSize;
- mLocked.orientedRanges.touchMajor.flat = 0;
- mLocked.orientedRanges.touchMajor.fuzz = 0;
+ mOrientedRanges.touchMajor.axis = AMOTION_EVENT_AXIS_TOUCH_MAJOR;
+ mOrientedRanges.touchMajor.source = mTouchSource;
+ mOrientedRanges.touchMajor.min = 0;
+ mOrientedRanges.touchMajor.max = diagonalSize;
+ mOrientedRanges.touchMajor.flat = 0;
+ mOrientedRanges.touchMajor.fuzz = 0;
- mLocked.orientedRanges.touchMinor = mLocked.orientedRanges.touchMajor;
- mLocked.orientedRanges.touchMinor.axis = AMOTION_EVENT_AXIS_TOUCH_MINOR;
+ mOrientedRanges.touchMinor = mOrientedRanges.touchMajor;
+ mOrientedRanges.touchMinor.axis = AMOTION_EVENT_AXIS_TOUCH_MINOR;
}
// ToolMajor and ToolMinor factors.
- mLocked.toolSizeLinearScale = 0;
- mLocked.toolSizeLinearBias = 0;
- mLocked.toolSizeAreaScale = 0;
- mLocked.toolSizeAreaBias = 0;
+ mToolSizeLinearScale = 0;
+ mToolSizeLinearBias = 0;
+ mToolSizeAreaScale = 0;
+ mToolSizeAreaBias = 0;
if (mCalibration.toolSizeCalibration != Calibration::TOOL_SIZE_CALIBRATION_NONE) {
if (mCalibration.toolSizeCalibration == Calibration::TOOL_SIZE_CALIBRATION_LINEAR) {
if (mCalibration.haveToolSizeLinearScale) {
- mLocked.toolSizeLinearScale = mCalibration.toolSizeLinearScale;
- } else if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
- mLocked.toolSizeLinearScale = float(min(width, height))
- / mRawAxes.toolMajor.maxValue;
+ mToolSizeLinearScale = mCalibration.toolSizeLinearScale;
+ } else if (mRawPointerAxes.toolMajor.valid
+ && mRawPointerAxes.toolMajor.maxValue != 0) {
+ mToolSizeLinearScale = float(min(width, height))
+ / mRawPointerAxes.toolMajor.maxValue;
}
if (mCalibration.haveToolSizeLinearBias) {
- mLocked.toolSizeLinearBias = mCalibration.toolSizeLinearBias;
+ mToolSizeLinearBias = mCalibration.toolSizeLinearBias;
}
} else if (mCalibration.toolSizeCalibration ==
Calibration::TOOL_SIZE_CALIBRATION_AREA) {
if (mCalibration.haveToolSizeLinearScale) {
- mLocked.toolSizeLinearScale = mCalibration.toolSizeLinearScale;
+ mToolSizeLinearScale = mCalibration.toolSizeLinearScale;
} else {
- mLocked.toolSizeLinearScale = min(width, height);
+ mToolSizeLinearScale = min(width, height);
}
if (mCalibration.haveToolSizeLinearBias) {
- mLocked.toolSizeLinearBias = mCalibration.toolSizeLinearBias;
+ mToolSizeLinearBias = mCalibration.toolSizeLinearBias;
}
if (mCalibration.haveToolSizeAreaScale) {
- mLocked.toolSizeAreaScale = mCalibration.toolSizeAreaScale;
- } else if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
- mLocked.toolSizeAreaScale = 1.0f / mRawAxes.toolMajor.maxValue;
+ mToolSizeAreaScale = mCalibration.toolSizeAreaScale;
+ } else if (mRawPointerAxes.toolMajor.valid
+ && mRawPointerAxes.toolMajor.maxValue != 0) {
+ mToolSizeAreaScale = 1.0f / mRawPointerAxes.toolMajor.maxValue;
}
if (mCalibration.haveToolSizeAreaBias) {
- mLocked.toolSizeAreaBias = mCalibration.toolSizeAreaBias;
+ mToolSizeAreaBias = mCalibration.toolSizeAreaBias;
}
}
- mLocked.orientedRanges.haveToolSize = true;
+ mOrientedRanges.haveToolSize = true;
- mLocked.orientedRanges.toolMajor.axis = AMOTION_EVENT_AXIS_TOOL_MAJOR;
- mLocked.orientedRanges.toolMajor.source = mTouchSource;
- mLocked.orientedRanges.toolMajor.min = 0;
- mLocked.orientedRanges.toolMajor.max = diagonalSize;
- mLocked.orientedRanges.toolMajor.flat = 0;
- mLocked.orientedRanges.toolMajor.fuzz = 0;
+ mOrientedRanges.toolMajor.axis = AMOTION_EVENT_AXIS_TOOL_MAJOR;
+ mOrientedRanges.toolMajor.source = mTouchSource;
+ mOrientedRanges.toolMajor.min = 0;
+ mOrientedRanges.toolMajor.max = diagonalSize;
+ mOrientedRanges.toolMajor.flat = 0;
+ mOrientedRanges.toolMajor.fuzz = 0;
- mLocked.orientedRanges.toolMinor = mLocked.orientedRanges.toolMajor;
- mLocked.orientedRanges.toolMinor.axis = AMOTION_EVENT_AXIS_TOOL_MINOR;
+ mOrientedRanges.toolMinor = mOrientedRanges.toolMajor;
+ mOrientedRanges.toolMinor.axis = AMOTION_EVENT_AXIS_TOOL_MINOR;
}
// Pressure factors.
- mLocked.pressureScale = 0;
+ mPressureScale = 0;
if (mCalibration.pressureCalibration != Calibration::PRESSURE_CALIBRATION_NONE) {
RawAbsoluteAxisInfo rawPressureAxis;
switch (mCalibration.pressureSource) {
case Calibration::PRESSURE_SOURCE_PRESSURE:
- rawPressureAxis = mRawAxes.pressure;
+ rawPressureAxis = mRawPointerAxes.pressure;
break;
case Calibration::PRESSURE_SOURCE_TOUCH:
- rawPressureAxis = mRawAxes.touchMajor;
+ rawPressureAxis = mRawPointerAxes.touchMajor;
break;
default:
rawPressureAxis.clear();
@@ -2548,84 +2622,84 @@ bool TouchInputMapper::configureSurfaceLocked() {
|| mCalibration.pressureCalibration
== Calibration::PRESSURE_CALIBRATION_AMPLITUDE) {
if (mCalibration.havePressureScale) {
- mLocked.pressureScale = mCalibration.pressureScale;
+ mPressureScale = mCalibration.pressureScale;
} else if (rawPressureAxis.valid && rawPressureAxis.maxValue != 0) {
- mLocked.pressureScale = 1.0f / rawPressureAxis.maxValue;
+ mPressureScale = 1.0f / rawPressureAxis.maxValue;
}
}
- mLocked.orientedRanges.havePressure = true;
+ mOrientedRanges.havePressure = true;
- mLocked.orientedRanges.pressure.axis = AMOTION_EVENT_AXIS_PRESSURE;
- mLocked.orientedRanges.pressure.source = mTouchSource;
- mLocked.orientedRanges.pressure.min = 0;
- mLocked.orientedRanges.pressure.max = 1.0;
- mLocked.orientedRanges.pressure.flat = 0;
- mLocked.orientedRanges.pressure.fuzz = 0;
+ mOrientedRanges.pressure.axis = AMOTION_EVENT_AXIS_PRESSURE;
+ mOrientedRanges.pressure.source = mTouchSource;
+ mOrientedRanges.pressure.min = 0;
+ mOrientedRanges.pressure.max = 1.0;
+ mOrientedRanges.pressure.flat = 0;
+ mOrientedRanges.pressure.fuzz = 0;
}
// Size factors.
- mLocked.sizeScale = 0;
+ mSizeScale = 0;
if (mCalibration.sizeCalibration != Calibration::SIZE_CALIBRATION_NONE) {
if (mCalibration.sizeCalibration == Calibration::SIZE_CALIBRATION_NORMALIZED) {
- if (mRawAxes.toolMajor.valid && mRawAxes.toolMajor.maxValue != 0) {
- mLocked.sizeScale = 1.0f / mRawAxes.toolMajor.maxValue;
+ if (mRawPointerAxes.toolMajor.valid && mRawPointerAxes.toolMajor.maxValue != 0) {
+ mSizeScale = 1.0f / mRawPointerAxes.toolMajor.maxValue;
}
}
- mLocked.orientedRanges.haveSize = true;
+ mOrientedRanges.haveSize = true;
- mLocked.orientedRanges.size.axis = AMOTION_EVENT_AXIS_SIZE;
- mLocked.orientedRanges.size.source = mTouchSource;
- mLocked.orientedRanges.size.min = 0;
- mLocked.orientedRanges.size.max = 1.0;
- mLocked.orientedRanges.size.flat = 0;
- mLocked.orientedRanges.size.fuzz = 0;
+ mOrientedRanges.size.axis = AMOTION_EVENT_AXIS_SIZE;
+ mOrientedRanges.size.source = mTouchSource;
+ mOrientedRanges.size.min = 0;
+ mOrientedRanges.size.max = 1.0;
+ mOrientedRanges.size.flat = 0;
+ mOrientedRanges.size.fuzz = 0;
}
// Orientation
- mLocked.orientationScale = 0;
+ mOrientationScale = 0;
if (mCalibration.orientationCalibration != Calibration::ORIENTATION_CALIBRATION_NONE) {
if (mCalibration.orientationCalibration
== Calibration::ORIENTATION_CALIBRATION_INTERPOLATED) {
- if (mRawAxes.orientation.valid && mRawAxes.orientation.maxValue != 0) {
- mLocked.orientationScale = float(M_PI_2) / mRawAxes.orientation.maxValue;
+ if (mRawPointerAxes.orientation.valid && mRawPointerAxes.orientation.maxValue != 0) {
+ mOrientationScale = float(M_PI_2) / mRawPointerAxes.orientation.maxValue;
}
}
- mLocked.orientedRanges.haveOrientation = true;
+ mOrientedRanges.haveOrientation = true;
- mLocked.orientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION;
- mLocked.orientedRanges.orientation.source = mTouchSource;
- mLocked.orientedRanges.orientation.min = - M_PI_2;
- mLocked.orientedRanges.orientation.max = M_PI_2;
- mLocked.orientedRanges.orientation.flat = 0;
- mLocked.orientedRanges.orientation.fuzz = 0;
+ mOrientedRanges.orientation.axis = AMOTION_EVENT_AXIS_ORIENTATION;
+ mOrientedRanges.orientation.source = mTouchSource;
+ mOrientedRanges.orientation.min = - M_PI_2;
+ mOrientedRanges.orientation.max = M_PI_2;
+ mOrientedRanges.orientation.flat = 0;
+ mOrientedRanges.orientation.fuzz = 0;
}
// Distance
- mLocked.distanceScale = 0;
+ mDistanceScale = 0;
if (mCalibration.distanceCalibration != Calibration::DISTANCE_CALIBRATION_NONE) {
if (mCalibration.distanceCalibration
== Calibration::DISTANCE_CALIBRATION_SCALED) {
if (mCalibration.haveDistanceScale) {
- mLocked.distanceScale = mCalibration.distanceScale;
+ mDistanceScale = mCalibration.distanceScale;
} else {
- mLocked.distanceScale = 1.0f;
+ mDistanceScale = 1.0f;
}
}
- mLocked.orientedRanges.haveDistance = true;
+ mOrientedRanges.haveDistance = true;
- mLocked.orientedRanges.distance.axis = AMOTION_EVENT_AXIS_DISTANCE;
- mLocked.orientedRanges.distance.source = mTouchSource;
- mLocked.orientedRanges.distance.min =
- mRawAxes.distance.minValue * mLocked.distanceScale;
- mLocked.orientedRanges.distance.max =
- mRawAxes.distance.minValue * mLocked.distanceScale;
- mLocked.orientedRanges.distance.flat = 0;
- mLocked.orientedRanges.distance.fuzz =
- mRawAxes.distance.fuzz * mLocked.distanceScale;
+ mOrientedRanges.distance.axis = AMOTION_EVENT_AXIS_DISTANCE;
+ mOrientedRanges.distance.source = mTouchSource;
+ mOrientedRanges.distance.min =
+ mRawPointerAxes.distance.minValue * mDistanceScale;
+ mOrientedRanges.distance.max =
+ mRawPointerAxes.distance.minValue * mDistanceScale;
+ mOrientedRanges.distance.flat = 0;
+ mOrientedRanges.distance.fuzz =
+ mRawPointerAxes.distance.fuzz * mDistanceScale;
}
}
@@ -2633,78 +2707,77 @@ bool TouchInputMapper::configureSurfaceLocked() {
// Compute oriented surface dimensions, precision, scales and ranges.
// Note that the maximum value reported is an inclusive maximum value so it is one
// unit less than the total width or height of surface.
- switch (mLocked.surfaceOrientation) {
+ switch (mSurfaceOrientation) {
case DISPLAY_ORIENTATION_90:
case DISPLAY_ORIENTATION_270:
- mLocked.orientedSurfaceWidth = mLocked.surfaceHeight;
- mLocked.orientedSurfaceHeight = mLocked.surfaceWidth;
-
- mLocked.orientedXPrecision = mLocked.yPrecision;
- mLocked.orientedYPrecision = mLocked.xPrecision;
-
- mLocked.orientedRanges.x.min = 0;
- mLocked.orientedRanges.x.max = (mRawAxes.y.maxValue - mRawAxes.y.minValue)
- * mLocked.yScale;
- mLocked.orientedRanges.x.flat = 0;
- mLocked.orientedRanges.x.fuzz = mLocked.yScale;
-
- mLocked.orientedRanges.y.min = 0;
- mLocked.orientedRanges.y.max = (mRawAxes.x.maxValue - mRawAxes.x.minValue)
- * mLocked.xScale;
- mLocked.orientedRanges.y.flat = 0;
- mLocked.orientedRanges.y.fuzz = mLocked.xScale;
+ mOrientedSurfaceWidth = mSurfaceHeight;
+ mOrientedSurfaceHeight = mSurfaceWidth;
+
+ mOrientedXPrecision = mYPrecision;
+ mOrientedYPrecision = mXPrecision;
+
+ mOrientedRanges.x.min = 0;
+ mOrientedRanges.x.max = (mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue)
+ * mYScale;
+ mOrientedRanges.x.flat = 0;
+ mOrientedRanges.x.fuzz = mYScale;
+
+ mOrientedRanges.y.min = 0;
+ mOrientedRanges.y.max = (mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue)
+ * mXScale;
+ mOrientedRanges.y.flat = 0;
+ mOrientedRanges.y.fuzz = mXScale;
break;
default:
- mLocked.orientedSurfaceWidth = mLocked.surfaceWidth;
- mLocked.orientedSurfaceHeight = mLocked.surfaceHeight;
-
- mLocked.orientedXPrecision = mLocked.xPrecision;
- mLocked.orientedYPrecision = mLocked.yPrecision;
-
- mLocked.orientedRanges.x.min = 0;
- mLocked.orientedRanges.x.max = (mRawAxes.x.maxValue - mRawAxes.x.minValue)
- * mLocked.xScale;
- mLocked.orientedRanges.x.flat = 0;
- mLocked.orientedRanges.x.fuzz = mLocked.xScale;
-
- mLocked.orientedRanges.y.min = 0;
- mLocked.orientedRanges.y.max = (mRawAxes.y.maxValue - mRawAxes.y.minValue)
- * mLocked.yScale;
- mLocked.orientedRanges.y.flat = 0;
- mLocked.orientedRanges.y.fuzz = mLocked.yScale;
+ mOrientedSurfaceWidth = mSurfaceWidth;
+ mOrientedSurfaceHeight = mSurfaceHeight;
+
+ mOrientedXPrecision = mXPrecision;
+ mOrientedYPrecision = mYPrecision;
+
+ mOrientedRanges.x.min = 0;
+ mOrientedRanges.x.max = (mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue)
+ * mXScale;
+ mOrientedRanges.x.flat = 0;
+ mOrientedRanges.x.fuzz = mXScale;
+
+ mOrientedRanges.y.min = 0;
+ mOrientedRanges.y.max = (mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue)
+ * mYScale;
+ mOrientedRanges.y.flat = 0;
+ mOrientedRanges.y.fuzz = mYScale;
break;
}
// Compute pointer gesture detection parameters.
- // TODO: These factors should not be hardcoded.
if (mParameters.deviceType == Parameters::DEVICE_TYPE_POINTER) {
- int32_t rawWidth = mRawAxes.x.maxValue - mRawAxes.x.minValue + 1;
- int32_t rawHeight = mRawAxes.y.maxValue - mRawAxes.y.minValue + 1;
+ int32_t rawWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
+ int32_t rawHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
float rawDiagonal = hypotf(rawWidth, rawHeight);
- float displayDiagonal = hypotf(mLocked.associatedDisplayWidth,
- mLocked.associatedDisplayHeight);
+ float displayDiagonal = hypotf(mAssociatedDisplayWidth,
+ mAssociatedDisplayHeight);
// Scale movements such that one whole swipe of the touch pad covers a
// given area relative to the diagonal size of the display when no acceleration
// 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
+ mPointerGestureXMovementScale = mConfig.pointerGestureMovementSpeedRatio
* displayDiagonal / rawDiagonal;
- mLocked.pointerGestureYMovementScale = mLocked.pointerGestureXMovementScale;
+ mPointerGestureYMovementScale = mPointerGestureXMovementScale;
// 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
+ mPointerGestureXZoomScale = mConfig.pointerGestureZoomSpeedRatio
* displayDiagonal / rawDiagonal;
- mLocked.pointerGestureYZoomScale = mLocked.pointerGestureXZoomScale;
+ mPointerGestureYZoomScale = mPointerGestureXZoomScale;
// Max width between pointers to detect a swipe gesture is more than some fraction
// of the diagonal axis of the touch pad. Touches that are wider than this are
// translated into freeform gestures.
- mLocked.pointerGestureMaxSwipeWidth =
+ mPointerGestureMaxSwipeWidth =
mConfig.pointerGestureSwipeMaxWidthRatio * rawDiagonal;
// Reset the current pointer gesture.
@@ -2720,35 +2793,35 @@ bool TouchInputMapper::configureSurfaceLocked() {
return true;
}
-void TouchInputMapper::dumpSurfaceLocked(String8& dump) {
- dump.appendFormat(INDENT3 "SurfaceWidth: %dpx\n", mLocked.surfaceWidth);
- dump.appendFormat(INDENT3 "SurfaceHeight: %dpx\n", mLocked.surfaceHeight);
- dump.appendFormat(INDENT3 "SurfaceOrientation: %d\n", mLocked.surfaceOrientation);
+void TouchInputMapper::dumpSurface(String8& dump) {
+ dump.appendFormat(INDENT3 "SurfaceWidth: %dpx\n", mSurfaceWidth);
+ dump.appendFormat(INDENT3 "SurfaceHeight: %dpx\n", mSurfaceHeight);
+ dump.appendFormat(INDENT3 "SurfaceOrientation: %d\n", mSurfaceOrientation);
}
-void TouchInputMapper::configureVirtualKeysLocked() {
+void TouchInputMapper::configureVirtualKeys() {
Vector<VirtualKeyDefinition> virtualKeyDefinitions;
getEventHub()->getVirtualKeyDefinitions(getDeviceId(), virtualKeyDefinitions);
- mLocked.virtualKeys.clear();
+ mVirtualKeys.clear();
if (virtualKeyDefinitions.size() == 0) {
return;
}
- mLocked.virtualKeys.setCapacity(virtualKeyDefinitions.size());
+ mVirtualKeys.setCapacity(virtualKeyDefinitions.size());
- int32_t touchScreenLeft = mRawAxes.x.minValue;
- int32_t touchScreenTop = mRawAxes.y.minValue;
- int32_t touchScreenWidth = mRawAxes.x.maxValue - mRawAxes.x.minValue + 1;
- int32_t touchScreenHeight = mRawAxes.y.maxValue - mRawAxes.y.minValue + 1;
+ int32_t touchScreenLeft = mRawPointerAxes.x.minValue;
+ int32_t touchScreenTop = mRawPointerAxes.y.minValue;
+ int32_t touchScreenWidth = mRawPointerAxes.x.maxValue - mRawPointerAxes.x.minValue + 1;
+ int32_t touchScreenHeight = mRawPointerAxes.y.maxValue - mRawPointerAxes.y.minValue + 1;
for (size_t i = 0; i < virtualKeyDefinitions.size(); i++) {
const VirtualKeyDefinition& virtualKeyDefinition =
virtualKeyDefinitions[i];
- mLocked.virtualKeys.add();
- VirtualKey& virtualKey = mLocked.virtualKeys.editTop();
+ mVirtualKeys.add();
+ VirtualKey& virtualKey = mVirtualKeys.editTop();
virtualKey.scanCode = virtualKeyDefinition.scanCode;
int32_t keyCode;
@@ -2757,7 +2830,7 @@ void TouchInputMapper::configureVirtualKeysLocked() {
& keyCode, & flags)) {
LOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring",
virtualKey.scanCode);
- mLocked.virtualKeys.pop(); // drop the key
+ mVirtualKeys.pop(); // drop the key
continue;
}
@@ -2769,22 +2842,22 @@ void TouchInputMapper::configureVirtualKeysLocked() {
int32_t halfHeight = virtualKeyDefinition.height / 2;
virtualKey.hitLeft = (virtualKeyDefinition.centerX - halfWidth)
- * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft;
+ * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
virtualKey.hitRight= (virtualKeyDefinition.centerX + halfWidth)
- * touchScreenWidth / mLocked.surfaceWidth + touchScreenLeft;
+ * touchScreenWidth / mSurfaceWidth + touchScreenLeft;
virtualKey.hitTop = (virtualKeyDefinition.centerY - halfHeight)
- * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop;
+ * touchScreenHeight / mSurfaceHeight + touchScreenTop;
virtualKey.hitBottom = (virtualKeyDefinition.centerY + halfHeight)
- * touchScreenHeight / mLocked.surfaceHeight + touchScreenTop;
+ * touchScreenHeight / mSurfaceHeight + touchScreenTop;
}
}
-void TouchInputMapper::dumpVirtualKeysLocked(String8& dump) {
- if (!mLocked.virtualKeys.isEmpty()) {
+void TouchInputMapper::dumpVirtualKeys(String8& dump) {
+ if (!mVirtualKeys.isEmpty()) {
dump.append(INDENT3 "Virtual Keys:\n");
- for (size_t i = 0; i < mLocked.virtualKeys.size(); i++) {
- const VirtualKey& virtualKey = mLocked.virtualKeys.itemAt(i);
+ for (size_t i = 0; i < mVirtualKeys.size(); i++) {
+ const VirtualKey& virtualKey = mVirtualKeys.itemAt(i);
dump.appendFormat(INDENT4 "%d: scanCode=%d, keyCode=%d, "
"hitLeft=%d, hitRight=%d, hitTop=%d, hitBottom=%d\n",
i, virtualKey.scanCode, virtualKey.keyCode,
@@ -2927,22 +3000,22 @@ void TouchInputMapper::resolveCalibration() {
// Pressure
switch (mCalibration.pressureSource) {
case Calibration::PRESSURE_SOURCE_DEFAULT:
- if (mRawAxes.pressure.valid) {
+ if (mRawPointerAxes.pressure.valid) {
mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_PRESSURE;
- } else if (mRawAxes.touchMajor.valid) {
+ } else if (mRawPointerAxes.touchMajor.valid) {
mCalibration.pressureSource = Calibration::PRESSURE_SOURCE_TOUCH;
}
break;
case Calibration::PRESSURE_SOURCE_PRESSURE:
- if (! mRawAxes.pressure.valid) {
+ if (! mRawPointerAxes.pressure.valid) {
LOGW("Calibration property touch.pressure.source is 'pressure' but "
"the pressure axis is not available.");
}
break;
case Calibration::PRESSURE_SOURCE_TOUCH:
- if (! mRawAxes.touchMajor.valid) {
+ if (! mRawPointerAxes.touchMajor.valid) {
LOGW("Calibration property touch.pressure.source is 'touch' but "
"the touchMajor axis is not available.");
}
@@ -2968,7 +3041,7 @@ void TouchInputMapper::resolveCalibration() {
// Tool Size
switch (mCalibration.toolSizeCalibration) {
case Calibration::TOOL_SIZE_CALIBRATION_DEFAULT:
- if (mRawAxes.toolMajor.valid) {
+ if (mRawPointerAxes.toolMajor.valid) {
mCalibration.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_LINEAR;
} else {
mCalibration.toolSizeCalibration = Calibration::TOOL_SIZE_CALIBRATION_NONE;
@@ -2997,7 +3070,7 @@ void TouchInputMapper::resolveCalibration() {
// Size
switch (mCalibration.sizeCalibration) {
case Calibration::SIZE_CALIBRATION_DEFAULT:
- if (mRawAxes.toolMajor.valid) {
+ if (mRawPointerAxes.toolMajor.valid) {
mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NORMALIZED;
} else {
mCalibration.sizeCalibration = Calibration::SIZE_CALIBRATION_NONE;
@@ -3011,7 +3084,7 @@ void TouchInputMapper::resolveCalibration() {
// Orientation
switch (mCalibration.orientationCalibration) {
case Calibration::ORIENTATION_CALIBRATION_DEFAULT:
- if (mRawAxes.orientation.valid) {
+ if (mRawPointerAxes.orientation.valid) {
mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_INTERPOLATED;
} else {
mCalibration.orientationCalibration = Calibration::ORIENTATION_CALIBRATION_NONE;
@@ -3025,7 +3098,7 @@ void TouchInputMapper::resolveCalibration() {
// Distance
switch (mCalibration.distanceCalibration) {
case Calibration::DISTANCE_CALIBRATION_DEFAULT:
- if (mRawAxes.distance.valid) {
+ if (mRawPointerAxes.distance.valid) {
mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_SCALED;
} else {
mCalibration.distanceCalibration = Calibration::DISTANCE_CALIBRATION_NONE;
@@ -3177,24 +3250,20 @@ void TouchInputMapper::dumpCalibration(String8& dump) {
}
void TouchInputMapper::reset() {
- // Synthesize touch up event if touch is currently down.
+ // Synthesize touch up event.
// This will also take care of finishing virtual key processing if needed.
- if (mLastTouch.pointerCount != 0) {
- nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
- mCurrentTouch.clear();
- syncTouch(when, true);
- }
+ nsecs_t when = systemTime(SYSTEM_TIME_MONOTONIC);
+ mCurrentRawPointerData.clear();
+ mCurrentButtonState = 0;
+ syncTouch(when, true);
- { // acquire lock
- AutoMutex _l(mLock);
- initializeLocked();
+ initialize();
- if (mPointerController != NULL
- && mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
- mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
- mPointerController->clearSpots();
- }
- } // release lock
+ if (mPointerController != NULL
+ && mParameters.gestureMode == Parameters::GESTURE_MODE_SPOTS) {
+ mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+ mPointerController->clearSpots();
+ }
InputMapper::reset();
}
@@ -3202,25 +3271,37 @@ void TouchInputMapper::reset() {
void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
#if DEBUG_RAW_EVENTS
if (!havePointerIds) {
- LOGD("syncTouch: pointerCount=%d, no pointer ids", mCurrentTouch.pointerCount);
+ LOGD("syncTouch: pointerCount %d -> %d, no pointer ids",
+ mLastRawPointerData.pointerCount,
+ mCurrentRawPointerData.pointerCount);
} else {
- LOGD("syncTouch: pointerCount=%d, up=0x%08x, down=0x%08x, move=0x%08x, "
- "last=0x%08x, current=0x%08x", mCurrentTouch.pointerCount,
- mLastTouch.idBits.value & ~mCurrentTouch.idBits.value,
- mCurrentTouch.idBits.value & ~mLastTouch.idBits.value,
- mLastTouch.idBits.value & mCurrentTouch.idBits.value,
- mLastTouch.idBits.value, mCurrentTouch.idBits.value);
+ LOGD("syncTouch: pointerCount %d -> %d, touching ids 0x%08x -> 0x%08x, "
+ "hovering ids 0x%08x -> 0x%08x",
+ mLastRawPointerData.pointerCount,
+ mCurrentRawPointerData.pointerCount,
+ mLastRawPointerData.touchingIdBits.value,
+ mCurrentRawPointerData.touchingIdBits.value,
+ mLastRawPointerData.hoveringIdBits.value,
+ mCurrentRawPointerData.hoveringIdBits.value);
}
#endif
+ // Configure the surface now, if possible.
+ if (!configureSurface()) {
+ mLastRawPointerData.clear();
+ mLastCookedPointerData.clear();
+ mLastButtonState = 0;
+ return;
+ }
+
// Preprocess pointer data.
if (!havePointerIds) {
- calculatePointerIds();
+ assignPointerIds();
}
- // Handle initial down events.
+ // Handle policy on initial down or hover events.
uint32_t policyFlags = 0;
- if (mLastTouch.pointerCount == 0 && mCurrentTouch.pointerCount != 0) {
+ if (mLastRawPointerData.pointerCount == 0 && mCurrentRawPointerData.pointerCount != 0) {
if (mParameters.deviceType == Parameters::DEVICE_TYPE_TOUCH_SCREEN) {
// If this is a touch screen, hide the pointer on an initial down.
getContext()->fadePointer();
@@ -3235,40 +3316,31 @@ void TouchInputMapper::syncTouch(nsecs_t when, bool havePointerIds) {
}
}
- // Synthesize key down from buttons if needed.
+ // Synthesize key down from raw buttons if needed.
synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_DOWN, when, getDeviceId(), mTouchSource,
- policyFlags, mLastTouch.buttonState, mCurrentTouch.buttonState);
-
- // Send motion events.
- TouchResult touchResult;
- if (mLastTouch.pointerCount == 0 && mCurrentTouch.pointerCount == 0
- && mLastTouch.buttonState == mCurrentTouch.buttonState) {
- // Drop spurious syncs.
- touchResult = DROP_STROKE;
- } else {
- // Process touches and virtual keys.
- touchResult = consumeOffScreenTouches(when, policyFlags);
- if (touchResult == DISPATCH_TOUCH) {
- suppressSwipeOntoVirtualKeys(when);
- if (mPointerController != NULL && mConfig.pointerGesturesEnabled) {
- dispatchPointerGestures(when, policyFlags, false /*isTimeout*/);
- }
- dispatchTouches(when, policyFlags);
- }
+ policyFlags, mLastButtonState, mCurrentButtonState);
+
+ if (consumeRawTouches(when, policyFlags)) {
+ mCurrentRawPointerData.clear();
}
- // Synthesize key up from buttons if needed.
+ if (mPointerController != NULL && mConfig.pointerGesturesEnabled) {
+ dispatchPointerGestures(when, policyFlags, false /*isTimeout*/);
+ }
+
+ cookPointerData();
+ dispatchHoverExit(when, policyFlags);
+ dispatchTouches(when, policyFlags);
+ dispatchHoverEnterAndMove(when, policyFlags);
+
+ // Synthesize key up from raw buttons if needed.
synthesizeButtonKeys(getContext(), AKEY_EVENT_ACTION_UP, when, getDeviceId(), mTouchSource,
- policyFlags, mLastTouch.buttonState, mCurrentTouch.buttonState);
+ policyFlags, mLastButtonState, mCurrentButtonState);
// Copy current touch to last touch in preparation for the next cycle.
- // Keep the button state so we can track edge-triggered button state changes.
- if (touchResult == DROP_STROKE) {
- mLastTouch.clear();
- mLastTouch.buttonState = mCurrentTouch.buttonState;
- } else {
- mLastTouch.copyFrom(mCurrentTouch);
- }
+ mLastRawPointerData.copyFrom(mCurrentRawPointerData);
+ mLastCookedPointerData.copyFrom(mCurrentCookedPointerData);
+ mLastButtonState = mCurrentButtonState;
}
void TouchInputMapper::timeoutExpired(nsecs_t when) {
@@ -3277,125 +3349,88 @@ void TouchInputMapper::timeoutExpired(nsecs_t when) {
}
}
-TouchInputMapper::TouchResult TouchInputMapper::consumeOffScreenTouches(
- nsecs_t when, uint32_t policyFlags) {
- int32_t keyEventAction, keyEventFlags;
- int32_t keyCode, scanCode, downTime;
- TouchResult touchResult;
-
- { // acquire lock
- AutoMutex _l(mLock);
-
- // Update surface size and orientation, including virtual key positions.
- if (! configureSurfaceLocked()) {
- return DROP_STROKE;
- }
-
- // Check for virtual key press.
- if (mLocked.currentVirtualKey.down) {
- if (mCurrentTouch.pointerCount == 0) {
- // Pointer went up while virtual key was down.
- mLocked.currentVirtualKey.down = false;
+bool TouchInputMapper::consumeRawTouches(nsecs_t when, uint32_t policyFlags) {
+ // Check for release of a virtual key.
+ if (mCurrentVirtualKey.down) {
+ if (mCurrentRawPointerData.touchingIdBits.isEmpty()) {
+ // Pointer went up while virtual key was down.
+ mCurrentVirtualKey.down = false;
+ if (!mCurrentVirtualKey.ignored) {
#if DEBUG_VIRTUAL_KEYS
LOGD("VirtualKeys: Generating key up: keyCode=%d, scanCode=%d",
- mLocked.currentVirtualKey.keyCode, mLocked.currentVirtualKey.scanCode);
+ mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
#endif
- keyEventAction = AKEY_EVENT_ACTION_UP;
- keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
- touchResult = SKIP_TOUCH;
- goto DispatchVirtualKey;
+ dispatchVirtualKey(when, policyFlags,
+ AKEY_EVENT_ACTION_UP,
+ AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
}
+ return true;
+ }
- if (mCurrentTouch.pointerCount == 1) {
- int32_t x = mCurrentTouch.pointers[0].x;
- int32_t y = mCurrentTouch.pointers[0].y;
- const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
- if (virtualKey && virtualKey->keyCode == mLocked.currentVirtualKey.keyCode) {
- // Pointer is still within the space of the virtual key.
- return SKIP_TOUCH;
- }
+ if (mCurrentRawPointerData.touchingIdBits.count() == 1) {
+ uint32_t id = mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
+ const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
+ const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
+ if (virtualKey && virtualKey->keyCode == mCurrentVirtualKey.keyCode) {
+ // Pointer is still within the space of the virtual key.
+ return true;
}
+ }
- // Pointer left virtual key area or another pointer also went down.
- // Send key cancellation and drop the stroke so subsequent motions will be
- // considered fresh downs. This is useful when the user swipes away from the
- // virtual key area into the main display surface.
- mLocked.currentVirtualKey.down = false;
+ // Pointer left virtual key area or another pointer also went down.
+ // Send key cancellation but do not consume the touch yet.
+ // This is useful when the user swipes through from the virtual key area
+ // into the main display surface.
+ mCurrentVirtualKey.down = false;
+ if (!mCurrentVirtualKey.ignored) {
#if DEBUG_VIRTUAL_KEYS
LOGD("VirtualKeys: Canceling key: keyCode=%d, scanCode=%d",
- mLocked.currentVirtualKey.keyCode, mLocked.currentVirtualKey.scanCode);
+ mCurrentVirtualKey.keyCode, mCurrentVirtualKey.scanCode);
#endif
- keyEventAction = AKEY_EVENT_ACTION_UP;
- keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
- | AKEY_EVENT_FLAG_CANCELED;
-
- // Check whether the pointer moved inside the display area where we should
- // start a new stroke.
- int32_t x = mCurrentTouch.pointers[0].x;
- int32_t y = mCurrentTouch.pointers[0].y;
- if (isPointInsideSurfaceLocked(x, y)) {
- mLastTouch.clear();
- touchResult = DISPATCH_TOUCH;
- } else {
- touchResult = DROP_STROKE;
- }
- } else {
- if (mCurrentTouch.pointerCount >= 1 && mLastTouch.pointerCount == 0) {
- // Pointer just went down. Handle off-screen touches, if needed.
- int32_t x = mCurrentTouch.pointers[0].x;
- int32_t y = mCurrentTouch.pointers[0].y;
- if (! isPointInsideSurfaceLocked(x, y)) {
- // If exactly one pointer went down, check for virtual key hit.
- // Otherwise we will drop the entire stroke.
- if (mCurrentTouch.pointerCount == 1) {
- const VirtualKey* virtualKey = findVirtualKeyHitLocked(x, y);
- if (virtualKey) {
- if (mContext->shouldDropVirtualKey(when, getDevice(),
- virtualKey->keyCode, virtualKey->scanCode)) {
- return DROP_STROKE;
- }
-
- mLocked.currentVirtualKey.down = true;
- mLocked.currentVirtualKey.downTime = when;
- mLocked.currentVirtualKey.keyCode = virtualKey->keyCode;
- mLocked.currentVirtualKey.scanCode = virtualKey->scanCode;
+ dispatchVirtualKey(when, policyFlags,
+ AKEY_EVENT_ACTION_UP,
+ AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY
+ | AKEY_EVENT_FLAG_CANCELED);
+ }
+ }
+
+ if (mLastRawPointerData.touchingIdBits.isEmpty()
+ && !mCurrentRawPointerData.touchingIdBits.isEmpty()) {
+ // Pointer just went down. Check for virtual key press or off-screen touches.
+ uint32_t id = mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
+ const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
+ if (!isPointInsideSurface(pointer.x, pointer.y)) {
+ // If exactly one pointer went down, check for virtual key hit.
+ // Otherwise we will drop the entire stroke.
+ if (mCurrentRawPointerData.touchingIdBits.count() == 1) {
+ const VirtualKey* virtualKey = findVirtualKeyHit(pointer.x, pointer.y);
+ if (virtualKey) {
+ mCurrentVirtualKey.down = true;
+ mCurrentVirtualKey.downTime = when;
+ mCurrentVirtualKey.keyCode = virtualKey->keyCode;
+ mCurrentVirtualKey.scanCode = virtualKey->scanCode;
+ mCurrentVirtualKey.ignored = mContext->shouldDropVirtualKey(
+ when, getDevice(), virtualKey->keyCode, virtualKey->scanCode);
+
+ if (!mCurrentVirtualKey.ignored) {
#if DEBUG_VIRTUAL_KEYS
- LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
- mLocked.currentVirtualKey.keyCode,
- mLocked.currentVirtualKey.scanCode);
+ LOGD("VirtualKeys: Generating key down: keyCode=%d, scanCode=%d",
+ mCurrentVirtualKey.keyCode,
+ mCurrentVirtualKey.scanCode);
#endif
- keyEventAction = AKEY_EVENT_ACTION_DOWN;
- keyEventFlags = AKEY_EVENT_FLAG_FROM_SYSTEM
- | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY;
- touchResult = SKIP_TOUCH;
- goto DispatchVirtualKey;
- }
+ dispatchVirtualKey(when, policyFlags,
+ AKEY_EVENT_ACTION_DOWN,
+ AKEY_EVENT_FLAG_FROM_SYSTEM | AKEY_EVENT_FLAG_VIRTUAL_HARD_KEY);
}
- return DROP_STROKE;
}
}
- return DISPATCH_TOUCH;
+ return true;
}
+ }
- DispatchVirtualKey:
- // Collect remaining state needed to dispatch virtual key.
- keyCode = mLocked.currentVirtualKey.keyCode;
- scanCode = mLocked.currentVirtualKey.scanCode;
- downTime = mLocked.currentVirtualKey.downTime;
- } // release lock
-
- // Dispatch virtual key.
- int32_t metaState = mContext->getGlobalMetaState();
- policyFlags |= POLICY_FLAG_VIRTUAL;
- getDispatcher()->notifyKey(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
- keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
- return touchResult;
-}
-
-void TouchInputMapper::suppressSwipeOntoVirtualKeys(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.
+ // most recent touch within the screen area. The idea is to filter out stray
+ // virtual key presses when interacting with the touch screen.
//
// Problems we're trying to solve:
//
@@ -3407,37 +3442,44 @@ 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) {
+ if (mConfig.virtualKeyQuietTime > 0 && !mCurrentRawPointerData.touchingIdBits.isEmpty()) {
mContext->disableVirtualKeysUntil(when + mConfig.virtualKeyQuietTime);
}
+ return false;
}
-void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
- uint32_t currentPointerCount = mCurrentTouch.pointerCount;
- uint32_t lastPointerCount = mLastTouch.pointerCount;
- if (currentPointerCount == 0 && lastPointerCount == 0) {
- return; // nothing to do!
- }
+void TouchInputMapper::dispatchVirtualKey(nsecs_t when, uint32_t policyFlags,
+ int32_t keyEventAction, int32_t keyEventFlags) {
+ int32_t keyCode = mCurrentVirtualKey.keyCode;
+ int32_t scanCode = mCurrentVirtualKey.scanCode;
+ nsecs_t downTime = mCurrentVirtualKey.downTime;
+ int32_t metaState = mContext->getGlobalMetaState();
+ policyFlags |= POLICY_FLAG_VIRTUAL;
- // Update current touch coordinates.
- float xPrecision, yPrecision;
- prepareTouches(&xPrecision, &yPrecision);
+ NotifyKeyArgs args(when, getDeviceId(), AINPUT_SOURCE_KEYBOARD, policyFlags,
+ keyEventAction, keyEventFlags, keyCode, scanCode, metaState, downTime);
+ getListener()->notifyKey(&args);
+}
- // Dispatch motions.
- BitSet32 currentIdBits = mCurrentTouch.idBits;
- BitSet32 lastIdBits = mLastTouch.idBits;
+void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
+ BitSet32 currentIdBits = mCurrentCookedPointerData.touchingIdBits;
+ BitSet32 lastIdBits = mLastCookedPointerData.touchingIdBits;
int32_t metaState = getContext()->getGlobalMetaState();
- int32_t buttonState = mCurrentTouch.buttonState;
+ int32_t buttonState = mCurrentButtonState;
if (currentIdBits == lastIdBits) {
- // No pointer id changes so this is a move event.
- // The dispatcher takes care of batching moves so we don't have to deal with that here.
- dispatchMotion(when, policyFlags, mTouchSource,
- AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState,
- AMOTION_EVENT_EDGE_FLAG_NONE,
- mCurrentTouchProperties, mCurrentTouchCoords,
- mCurrentTouch.idToIndex, currentIdBits, -1,
- xPrecision, yPrecision, mDownTime);
+ if (!currentIdBits.isEmpty()) {
+ // No pointer id changes so this is a move event.
+ // The listener takes care of batching moves so we don't have to deal with that here.
+ dispatchMotion(when, policyFlags, mTouchSource,
+ AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState,
+ AMOTION_EVENT_EDGE_FLAG_NONE,
+ mCurrentCookedPointerData.pointerProperties,
+ mCurrentCookedPointerData.pointerCoords,
+ mCurrentCookedPointerData.idToIndex,
+ currentIdBits, -1,
+ mOrientedXPrecision, mOrientedYPrecision, mDownTime);
+ }
} else {
// There may be pointers going up and pointers going down and pointers moving
// all at the same time.
@@ -3449,23 +3491,28 @@ void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
// Update last coordinates of pointers that have moved so that we observe the new
// pointer positions at the same time as other pointers that have just gone up.
bool moveNeeded = updateMovedPointers(
- mCurrentTouchProperties, mCurrentTouchCoords, mCurrentTouch.idToIndex,
- mLastTouchProperties, mLastTouchCoords, mLastTouch.idToIndex,
+ mCurrentCookedPointerData.pointerProperties,
+ mCurrentCookedPointerData.pointerCoords,
+ mCurrentCookedPointerData.idToIndex,
+ mLastCookedPointerData.pointerProperties,
+ mLastCookedPointerData.pointerCoords,
+ mLastCookedPointerData.idToIndex,
moveIdBits);
- if (buttonState != mLastTouch.buttonState) {
+ if (buttonState != mLastButtonState) {
moveNeeded = true;
}
// Dispatch pointer up events.
while (!upIdBits.isEmpty()) {
- uint32_t upId = upIdBits.firstMarkedBit();
- upIdBits.clearBit(upId);
+ uint32_t upId = upIdBits.clearFirstMarkedBit();
dispatchMotion(when, policyFlags, mTouchSource,
AMOTION_EVENT_ACTION_POINTER_UP, 0, metaState, buttonState, 0,
- mLastTouchProperties, mLastTouchCoords,
- mLastTouch.idToIndex, dispatchedIdBits, upId,
- xPrecision, yPrecision, mDownTime);
+ mLastCookedPointerData.pointerProperties,
+ mLastCookedPointerData.pointerCoords,
+ mLastCookedPointerData.idToIndex,
+ dispatchedIdBits, upId,
+ mOrientedXPrecision, mOrientedYPrecision, mDownTime);
dispatchedIdBits.clearBit(upId);
}
@@ -3476,15 +3523,16 @@ void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
LOG_ASSERT(moveIdBits.value == dispatchedIdBits.value);
dispatchMotion(when, policyFlags, mTouchSource,
AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, 0,
- mCurrentTouchProperties, mCurrentTouchCoords,
- mCurrentTouch.idToIndex, dispatchedIdBits, -1,
- xPrecision, yPrecision, mDownTime);
+ mCurrentCookedPointerData.pointerProperties,
+ mCurrentCookedPointerData.pointerCoords,
+ mCurrentCookedPointerData.idToIndex,
+ dispatchedIdBits, -1,
+ mOrientedXPrecision, mOrientedYPrecision, mDownTime);
}
// Dispatch pointer down events using the new pointer locations.
while (!downIdBits.isEmpty()) {
- uint32_t downId = downIdBits.firstMarkedBit();
- downIdBits.clearBit(downId);
+ uint32_t downId = downIdBits.clearFirstMarkedBit();
dispatchedIdBits.markBit(downId);
if (dispatchedIdBits.count() == 1) {
@@ -3494,49 +3542,88 @@ void TouchInputMapper::dispatchTouches(nsecs_t when, uint32_t policyFlags) {
dispatchMotion(when, policyFlags, mTouchSource,
AMOTION_EVENT_ACTION_POINTER_DOWN, 0, metaState, buttonState, 0,
- mCurrentTouchProperties, mCurrentTouchCoords,
- mCurrentTouch.idToIndex, dispatchedIdBits, downId,
- xPrecision, yPrecision, mDownTime);
+ mCurrentCookedPointerData.pointerProperties,
+ mCurrentCookedPointerData.pointerCoords,
+ mCurrentCookedPointerData.idToIndex,
+ dispatchedIdBits, downId,
+ mOrientedXPrecision, mOrientedYPrecision, mDownTime);
}
}
+}
- // Update state for next time.
- for (uint32_t i = 0; i < currentPointerCount; i++) {
- mLastTouchProperties[i].copyFrom(mCurrentTouchProperties[i]);
- mLastTouchCoords[i].copyFrom(mCurrentTouchCoords[i]);
+void TouchInputMapper::dispatchHoverExit(nsecs_t when, uint32_t policyFlags) {
+ if (mSentHoverEnter &&
+ (mCurrentCookedPointerData.hoveringIdBits.isEmpty()
+ || !mCurrentCookedPointerData.touchingIdBits.isEmpty())) {
+ int32_t metaState = getContext()->getGlobalMetaState();
+ dispatchMotion(when, policyFlags, mTouchSource,
+ AMOTION_EVENT_ACTION_HOVER_EXIT, 0, metaState, mLastButtonState, 0,
+ mLastCookedPointerData.pointerProperties,
+ mLastCookedPointerData.pointerCoords,
+ mLastCookedPointerData.idToIndex,
+ mLastCookedPointerData.hoveringIdBits, -1,
+ mOrientedXPrecision, mOrientedYPrecision, mDownTime);
+ mSentHoverEnter = false;
}
}
-void TouchInputMapper::prepareTouches(float* outXPrecision, float* outYPrecision) {
- uint32_t currentPointerCount = mCurrentTouch.pointerCount;
- uint32_t lastPointerCount = mLastTouch.pointerCount;
+void TouchInputMapper::dispatchHoverEnterAndMove(nsecs_t when, uint32_t policyFlags) {
+ if (mCurrentCookedPointerData.touchingIdBits.isEmpty()
+ && !mCurrentCookedPointerData.hoveringIdBits.isEmpty()) {
+ int32_t metaState = getContext()->getGlobalMetaState();
+ if (!mSentHoverEnter) {
+ dispatchMotion(when, policyFlags, mTouchSource,
+ AMOTION_EVENT_ACTION_HOVER_ENTER, 0, metaState, mCurrentButtonState, 0,
+ mCurrentCookedPointerData.pointerProperties,
+ mCurrentCookedPointerData.pointerCoords,
+ mCurrentCookedPointerData.idToIndex,
+ mCurrentCookedPointerData.hoveringIdBits, -1,
+ mOrientedXPrecision, mOrientedYPrecision, mDownTime);
+ mSentHoverEnter = true;
+ }
- AutoMutex _l(mLock);
+ dispatchMotion(when, policyFlags, mTouchSource,
+ AMOTION_EVENT_ACTION_HOVER_MOVE, 0, metaState, mCurrentButtonState, 0,
+ mCurrentCookedPointerData.pointerProperties,
+ mCurrentCookedPointerData.pointerCoords,
+ mCurrentCookedPointerData.idToIndex,
+ mCurrentCookedPointerData.hoveringIdBits, -1,
+ mOrientedXPrecision, mOrientedYPrecision, mDownTime);
+ }
+}
+
+void TouchInputMapper::cookPointerData() {
+ uint32_t currentPointerCount = mCurrentRawPointerData.pointerCount;
+
+ mCurrentCookedPointerData.clear();
+ mCurrentCookedPointerData.pointerCount = currentPointerCount;
+ mCurrentCookedPointerData.hoveringIdBits = mCurrentRawPointerData.hoveringIdBits;
+ mCurrentCookedPointerData.touchingIdBits = mCurrentRawPointerData.touchingIdBits;
- // Walk through the the active pointers and map touch screen coordinates (TouchData) into
- // display or surface coordinates (PointerCoords) and adjust for display orientation.
+ // Walk through the the active pointers and map device coordinates onto
+ // surface coordinates and adjust for display orientation.
for (uint32_t i = 0; i < currentPointerCount; i++) {
- const PointerData& in = mCurrentTouch.pointers[i];
+ const RawPointerData::Pointer& in = mCurrentRawPointerData.pointers[i];
// ToolMajor and ToolMinor
float toolMajor, toolMinor;
switch (mCalibration.toolSizeCalibration) {
case Calibration::TOOL_SIZE_CALIBRATION_GEOMETRIC:
- toolMajor = in.toolMajor * mLocked.geometricScale;
- if (mRawAxes.toolMinor.valid) {
- toolMinor = in.toolMinor * mLocked.geometricScale;
+ toolMajor = in.toolMajor * mGeometricScale;
+ if (mRawPointerAxes.toolMinor.valid) {
+ toolMinor = in.toolMinor * mGeometricScale;
} else {
toolMinor = toolMajor;
}
break;
case Calibration::TOOL_SIZE_CALIBRATION_LINEAR:
toolMajor = in.toolMajor != 0
- ? in.toolMajor * mLocked.toolSizeLinearScale + mLocked.toolSizeLinearBias
+ ? in.toolMajor * mToolSizeLinearScale + mToolSizeLinearBias
: 0;
- if (mRawAxes.toolMinor.valid) {
+ if (mRawPointerAxes.toolMinor.valid) {
toolMinor = in.toolMinor != 0
- ? in.toolMinor * mLocked.toolSizeLinearScale
- + mLocked.toolSizeLinearBias
+ ? in.toolMinor * mToolSizeLinearScale
+ + mToolSizeLinearBias
: 0;
} else {
toolMinor = toolMajor;
@@ -3545,8 +3632,8 @@ void TouchInputMapper::prepareTouches(float* outXPrecision, float* outYPrecision
case Calibration::TOOL_SIZE_CALIBRATION_AREA:
if (in.toolMajor != 0) {
float diameter = sqrtf(in.toolMajor
- * mLocked.toolSizeAreaScale + mLocked.toolSizeAreaBias);
- toolMajor = diameter * mLocked.toolSizeLinearScale + mLocked.toolSizeLinearBias;
+ * mToolSizeAreaScale + mToolSizeAreaBias);
+ toolMajor = diameter * mToolSizeLinearScale + mToolSizeLinearBias;
} else {
toolMajor = 0;
}
@@ -3559,8 +3646,9 @@ void TouchInputMapper::prepareTouches(float* outXPrecision, float* outYPrecision
}
if (mCalibration.haveToolSizeIsSummed && mCalibration.toolSizeIsSummed) {
- toolMajor /= currentPointerCount;
- toolMinor /= currentPointerCount;
+ uint32_t touchingCount = mCurrentRawPointerData.touchingIdBits.count();
+ toolMajor /= touchingCount;
+ toolMinor /= touchingCount;
}
// Pressure
@@ -3580,10 +3668,10 @@ void TouchInputMapper::prepareTouches(float* outXPrecision, float* outYPrecision
switch (mCalibration.pressureCalibration) {
case Calibration::PRESSURE_CALIBRATION_PHYSICAL:
case Calibration::PRESSURE_CALIBRATION_AMPLITUDE:
- pressure = rawPressure * mLocked.pressureScale;
+ pressure = rawPressure * mPressureScale;
break;
default:
- pressure = 1;
+ pressure = in.isHovering ? 0 : 1;
break;
}
@@ -3591,9 +3679,9 @@ void TouchInputMapper::prepareTouches(float* outXPrecision, float* outYPrecision
float touchMajor, touchMinor;
switch (mCalibration.touchSizeCalibration) {
case Calibration::TOUCH_SIZE_CALIBRATION_GEOMETRIC:
- touchMajor = in.touchMajor * mLocked.geometricScale;
- if (mRawAxes.touchMinor.valid) {
- touchMinor = in.touchMinor * mLocked.geometricScale;
+ touchMajor = in.touchMajor * mGeometricScale;
+ if (mRawPointerAxes.touchMinor.valid) {
+ touchMinor = in.touchMinor * mGeometricScale;
} else {
touchMinor = touchMajor;
}
@@ -3619,10 +3707,10 @@ void TouchInputMapper::prepareTouches(float* outXPrecision, float* outYPrecision
float size;
switch (mCalibration.sizeCalibration) {
case Calibration::SIZE_CALIBRATION_NORMALIZED: {
- float rawSize = mRawAxes.toolMinor.valid
+ float rawSize = mRawPointerAxes.toolMinor.valid
? avg(in.toolMajor, in.toolMinor)
: in.toolMajor;
- size = rawSize * mLocked.sizeScale;
+ size = rawSize * mSizeScale;
break;
}
default:
@@ -3634,7 +3722,7 @@ void TouchInputMapper::prepareTouches(float* outXPrecision, float* outYPrecision
float orientation;
switch (mCalibration.orientationCalibration) {
case Calibration::ORIENTATION_CALIBRATION_INTERPOLATED:
- orientation = in.orientation * mLocked.orientationScale;
+ orientation = in.orientation * mOrientationScale;
break;
case Calibration::ORIENTATION_CALIBRATION_VECTOR: {
int32_t c1 = signExtendNybble((in.orientation & 0xf0) >> 4);
@@ -3659,7 +3747,7 @@ void TouchInputMapper::prepareTouches(float* outXPrecision, float* outYPrecision
float distance;
switch (mCalibration.distanceCalibration) {
case Calibration::DISTANCE_CALIBRATION_SCALED:
- distance = in.distance * mLocked.distanceScale;
+ distance = in.distance * mDistanceScale;
break;
default:
distance = 0;
@@ -3668,35 +3756,35 @@ void TouchInputMapper::prepareTouches(float* outXPrecision, float* outYPrecision
// X and Y
// Adjust coords for surface orientation.
float x, y;
- switch (mLocked.surfaceOrientation) {
+ switch (mSurfaceOrientation) {
case DISPLAY_ORIENTATION_90:
- x = float(in.y - mRawAxes.y.minValue) * mLocked.yScale;
- y = float(mRawAxes.x.maxValue - in.x) * mLocked.xScale;
+ x = float(in.y - mRawPointerAxes.y.minValue) * mYScale;
+ y = float(mRawPointerAxes.x.maxValue - in.x) * mXScale;
orientation -= M_PI_2;
if (orientation < - M_PI_2) {
orientation += M_PI;
}
break;
case DISPLAY_ORIENTATION_180:
- x = float(mRawAxes.x.maxValue - in.x) * mLocked.xScale;
- y = float(mRawAxes.y.maxValue - in.y) * mLocked.yScale;
+ x = float(mRawPointerAxes.x.maxValue - in.x) * mXScale;
+ y = float(mRawPointerAxes.y.maxValue - in.y) * mYScale;
break;
case DISPLAY_ORIENTATION_270:
- x = float(mRawAxes.y.maxValue - in.y) * mLocked.yScale;
- y = float(in.x - mRawAxes.x.minValue) * mLocked.xScale;
+ x = float(mRawPointerAxes.y.maxValue - in.y) * mYScale;
+ y = float(in.x - mRawPointerAxes.x.minValue) * mXScale;
orientation += M_PI_2;
if (orientation > M_PI_2) {
orientation -= M_PI;
}
break;
default:
- x = float(in.x - mRawAxes.x.minValue) * mLocked.xScale;
- y = float(in.y - mRawAxes.y.minValue) * mLocked.yScale;
+ x = float(in.x - mRawPointerAxes.x.minValue) * mXScale;
+ y = float(in.y - mRawPointerAxes.y.minValue) * mYScale;
break;
}
// Write output coords.
- PointerCoords& out = mCurrentTouchCoords[i];
+ PointerCoords& out = mCurrentCookedPointerData.pointerCoords[i];
out.clear();
out.setAxisValue(AMOTION_EVENT_AXIS_X, x);
out.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
@@ -3707,19 +3795,18 @@ void TouchInputMapper::prepareTouches(float* outXPrecision, float* outYPrecision
out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MAJOR, toolMajor);
out.setAxisValue(AMOTION_EVENT_AXIS_TOOL_MINOR, toolMinor);
out.setAxisValue(AMOTION_EVENT_AXIS_ORIENTATION, orientation);
- if (distance != 0) {
- out.setAxisValue(AMOTION_EVENT_AXIS_DISTANCE, distance);
- }
+ out.setAxisValue(AMOTION_EVENT_AXIS_DISTANCE, distance);
// Write output properties.
- PointerProperties& properties = mCurrentTouchProperties[i];
+ PointerProperties& properties = mCurrentCookedPointerData.pointerProperties[i];
+ uint32_t id = in.id;
properties.clear();
- properties.id = mCurrentTouch.pointers[i].id;
- properties.toolType = mCurrentTouch.pointers[i].toolType;
- }
+ properties.id = id;
+ properties.toolType = in.toolType;
- *outXPrecision = mLocked.orientedXPrecision;
- *outYPrecision = mLocked.orientedYPrecision;
+ // Write id index.
+ mCurrentCookedPointerData.idToIndex[id] = i;
+ }
}
void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlags,
@@ -3782,7 +3869,7 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag
// Send events!
int32_t metaState = getContext()->getGlobalMetaState();
- int32_t buttonState = mCurrentTouch.buttonState;
+ int32_t buttonState = mCurrentButtonState;
// Update last coordinates of pointers that have moved so that we observe the new
// pointer positions at the same time as other pointers that have just gone up.
@@ -3803,7 +3890,7 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag
mPointerGesture.lastGestureProperties,
mPointerGesture.lastGestureCoords, mPointerGesture.lastGestureIdToIndex,
movedGestureIdBits);
- if (buttonState != mLastTouch.buttonState) {
+ if (buttonState != mLastButtonState) {
moveNeeded = true;
}
}
@@ -3830,8 +3917,7 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag
& ~mPointerGesture.currentGestureIdBits.value;
}
while (!upGestureIdBits.isEmpty()) {
- uint32_t id = upGestureIdBits.firstMarkedBit();
- upGestureIdBits.clearBit(id);
+ uint32_t id = upGestureIdBits.clearFirstMarkedBit();
dispatchMotion(when, policyFlags, mPointerSource,
AMOTION_EVENT_ACTION_POINTER_UP, 0,
@@ -3861,8 +3947,7 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag
BitSet32 downGestureIdBits(mPointerGesture.currentGestureIdBits.value
& ~dispatchedGestureIdBits.value);
while (!downGestureIdBits.isEmpty()) {
- uint32_t id = downGestureIdBits.firstMarkedBit();
- downGestureIdBits.clearBit(id);
+ uint32_t id = downGestureIdBits.clearFirstMarkedBit();
dispatchedGestureIdBits.markBit(id);
if (dispatchedGestureIdBits.count() == 1) {
@@ -3906,10 +3991,11 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_X, x);
pointerCoords.setAxisValue(AMOTION_EVENT_AXIS_Y, y);
- getDispatcher()->notifyMotion(when, getDeviceId(), mPointerSource, policyFlags,
+ NotifyMotionArgs args(when, getDeviceId(), mPointerSource, policyFlags,
AMOTION_EVENT_ACTION_HOVER_MOVE, 0,
metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
1, &pointerProperties, &pointerCoords, 0, 0, mPointerGesture.downTime);
+ getListener()->notifyMotion(&args);
}
// Update state.
@@ -3919,8 +4005,7 @@ void TouchInputMapper::dispatchPointerGestures(nsecs_t when, uint32_t policyFlag
} else {
mPointerGesture.lastGestureIdBits = mPointerGesture.currentGestureIdBits;
for (BitSet32 idBits(mPointerGesture.currentGestureIdBits); !idBits.isEmpty(); ) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
+ uint32_t id = idBits.clearFirstMarkedBit();
uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
mPointerGesture.lastGestureProperties[index].copyFrom(
mPointerGesture.currentGestureProperties[index]);
@@ -3936,8 +4021,6 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
*outCancelPreviousGesture = false;
*outFinishPreviousGesture = false;
- AutoMutex _l(mLock);
-
// Handle TAP timeout.
if (isTimeout) {
#if DEBUG_GESTURES
@@ -3973,16 +4056,14 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
{
VelocityTracker::Position positions[MAX_POINTERS];
uint32_t count = 0;
- for (BitSet32 idBits(mCurrentTouch.idBits); !idBits.isEmpty(); count++) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
- uint32_t index = mCurrentTouch.idToIndex[id];
- positions[count].x = mCurrentTouch.pointers[index].x
- * mLocked.pointerGestureXMovementScale;
- positions[count].y = mCurrentTouch.pointers[index].y
- * mLocked.pointerGestureYMovementScale;
+ for (BitSet32 idBits(mCurrentRawPointerData.touchingIdBits); !idBits.isEmpty(); count++) {
+ uint32_t id = idBits.clearFirstMarkedBit();
+ const RawPointerData::Pointer& pointer = mCurrentRawPointerData.pointerForId(id);
+ positions[count].x = pointer.x * mPointerGestureXMovementScale;
+ positions[count].y = pointer.y * mPointerGestureYMovementScale;
}
- mPointerGesture.velocityTracker.addMovement(when, mCurrentTouch.idBits, positions);
+ mPointerGesture.velocityTracker.addMovement(when,
+ mCurrentRawPointerData.touchingIdBits, positions);
}
// Pick a new active touch id if needed.
@@ -3994,20 +4075,25 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
int32_t lastActiveTouchId = mPointerGesture.activeTouchId;
int32_t activeTouchId = lastActiveTouchId;
if (activeTouchId < 0) {
- if (!mCurrentTouch.idBits.isEmpty()) {
+ if (!mCurrentRawPointerData.touchingIdBits.isEmpty()) {
activeTouchChanged = true;
- activeTouchId = mPointerGesture.activeTouchId = mCurrentTouch.idBits.firstMarkedBit();
+ activeTouchId = mPointerGesture.activeTouchId =
+ mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
mPointerGesture.firstTouchTime = when;
}
- } else if (!mCurrentTouch.idBits.hasBit(activeTouchId)) {
+ } else if (!mCurrentRawPointerData.touchingIdBits.hasBit(activeTouchId)) {
activeTouchChanged = true;
- if (!mCurrentTouch.idBits.isEmpty()) {
- activeTouchId = mPointerGesture.activeTouchId = mCurrentTouch.idBits.firstMarkedBit();
+ if (!mCurrentRawPointerData.touchingIdBits.isEmpty()) {
+ activeTouchId = mPointerGesture.activeTouchId =
+ mCurrentRawPointerData.touchingIdBits.firstMarkedBit();
} else {
activeTouchId = mPointerGesture.activeTouchId = -1;
}
}
+ uint32_t currentTouchingPointerCount = mCurrentRawPointerData.touchingIdBits.count();
+ uint32_t lastTouchingPointerCount = mLastRawPointerData.touchingIdBits.count();
+
// Determine whether we are in quiet time.
bool isQuietTime = false;
if (activeTouchId < 0) {
@@ -4018,14 +4104,14 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
if ((mPointerGesture.lastGestureMode == PointerGesture::PRESS
|| mPointerGesture.lastGestureMode == PointerGesture::SWIPE
|| mPointerGesture.lastGestureMode == PointerGesture::FREEFORM)
- && mCurrentTouch.pointerCount < 2) {
+ && currentTouchingPointerCount < 2) {
// Enter quiet time when exiting swipe or freeform state.
// This is to prevent accidentally entering the hover state and flinging the
// pointer when finishing a swipe and there is still one pointer left onscreen.
isQuietTime = true;
} else if (mPointerGesture.lastGestureMode == PointerGesture::BUTTON_CLICK_OR_DRAG
- && mCurrentTouch.pointerCount >= 2
- && !isPointerDown(mCurrentTouch.buttonState)) {
+ && currentTouchingPointerCount >= 2
+ && !isPointerDown(mCurrentButtonState)) {
// Enter quiet time when releasing the button and there are still two or more
// fingers down. This may indicate that one finger was used to press the button
// but it has not gone up yet.
@@ -4053,7 +4139,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.currentGestureIdBits.clear();
mPointerGesture.pointerVelocityControl.reset();
- } else if (isPointerDown(mCurrentTouch.buttonState)) {
+ } else if (isPointerDown(mCurrentButtonState)) {
// Case 2: Button is pressed. (BUTTON_CLICK_OR_DRAG)
// The pointer follows the active touch point.
// Emit DOWN, MOVE, UP events at the pointer location.
@@ -4069,7 +4155,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
// being dragged.
#if DEBUG_GESTURES
LOGD("Gestures: BUTTON_CLICK_OR_DRAG activeTouchId=%d, "
- "currentTouchPointerCount=%d", activeTouchId, mCurrentTouch.pointerCount);
+ "currentTouchingPointerCount=%d", activeTouchId, currentTouchingPointerCount);
#endif
// Reset state when just starting.
if (mPointerGesture.lastGestureMode != PointerGesture::BUTTON_CLICK_OR_DRAG) {
@@ -4079,11 +4165,11 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
// Switch pointers if needed.
// Find the fastest pointer and follow it.
- if (activeTouchId >= 0 && mCurrentTouch.pointerCount > 1) {
+ if (activeTouchId >= 0 && currentTouchingPointerCount > 1) {
int32_t bestId = -1;
float bestSpeed = mConfig.pointerGestureDragMinSwitchSpeed;
- for (uint32_t i = 0; i < mCurrentTouch.pointerCount; i++) {
- uint32_t id = mCurrentTouch.pointers[i].id;
+ for (BitSet32 idBits(mCurrentRawPointerData.touchingIdBits); !idBits.isEmpty(); ) {
+ uint32_t id = idBits.clearFirstMarkedBit();
float vx, vy;
if (mPointerGesture.velocityTracker.getVelocity(id, &vx, &vy)) {
float speed = hypotf(vx, vy);
@@ -4103,17 +4189,15 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
}
}
- if (activeTouchId >= 0 && mLastTouch.idBits.hasBit(activeTouchId)) {
- const PointerData& currentPointer =
- mCurrentTouch.pointers[mCurrentTouch.idToIndex[activeTouchId]];
- const PointerData& lastPointer =
- mLastTouch.pointers[mLastTouch.idToIndex[activeTouchId]];
- float deltaX = (currentPointer.x - lastPointer.x)
- * mLocked.pointerGestureXMovementScale;
- float deltaY = (currentPointer.y - lastPointer.y)
- * mLocked.pointerGestureYMovementScale;
+ if (activeTouchId >= 0 && mLastRawPointerData.touchingIdBits.hasBit(activeTouchId)) {
+ const RawPointerData::Pointer& currentPointer =
+ mCurrentRawPointerData.pointerForId(activeTouchId);
+ const RawPointerData::Pointer& lastPointer =
+ mLastRawPointerData.pointerForId(activeTouchId);
+ float deltaX = (currentPointer.x - lastPointer.x) * mPointerGestureXMovementScale;
+ float deltaY = (currentPointer.y - lastPointer.y) * mPointerGestureYMovementScale;
- rotateDelta(mLocked.surfaceOrientation, &deltaX, &deltaY);
+ rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
mPointerGesture.pointerVelocityControl.move(when, &deltaX, &deltaY);
// Move the pointer using a relative motion.
@@ -4138,7 +4222,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_X, x);
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_Y, y);
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE, 1.0f);
- } else if (mCurrentTouch.pointerCount == 0) {
+ } else if (currentTouchingPointerCount == 0) {
// Case 3. No fingers down and button is not pressed. (NEUTRAL)
if (mPointerGesture.lastGestureMode != PointerGesture::NEUTRAL) {
*outFinishPreviousGesture = true;
@@ -4149,7 +4233,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
bool tapped = false;
if ((mPointerGesture.lastGestureMode == PointerGesture::HOVER
|| mPointerGesture.lastGestureMode == PointerGesture::TAP_DRAG)
- && mLastTouch.pointerCount == 1) {
+ && lastTouchingPointerCount == 1) {
if (when <= mPointerGesture.tapDownTime + mConfig.pointerGestureTapInterval) {
float x, y;
mPointerController->getPosition(&x, &y);
@@ -4209,7 +4293,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.currentGestureMode = PointerGesture::NEUTRAL;
mPointerGesture.currentGestureIdBits.clear();
}
- } else if (mCurrentTouch.pointerCount == 1) {
+ } else if (currentTouchingPointerCount == 1) {
// Case 4. Exactly one finger down, button is not pressed. (HOVER or TAP_DRAG)
// The pointer follows the active touch point.
// When in HOVER, emit HOVER_MOVE events at the pointer location.
@@ -4241,17 +4325,17 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.currentGestureMode = PointerGesture::TAP_DRAG;
}
- if (mLastTouch.idBits.hasBit(activeTouchId)) {
- const PointerData& currentPointer =
- mCurrentTouch.pointers[mCurrentTouch.idToIndex[activeTouchId]];
- const PointerData& lastPointer =
- mLastTouch.pointers[mLastTouch.idToIndex[activeTouchId]];
+ if (mLastRawPointerData.touchingIdBits.hasBit(activeTouchId)) {
+ const RawPointerData::Pointer& currentPointer =
+ mCurrentRawPointerData.pointerForId(activeTouchId);
+ const RawPointerData::Pointer& lastPointer =
+ mLastRawPointerData.pointerForId(activeTouchId);
float deltaX = (currentPointer.x - lastPointer.x)
- * mLocked.pointerGestureXMovementScale;
+ * mPointerGestureXMovementScale;
float deltaY = (currentPointer.y - lastPointer.y)
- * mLocked.pointerGestureYMovementScale;
+ * mPointerGestureYMovementScale;
- rotateDelta(mLocked.surfaceOrientation, &deltaX, &deltaY);
+ rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
mPointerGesture.pointerVelocityControl.move(when, &deltaX, &deltaY);
// Move the pointer using a relative motion.
@@ -4294,7 +4378,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.currentGestureCoords[0].setAxisValue(AMOTION_EVENT_AXIS_PRESSURE,
down ? 1.0f : 0.0f);
- if (mLastTouch.pointerCount == 0 && mCurrentTouch.pointerCount != 0) {
+ if (lastTouchingPointerCount == 0 && currentTouchingPointerCount != 0) {
mPointerGesture.resetTap();
mPointerGesture.tapDownTime = when;
mPointerGesture.tapX = x;
@@ -4322,7 +4406,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
&& mPointerGesture.lastGestureMode != PointerGesture::SWIPE
&& mPointerGesture.lastGestureMode != PointerGesture::FREEFORM) {
*outFinishPreviousGesture = true;
- } else if (!settled && mCurrentTouch.pointerCount > mLastTouch.pointerCount) {
+ } else if (!settled && currentTouchingPointerCount > lastTouchingPointerCount) {
// Additional pointers have gone down but not yet settled.
// Reset the gesture.
#if DEBUG_GESTURES
@@ -4350,33 +4434,31 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
+ mConfig.pointerGestureMultitouchSettleInterval - when)
* 0.000001f);
#endif
- mCurrentTouch.getCentroid(&mPointerGesture.referenceTouchX,
+ mCurrentRawPointerData.getCentroidOfTouchingPointers(
+ &mPointerGesture.referenceTouchX,
&mPointerGesture.referenceTouchY);
mPointerController->getPosition(&mPointerGesture.referenceGestureX,
&mPointerGesture.referenceGestureY);
}
// Clear the reference deltas for fingers not yet included in the reference calculation.
- for (BitSet32 idBits(mCurrentTouch.idBits.value & ~mPointerGesture.referenceIdBits.value);
- !idBits.isEmpty(); ) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
-
+ for (BitSet32 idBits(mCurrentRawPointerData.touchingIdBits.value
+ & ~mPointerGesture.referenceIdBits.value); !idBits.isEmpty(); ) {
+ uint32_t id = idBits.clearFirstMarkedBit();
mPointerGesture.referenceDeltas[id].dx = 0;
mPointerGesture.referenceDeltas[id].dy = 0;
}
- mPointerGesture.referenceIdBits = mCurrentTouch.idBits;
+ mPointerGesture.referenceIdBits = mCurrentRawPointerData.touchingIdBits;
// Add delta for all fingers and calculate a common movement delta.
float commonDeltaX = 0, commonDeltaY = 0;
- BitSet32 commonIdBits(mLastTouch.idBits.value & mCurrentTouch.idBits.value);
+ BitSet32 commonIdBits(mLastRawPointerData.touchingIdBits.value
+ & mCurrentRawPointerData.touchingIdBits.value);
for (BitSet32 idBits(commonIdBits); !idBits.isEmpty(); ) {
bool first = (idBits == commonIdBits);
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
-
- const PointerData& cpd = mCurrentTouch.pointers[mCurrentTouch.idToIndex[id]];
- const PointerData& lpd = mLastTouch.pointers[mLastTouch.idToIndex[id]];
+ uint32_t id = idBits.clearFirstMarkedBit();
+ const RawPointerData::Pointer& cpd = mCurrentRawPointerData.pointerForId(id);
+ const RawPointerData::Pointer& lpd = mLastRawPointerData.pointerForId(id);
PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
delta.dx += cpd.x - lpd.x;
delta.dy += cpd.y - lpd.y;
@@ -4395,12 +4477,10 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
float dist[MAX_POINTER_ID + 1];
int32_t distOverThreshold = 0;
for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
-
+ uint32_t id = idBits.clearFirstMarkedBit();
PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
- dist[id] = hypotf(delta.dx * mLocked.pointerGestureXZoomScale,
- delta.dy * mLocked.pointerGestureYZoomScale);
+ dist[id] = hypotf(delta.dx * mPointerGestureXZoomScale,
+ delta.dy * mPointerGestureYZoomScale);
if (dist[id] > mConfig.pointerGestureMultitouchMinDistance) {
distOverThreshold += 1;
}
@@ -4409,71 +4489,74 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
// Only transition when at least two pointers have moved further than
// the minimum distance threshold.
if (distOverThreshold >= 2) {
- float d;
- if (mCurrentTouch.pointerCount > 2) {
+ if (currentTouchingPointerCount > 2) {
// There are more than two pointers, switch to FREEFORM.
#if DEBUG_GESTURES
LOGD("Gestures: PRESS transitioned to FREEFORM, number of pointers %d > 2",
- mCurrentTouch.pointerCount);
+ currentTouchingPointerCount);
#endif
*outCancelPreviousGesture = true;
mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
- } else if (((d = distance(
- mCurrentTouch.pointers[0].x, mCurrentTouch.pointers[0].y,
- mCurrentTouch.pointers[1].x, mCurrentTouch.pointers[1].y))
- > mLocked.pointerGestureMaxSwipeWidth)) {
- // There are two pointers but they are too far apart for a SWIPE,
- // switch to FREEFORM.
+ } else {
+ // There are exactly two pointers.
+ BitSet32 idBits(mCurrentRawPointerData.touchingIdBits);
+ uint32_t id1 = idBits.clearFirstMarkedBit();
+ uint32_t id2 = idBits.firstMarkedBit();
+ const RawPointerData::Pointer& p1 = mCurrentRawPointerData.pointerForId(id1);
+ const RawPointerData::Pointer& p2 = mCurrentRawPointerData.pointerForId(id2);
+ float mutualDistance = distance(p1.x, p1.y, p2.x, p2.y);
+ if (mutualDistance > mPointerGestureMaxSwipeWidth) {
+ // There are two pointers but they are too far apart for a SWIPE,
+ // switch to FREEFORM.
#if DEBUG_GESTURES
- LOGD("Gestures: PRESS transitioned to FREEFORM, distance %0.3f > %0.3f",
- d, mLocked.pointerGestureMaxSwipeWidth);
+ LOGD("Gestures: PRESS transitioned to FREEFORM, distance %0.3f > %0.3f",
+ mutualDistance, mPointerGestureMaxSwipeWidth);
#endif
- *outCancelPreviousGesture = true;
- mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
- } else {
- // There are two pointers. Wait for both pointers to start moving
- // before deciding whether this is a SWIPE or FREEFORM gesture.
- uint32_t id1 = mCurrentTouch.pointers[0].id;
- uint32_t id2 = mCurrentTouch.pointers[1].id;
- float dist1 = dist[id1];
- float dist2 = dist[id2];
- 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
- // approches 1.0. Recall that dot(v1, v2) = cos(angle) * mag(v1) * mag(v2).
- PointerGesture::Delta& delta1 = mPointerGesture.referenceDeltas[id1];
- PointerGesture::Delta& delta2 = mPointerGesture.referenceDeltas[id2];
- float dx1 = delta1.dx * mLocked.pointerGestureXZoomScale;
- float dy1 = delta1.dy * mLocked.pointerGestureYZoomScale;
- float dx2 = delta2.dx * mLocked.pointerGestureXZoomScale;
- float dy2 = delta2.dy * mLocked.pointerGestureYZoomScale;
- float dot = dx1 * dx2 + dy1 * dy2;
- float cosine = dot / (dist1 * dist2); // denominator always > 0
- if (cosine >= mConfig.pointerGestureSwipeTransitionAngleCosine) {
- // Pointers are moving in the same direction. Switch to SWIPE.
+ *outCancelPreviousGesture = true;
+ mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
+ } else {
+ // There are two pointers. Wait for both pointers to start moving
+ // before deciding whether this is a SWIPE or FREEFORM gesture.
+ float dist1 = dist[id1];
+ float dist2 = dist[id2];
+ 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
+ // approches 1.0. Recall that dot(v1, v2) = cos(angle) * mag(v1) * mag(v2).
+ PointerGesture::Delta& delta1 = mPointerGesture.referenceDeltas[id1];
+ PointerGesture::Delta& delta2 = mPointerGesture.referenceDeltas[id2];
+ float dx1 = delta1.dx * mPointerGestureXZoomScale;
+ float dy1 = delta1.dy * mPointerGestureYZoomScale;
+ float dx2 = delta2.dx * mPointerGestureXZoomScale;
+ float dy2 = delta2.dy * mPointerGestureYZoomScale;
+ float dot = dx1 * dx2 + dy1 * dy2;
+ float cosine = dot / (dist1 * dist2); // denominator always > 0
+ 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);
+ 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);
#endif
- mPointerGesture.currentGestureMode = PointerGesture::SWIPE;
- } else {
- // Pointers are moving in different directions. Switch to FREEFORM.
+ mPointerGesture.currentGestureMode = PointerGesture::SWIPE;
+ } else {
+ // Pointers are moving in different directions. Switch to FREEFORM.
#if DEBUG_GESTURES
- 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);
+ 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);
#endif
- *outCancelPreviousGesture = true;
- mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
+ *outCancelPreviousGesture = true;
+ mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
+ }
}
}
}
@@ -4481,10 +4564,10 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
} else if (mPointerGesture.currentGestureMode == PointerGesture::SWIPE) {
// Switch from SWIPE to FREEFORM if additional pointers go down.
// Cancel previous gesture.
- if (mCurrentTouch.pointerCount > 2) {
+ if (currentTouchingPointerCount > 2) {
#if DEBUG_GESTURES
LOGD("Gestures: SWIPE transitioned to FREEFORM, number of pointers %d > 2",
- mCurrentTouch.pointerCount);
+ currentTouchingPointerCount);
#endif
*outCancelPreviousGesture = true;
mPointerGesture.currentGestureMode = PointerGesture::FREEFORM;
@@ -4496,9 +4579,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
if (mPointerGesture.currentGestureMode != PointerGesture::PRESS
&& (commonDeltaX || commonDeltaY)) {
for (BitSet32 idBits(mPointerGesture.referenceIdBits); !idBits.isEmpty(); ) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
-
+ uint32_t id = idBits.clearFirstMarkedBit();
PointerGesture::Delta& delta = mPointerGesture.referenceDeltas[id];
delta.dx = 0;
delta.dy = 0;
@@ -4507,10 +4588,10 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.referenceTouchX += commonDeltaX;
mPointerGesture.referenceTouchY += commonDeltaY;
- commonDeltaX *= mLocked.pointerGestureXMovementScale;
- commonDeltaY *= mLocked.pointerGestureYMovementScale;
+ commonDeltaX *= mPointerGestureXMovementScale;
+ commonDeltaY *= mPointerGestureYMovementScale;
- rotateDelta(mLocked.surfaceOrientation, &commonDeltaX, &commonDeltaY);
+ rotateDelta(mSurfaceOrientation, &commonDeltaX, &commonDeltaY);
mPointerGesture.pointerVelocityControl.move(when, &commonDeltaX, &commonDeltaY);
mPointerGesture.referenceGestureX += commonDeltaX;
@@ -4524,7 +4605,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
#if DEBUG_GESTURES
LOGD("Gestures: PRESS or SWIPE activeTouchId=%d,"
"activeGestureId=%d, currentTouchPointerCount=%d",
- activeTouchId, mPointerGesture.activeGestureId, mCurrentTouch.pointerCount);
+ activeTouchId, mPointerGesture.activeGestureId, currentTouchingPointerCount);
#endif
LOG_ASSERT(mPointerGesture.activeGestureId >= 0);
@@ -4546,7 +4627,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
#if DEBUG_GESTURES
LOGD("Gestures: FREEFORM activeTouchId=%d,"
"activeGestureId=%d, currentTouchPointerCount=%d",
- activeTouchId, mPointerGesture.activeGestureId, mCurrentTouch.pointerCount);
+ activeTouchId, mPointerGesture.activeGestureId, currentTouchingPointerCount);
#endif
LOG_ASSERT(mPointerGesture.activeGestureId >= 0);
@@ -4568,15 +4649,16 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
} else {
// Otherwise, assume we mapped all touches from the previous frame.
// Reuse all mappings that are still applicable.
- mappedTouchIdBits.value = mLastTouch.idBits.value & mCurrentTouch.idBits.value;
+ mappedTouchIdBits.value = mLastRawPointerData.touchingIdBits.value
+ & mCurrentRawPointerData.touchingIdBits.value;
usedGestureIdBits = mPointerGesture.lastGestureIdBits;
// Check whether we need to choose a new active gesture id because the
// current went went up.
- for (BitSet32 upTouchIdBits(mLastTouch.idBits.value & ~mCurrentTouch.idBits.value);
+ for (BitSet32 upTouchIdBits(mLastRawPointerData.touchingIdBits.value
+ & ~mCurrentRawPointerData.touchingIdBits.value);
!upTouchIdBits.isEmpty(); ) {
- uint32_t upTouchId = upTouchIdBits.firstMarkedBit();
- upTouchIdBits.clearBit(upTouchId);
+ uint32_t upTouchId = upTouchIdBits.clearFirstMarkedBit();
uint32_t upGestureId = mPointerGesture.freeformTouchToGestureIdMap[upTouchId];
if (upGestureId == uint32_t(mPointerGesture.activeGestureId)) {
mPointerGesture.activeGestureId = -1;
@@ -4593,12 +4675,12 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.activeGestureId);
#endif
- for (uint32_t i = 0; i < mCurrentTouch.pointerCount; i++) {
- uint32_t touchId = mCurrentTouch.pointers[i].id;
+ BitSet32 idBits(mCurrentRawPointerData.touchingIdBits);
+ for (uint32_t i = 0; i < currentTouchingPointerCount; i++) {
+ uint32_t touchId = idBits.clearFirstMarkedBit();
uint32_t gestureId;
if (!mappedTouchIdBits.hasBit(touchId)) {
- gestureId = usedGestureIdBits.firstUnmarkedBit();
- usedGestureIdBits.markBit(gestureId);
+ gestureId = usedGestureIdBits.markFirstUnmarkedBit();
mPointerGesture.freeformTouchToGestureIdMap[touchId] = gestureId;
#if DEBUG_GESTURES
LOGD("Gestures: FREEFORM "
@@ -4616,11 +4698,13 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.currentGestureIdBits.markBit(gestureId);
mPointerGesture.currentGestureIdToIndex[gestureId] = i;
- float deltaX = (mCurrentTouch.pointers[i].x - mPointerGesture.referenceTouchX)
- * mLocked.pointerGestureXZoomScale;
- float deltaY = (mCurrentTouch.pointers[i].y - mPointerGesture.referenceTouchY)
- * mLocked.pointerGestureYZoomScale;
- rotateDelta(mLocked.surfaceOrientation, &deltaX, &deltaY);
+ const RawPointerData::Pointer& pointer =
+ mCurrentRawPointerData.pointerForId(touchId);
+ float deltaX = (pointer.x - mPointerGesture.referenceTouchX)
+ * mPointerGestureXZoomScale;
+ float deltaY = (pointer.y - mPointerGesture.referenceTouchY)
+ * mPointerGestureYZoomScale;
+ rotateDelta(mSurfaceOrientation, &deltaX, &deltaY);
mPointerGesture.currentGestureProperties[i].clear();
mPointerGesture.currentGestureProperties[i].id = gestureId;
@@ -4646,7 +4730,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
}
}
- mPointerController->setButtonState(mCurrentTouch.buttonState);
+ mPointerController->setButtonState(mCurrentButtonState);
#if DEBUG_GESTURES
LOGD("Gestures: finishPreviousGesture=%s, cancelPreviousGesture=%s, "
@@ -4656,8 +4740,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
mPointerGesture.currentGestureMode, mPointerGesture.currentGestureIdBits.value,
mPointerGesture.lastGestureMode, mPointerGesture.lastGestureIdBits.value);
for (BitSet32 idBits = mPointerGesture.currentGestureIdBits; !idBits.isEmpty(); ) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
+ uint32_t id = idBits.clearFirstMarkedBit();
uint32_t index = mPointerGesture.currentGestureIdToIndex[id];
const PointerProperties& properties = mPointerGesture.currentGestureProperties[index];
const PointerCoords& coords = mPointerGesture.currentGestureCoords[index];
@@ -4669,8 +4752,7 @@ bool TouchInputMapper::preparePointerGestures(nsecs_t when,
coords.getAxisValue(AMOTION_EVENT_AXIS_PRESSURE));
}
for (BitSet32 idBits = mPointerGesture.lastGestureIdBits; !idBits.isEmpty(); ) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
+ uint32_t id = idBits.clearFirstMarkedBit();
uint32_t index = mPointerGesture.lastGestureIdToIndex[id];
const PointerProperties& properties = mPointerGesture.lastGestureProperties[index];
const PointerCoords& coords = mPointerGesture.lastGestureCoords[index];
@@ -4694,8 +4776,7 @@ void TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32
PointerProperties pointerProperties[MAX_POINTERS];
uint32_t pointerCount = 0;
while (!idBits.isEmpty()) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
+ uint32_t id = idBits.clearFirstMarkedBit();
uint32_t index = idToIndex[id];
pointerProperties[pointerCount].copyFrom(properties[index]);
pointerCoords[pointerCount].copyFrom(coords[index]);
@@ -4723,9 +4804,10 @@ void TouchInputMapper::dispatchMotion(nsecs_t when, uint32_t policyFlags, uint32
}
}
- getDispatcher()->notifyMotion(when, getDeviceId(), source, policyFlags,
+ NotifyMotionArgs args(when, getDeviceId(), source, policyFlags,
action, flags, metaState, buttonState, edgeFlags,
pointerCount, pointerProperties, pointerCoords, xPrecision, yPrecision, downTime);
+ getListener()->notifyMotion(&args);
}
bool TouchInputMapper::updateMovedPointers(const PointerProperties* inProperties,
@@ -4734,9 +4816,7 @@ bool TouchInputMapper::updateMovedPointers(const PointerProperties* inProperties
BitSet32 idBits) const {
bool changed = false;
while (!idBits.isEmpty()) {
- uint32_t id = idBits.firstMarkedBit();
- idBits.clearBit(id);
-
+ uint32_t id = idBits.clearFirstMarkedBit();
uint32_t inIndex = inIdToIndex[id];
uint32_t outIndex = outIdToIndex[id];
@@ -4759,24 +4839,21 @@ bool TouchInputMapper::updateMovedPointers(const PointerProperties* inProperties
}
void TouchInputMapper::fadePointer() {
- { // acquire lock
- AutoMutex _l(mLock);
- if (mPointerController != NULL) {
- mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
- }
- } // release lock
+ if (mPointerController != NULL) {
+ mPointerController->fade(PointerControllerInterface::TRANSITION_GRADUAL);
+ }
}
-bool TouchInputMapper::isPointInsideSurfaceLocked(int32_t x, int32_t y) {
- return x >= mRawAxes.x.minValue && x <= mRawAxes.x.maxValue
- && y >= mRawAxes.y.minValue && y <= mRawAxes.y.maxValue;
+bool TouchInputMapper::isPointInsideSurface(int32_t x, int32_t y) {
+ return x >= mRawPointerAxes.x.minValue && x <= mRawPointerAxes.x.maxValue
+ && y >= mRawPointerAxes.y.minValue && y <= mRawPointerAxes.y.maxValue;
}
-const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHitLocked(
+const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHit(
int32_t x, int32_t y) {
- size_t numVirtualKeys = mLocked.virtualKeys.size();
+ size_t numVirtualKeys = mVirtualKeys.size();
for (size_t i = 0; i < numVirtualKeys; i++) {
- const VirtualKey& virtualKey = mLocked.virtualKeys[i];
+ const VirtualKey& virtualKey = mVirtualKeys[i];
#if DEBUG_VIRTUAL_KEYS
LOGD("VirtualKeys: Hit test (%d, %d): keyCode=%d, scanCode=%d, "
@@ -4795,43 +4872,59 @@ const TouchInputMapper::VirtualKey* TouchInputMapper::findVirtualKeyHitLocked(
return NULL;
}
-void TouchInputMapper::calculatePointerIds() {
- uint32_t currentPointerCount = mCurrentTouch.pointerCount;
- uint32_t lastPointerCount = mLastTouch.pointerCount;
+void TouchInputMapper::assignPointerIds() {
+ uint32_t currentPointerCount = mCurrentRawPointerData.pointerCount;
+ uint32_t lastPointerCount = mLastRawPointerData.pointerCount;
+
+ mCurrentRawPointerData.clearIdBits();
if (currentPointerCount == 0) {
// No pointers to assign.
- mCurrentTouch.idBits.clear();
- } else if (lastPointerCount == 0) {
+ return;
+ }
+
+ if (lastPointerCount == 0) {
// All pointers are new.
- mCurrentTouch.idBits.clear();
for (uint32_t i = 0; i < currentPointerCount; i++) {
- mCurrentTouch.pointers[i].id = i;
- mCurrentTouch.idToIndex[i] = i;
- mCurrentTouch.idBits.markBit(i);
+ uint32_t id = i;
+ mCurrentRawPointerData.pointers[i].id = id;
+ mCurrentRawPointerData.idToIndex[id] = i;
+ mCurrentRawPointerData.markIdBit(id, mCurrentRawPointerData.isHovering(i));
}
- } else if (currentPointerCount == 1 && lastPointerCount == 1) {
+ return;
+ }
+
+ if (currentPointerCount == 1 && lastPointerCount == 1
+ && mCurrentRawPointerData.pointers[0].toolType
+ == mLastRawPointerData.pointers[0].toolType) {
// Only one pointer and no change in count so it must have the same id as before.
- uint32_t id = mLastTouch.pointers[0].id;
- mCurrentTouch.pointers[0].id = id;
- mCurrentTouch.idToIndex[id] = 0;
- mCurrentTouch.idBits.value = BitSet32::valueForBit(id);
- } else {
- // General case.
- // We build a heap of squared euclidean distances between current and last pointers
- // associated with the current and last pointer indices. Then, we find the best
- // match (by distance) for each current pointer.
- PointerDistanceHeapElement heap[MAX_POINTERS * MAX_POINTERS];
-
- uint32_t heapSize = 0;
- for (uint32_t currentPointerIndex = 0; currentPointerIndex < currentPointerCount;
- currentPointerIndex++) {
- for (uint32_t lastPointerIndex = 0; lastPointerIndex < lastPointerCount;
- lastPointerIndex++) {
- int64_t deltaX = mCurrentTouch.pointers[currentPointerIndex].x
- - mLastTouch.pointers[lastPointerIndex].x;
- int64_t deltaY = mCurrentTouch.pointers[currentPointerIndex].y
- - mLastTouch.pointers[lastPointerIndex].y;
+ uint32_t id = mLastRawPointerData.pointers[0].id;
+ mCurrentRawPointerData.pointers[0].id = id;
+ mCurrentRawPointerData.idToIndex[id] = 0;
+ mCurrentRawPointerData.markIdBit(id, mCurrentRawPointerData.isHovering(0));
+ return;
+ }
+
+ // General case.
+ // We build a heap of squared euclidean distances between current and last pointers
+ // associated with the current and last pointer indices. Then, we find the best
+ // match (by distance) for each current pointer.
+ // The pointers must have the same tool type but it is possible for them to
+ // transition from hovering to touching or vice-versa while retaining the same id.
+ PointerDistanceHeapElement heap[MAX_POINTERS * MAX_POINTERS];
+
+ uint32_t heapSize = 0;
+ for (uint32_t currentPointerIndex = 0; currentPointerIndex < currentPointerCount;
+ currentPointerIndex++) {
+ for (uint32_t lastPointerIndex = 0; lastPointerIndex < lastPointerCount;
+ lastPointerIndex++) {
+ const RawPointerData::Pointer& currentPointer =
+ mCurrentRawPointerData.pointers[currentPointerIndex];
+ const RawPointerData::Pointer& lastPointer =
+ mLastRawPointerData.pointers[lastPointerIndex];
+ if (currentPointer.toolType == lastPointer.toolType) {
+ int64_t deltaX = currentPointer.x - lastPointer.x;
+ int64_t deltaY = currentPointer.y - lastPointer.y;
uint64_t distance = uint64_t(deltaX * deltaX + deltaY * deltaY);
@@ -4842,193 +4935,174 @@ void TouchInputMapper::calculatePointerIds() {
heapSize += 1;
}
}
+ }
- // Heapify
- for (uint32_t startIndex = heapSize / 2; startIndex != 0; ) {
- startIndex -= 1;
- for (uint32_t parentIndex = startIndex; ;) {
- uint32_t childIndex = parentIndex * 2 + 1;
- if (childIndex >= heapSize) {
- break;
- }
-
- if (childIndex + 1 < heapSize
- && heap[childIndex + 1].distance < heap[childIndex].distance) {
- childIndex += 1;
- }
+ // Heapify
+ for (uint32_t startIndex = heapSize / 2; startIndex != 0; ) {
+ startIndex -= 1;
+ for (uint32_t parentIndex = startIndex; ;) {
+ uint32_t childIndex = parentIndex * 2 + 1;
+ if (childIndex >= heapSize) {
+ break;
+ }
- if (heap[parentIndex].distance <= heap[childIndex].distance) {
- break;
- }
+ if (childIndex + 1 < heapSize
+ && heap[childIndex + 1].distance < heap[childIndex].distance) {
+ childIndex += 1;
+ }
- swap(heap[parentIndex], heap[childIndex]);
- parentIndex = childIndex;
+ if (heap[parentIndex].distance <= heap[childIndex].distance) {
+ break;
}
+
+ swap(heap[parentIndex], heap[childIndex]);
+ parentIndex = childIndex;
}
+ }
#if DEBUG_POINTER_ASSIGNMENT
- LOGD("calculatePointerIds - initial distance min-heap: size=%d", heapSize);
- for (size_t i = 0; i < heapSize; i++) {
- LOGD(" heap[%d]: cur=%d, last=%d, distance=%lld",
- i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
- heap[i].distance);
- }
+ LOGD("assignPointerIds - initial distance min-heap: size=%d", heapSize);
+ for (size_t i = 0; i < heapSize; i++) {
+ LOGD(" heap[%d]: cur=%d, last=%d, distance=%lld",
+ i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
+ heap[i].distance);
+ }
#endif
- // Pull matches out by increasing order of distance.
- // To avoid reassigning pointers that have already been matched, the loop keeps track
- // of which last and current pointers have been matched using the matchedXXXBits variables.
- // It also tracks the used pointer id bits.
- BitSet32 matchedLastBits(0);
- BitSet32 matchedCurrentBits(0);
- BitSet32 usedIdBits(0);
- bool first = true;
- for (uint32_t i = min(currentPointerCount, lastPointerCount); i > 0; i--) {
- for (;;) {
- if (first) {
- // The first time through the loop, we just consume the root element of
- // the heap (the one with smallest distance).
- first = false;
- } else {
- // Previous iterations consumed the root element of the heap.
- // Pop root element off of the heap (sift down).
- heapSize -= 1;
- LOG_ASSERT(heapSize > 0);
-
- // Sift down.
- heap[0] = heap[heapSize];
- for (uint32_t parentIndex = 0; ;) {
- uint32_t childIndex = parentIndex * 2 + 1;
- if (childIndex >= heapSize) {
- break;
- }
-
- if (childIndex + 1 < heapSize
- && heap[childIndex + 1].distance < heap[childIndex].distance) {
- childIndex += 1;
- }
+ // Pull matches out by increasing order of distance.
+ // To avoid reassigning pointers that have already been matched, the loop keeps track
+ // of which last and current pointers have been matched using the matchedXXXBits variables.
+ // It also tracks the used pointer id bits.
+ BitSet32 matchedLastBits(0);
+ BitSet32 matchedCurrentBits(0);
+ BitSet32 usedIdBits(0);
+ bool first = true;
+ for (uint32_t i = min(currentPointerCount, lastPointerCount); heapSize > 0 && i > 0; i--) {
+ while (heapSize > 0) {
+ if (first) {
+ // The first time through the loop, we just consume the root element of
+ // the heap (the one with smallest distance).
+ first = false;
+ } else {
+ // Previous iterations consumed the root element of the heap.
+ // Pop root element off of the heap (sift down).
+ heap[0] = heap[heapSize];
+ for (uint32_t parentIndex = 0; ;) {
+ uint32_t childIndex = parentIndex * 2 + 1;
+ if (childIndex >= heapSize) {
+ break;
+ }
- if (heap[parentIndex].distance <= heap[childIndex].distance) {
- break;
- }
+ if (childIndex + 1 < heapSize
+ && heap[childIndex + 1].distance < heap[childIndex].distance) {
+ childIndex += 1;
+ }
- swap(heap[parentIndex], heap[childIndex]);
- parentIndex = childIndex;
+ if (heap[parentIndex].distance <= heap[childIndex].distance) {
+ break;
}
+ swap(heap[parentIndex], heap[childIndex]);
+ parentIndex = childIndex;
+ }
+
#if DEBUG_POINTER_ASSIGNMENT
- LOGD("calculatePointerIds - reduced distance min-heap: size=%d", heapSize);
- for (size_t i = 0; i < heapSize; i++) {
- LOGD(" heap[%d]: cur=%d, last=%d, distance=%lld",
- i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
- heap[i].distance);
- }
-#endif
+ LOGD("assignPointerIds - reduced distance min-heap: size=%d", heapSize);
+ for (size_t i = 0; i < heapSize; i++) {
+ LOGD(" heap[%d]: cur=%d, last=%d, distance=%lld",
+ i, heap[i].currentPointerIndex, heap[i].lastPointerIndex,
+ heap[i].distance);
}
+#endif
+ }
- uint32_t currentPointerIndex = heap[0].currentPointerIndex;
- if (matchedCurrentBits.hasBit(currentPointerIndex)) continue; // already matched
+ heapSize -= 1;
- uint32_t lastPointerIndex = heap[0].lastPointerIndex;
- if (matchedLastBits.hasBit(lastPointerIndex)) continue; // already matched
+ uint32_t currentPointerIndex = heap[0].currentPointerIndex;
+ if (matchedCurrentBits.hasBit(currentPointerIndex)) continue; // already matched
- matchedCurrentBits.markBit(currentPointerIndex);
- matchedLastBits.markBit(lastPointerIndex);
+ uint32_t lastPointerIndex = heap[0].lastPointerIndex;
+ if (matchedLastBits.hasBit(lastPointerIndex)) continue; // already matched
- uint32_t id = mLastTouch.pointers[lastPointerIndex].id;
- mCurrentTouch.pointers[currentPointerIndex].id = id;
- mCurrentTouch.idToIndex[id] = currentPointerIndex;
- usedIdBits.markBit(id);
+ matchedCurrentBits.markBit(currentPointerIndex);
+ matchedLastBits.markBit(lastPointerIndex);
+
+ uint32_t id = mLastRawPointerData.pointers[lastPointerIndex].id;
+ mCurrentRawPointerData.pointers[currentPointerIndex].id = id;
+ mCurrentRawPointerData.idToIndex[id] = currentPointerIndex;
+ mCurrentRawPointerData.markIdBit(id,
+ mCurrentRawPointerData.isHovering(currentPointerIndex));
+ usedIdBits.markBit(id);
#if DEBUG_POINTER_ASSIGNMENT
- LOGD("calculatePointerIds - matched: cur=%d, last=%d, id=%d, distance=%lld",
- lastPointerIndex, currentPointerIndex, id, heap[0].distance);
+ LOGD("assignPointerIds - matched: cur=%d, last=%d, id=%d, distance=%lld",
+ lastPointerIndex, currentPointerIndex, id, heap[0].distance);
#endif
- break;
- }
+ break;
}
+ }
- // Assign fresh ids to new pointers.
- if (currentPointerCount > lastPointerCount) {
- for (uint32_t i = currentPointerCount - lastPointerCount; ;) {
- uint32_t currentPointerIndex = matchedCurrentBits.firstUnmarkedBit();
- uint32_t id = usedIdBits.firstUnmarkedBit();
+ // Assign fresh ids to pointers that were not matched in the process.
+ for (uint32_t i = currentPointerCount - matchedCurrentBits.count(); i != 0; i--) {
+ uint32_t currentPointerIndex = matchedCurrentBits.markFirstUnmarkedBit();
+ uint32_t id = usedIdBits.markFirstUnmarkedBit();
- mCurrentTouch.pointers[currentPointerIndex].id = id;
- mCurrentTouch.idToIndex[id] = currentPointerIndex;
- usedIdBits.markBit(id);
+ mCurrentRawPointerData.pointers[currentPointerIndex].id = id;
+ mCurrentRawPointerData.idToIndex[id] = currentPointerIndex;
+ mCurrentRawPointerData.markIdBit(id,
+ mCurrentRawPointerData.isHovering(currentPointerIndex));
#if DEBUG_POINTER_ASSIGNMENT
- LOGD("calculatePointerIds - assigned: cur=%d, id=%d",
- currentPointerIndex, id);
+ LOGD("assignPointerIds - assigned: cur=%d, id=%d",
+ currentPointerIndex, id);
#endif
-
- if (--i == 0) break; // done
- matchedCurrentBits.markBit(currentPointerIndex);
- }
- }
-
- // Fix id bits.
- mCurrentTouch.idBits = usedIdBits;
}
}
int32_t TouchInputMapper::getKeyCodeState(uint32_t sourceMask, int32_t keyCode) {
- { // acquire lock
- AutoMutex _l(mLock);
-
- if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.keyCode == keyCode) {
- return AKEY_STATE_VIRTUAL;
- }
+ if (mCurrentVirtualKey.down && mCurrentVirtualKey.keyCode == keyCode) {
+ return AKEY_STATE_VIRTUAL;
+ }
- size_t numVirtualKeys = mLocked.virtualKeys.size();
- for (size_t i = 0; i < numVirtualKeys; i++) {
- const VirtualKey& virtualKey = mLocked.virtualKeys[i];
- if (virtualKey.keyCode == keyCode) {
- return AKEY_STATE_UP;
- }
+ size_t numVirtualKeys = mVirtualKeys.size();
+ for (size_t i = 0; i < numVirtualKeys; i++) {
+ const VirtualKey& virtualKey = mVirtualKeys[i];
+ if (virtualKey.keyCode == keyCode) {
+ return AKEY_STATE_UP;
}
- } // release lock
+ }
return AKEY_STATE_UNKNOWN;
}
int32_t TouchInputMapper::getScanCodeState(uint32_t sourceMask, int32_t scanCode) {
- { // acquire lock
- AutoMutex _l(mLock);
-
- if (mLocked.currentVirtualKey.down && mLocked.currentVirtualKey.scanCode == scanCode) {
- return AKEY_STATE_VIRTUAL;
- }
+ if (mCurrentVirtualKey.down && mCurrentVirtualKey.scanCode == scanCode) {
+ return AKEY_STATE_VIRTUAL;
+ }
- size_t numVirtualKeys = mLocked.virtualKeys.size();
- for (size_t i = 0; i < numVirtualKeys; i++) {
- const VirtualKey& virtualKey = mLocked.virtualKeys[i];
- if (virtualKey.scanCode == scanCode) {
- return AKEY_STATE_UP;
- }
+ size_t numVirtualKeys = mVirtualKeys.size();
+ for (size_t i = 0; i < numVirtualKeys; i++) {
+ const VirtualKey& virtualKey = mVirtualKeys[i];
+ if (virtualKey.scanCode == scanCode) {
+ return AKEY_STATE_UP;
}
- } // release lock
+ }
return AKEY_STATE_UNKNOWN;
}
bool TouchInputMapper::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes,
const int32_t* keyCodes, uint8_t* outFlags) {
- { // acquire lock
- AutoMutex _l(mLock);
-
- size_t numVirtualKeys = mLocked.virtualKeys.size();
- for (size_t i = 0; i < numVirtualKeys; i++) {
- const VirtualKey& virtualKey = mLocked.virtualKeys[i];
+ size_t numVirtualKeys = mVirtualKeys.size();
+ for (size_t i = 0; i < numVirtualKeys; i++) {
+ const VirtualKey& virtualKey = mVirtualKeys[i];
- for (size_t i = 0; i < numCodes; i++) {
- if (virtualKey.keyCode == keyCodes[i]) {
- outFlags[i] = 1;
- }
+ for (size_t i = 0; i < numCodes; i++) {
+ if (virtualKey.keyCode == keyCodes[i]) {
+ outFlags[i] = 1;
}
}
- } // release lock
+ }
return true;
}
@@ -5067,21 +5141,18 @@ void SingleTouchInputMapper::process(const RawEvent* rawEvent) {
}
void SingleTouchInputMapper::sync(nsecs_t when) {
- mCurrentTouch.clear();
+ mCurrentRawPointerData.clear();
+ mCurrentButtonState = 0;
if (mTouchButtonAccumulator.isActive()) {
- uint32_t buttonState = mTouchButtonAccumulator.getButtonState();
- bool isHovering = mTouchButtonAccumulator.isHovering();
- if (mSingleTouchMotionAccumulator.getAbsoluteDistance() > 0) {
- isHovering = true;
- }
+ mCurrentRawPointerData.pointerCount = 1;
+ mCurrentRawPointerData.idToIndex[0] = 0;
- mCurrentTouch.pointerCount = 1;
- mCurrentTouch.idToIndex[0] = 0;
- mCurrentTouch.idBits.markBit(0);
- mCurrentTouch.buttonState = buttonState;
+ bool isHovering = mTouchButtonAccumulator.isHovering()
+ || mSingleTouchMotionAccumulator.getAbsoluteDistance() > 0;
+ mCurrentRawPointerData.markIdBit(0, isHovering);
- PointerData& outPointer = mCurrentTouch.pointers[0];
+ RawPointerData::Pointer& outPointer = mCurrentRawPointerData.pointers[0];
outPointer.id = 0;
outPointer.x = mSingleTouchMotionAccumulator.getAbsoluteX();
outPointer.y = mSingleTouchMotionAccumulator.getAbsoluteY();
@@ -5097,21 +5168,24 @@ void SingleTouchInputMapper::sync(nsecs_t when) {
outPointer.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
}
outPointer.isHovering = isHovering;
+
+ mCurrentButtonState = mTouchButtonAccumulator.getButtonState()
+ | mCursorButtonAccumulator.getButtonState();
}
syncTouch(when, true);
}
-void SingleTouchInputMapper::configureRawAxes() {
- TouchInputMapper::configureRawAxes();
+void SingleTouchInputMapper::configureRawPointerAxes() {
+ TouchInputMapper::configureRawPointerAxes();
mTouchButtonAccumulator.configure(getDevice());
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_X, & mRawAxes.x);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_Y, & mRawAxes.y);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_PRESSURE, & mRawAxes.pressure);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_TOOL_WIDTH, & mRawAxes.toolMajor);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_DISTANCE, & mRawAxes.distance);
+ getAbsoluteAxisInfo(ABS_X, &mRawPointerAxes.x);
+ getAbsoluteAxisInfo(ABS_Y, &mRawPointerAxes.y);
+ getAbsoluteAxisInfo(ABS_PRESSURE, &mRawPointerAxes.pressure);
+ getAbsoluteAxisInfo(ABS_TOOL_WIDTH, &mRawPointerAxes.toolMajor);
+ getAbsoluteAxisInfo(ABS_DISTANCE, &mRawPointerAxes.distance);
}
@@ -5172,8 +5246,9 @@ void MultiTouchInputMapper::sync(nsecs_t when) {
size_t inCount = mMultiTouchMotionAccumulator.getSlotCount();
size_t outCount = 0;
bool havePointerIds = true;
+ BitSet32 newPointerIdBits;
- mCurrentTouch.clear();
+ mCurrentRawPointerData.clear();
for (size_t inIndex = 0; inIndex < inCount; inIndex++) {
const MultiTouchMotionAccumulator::Slot* inSlot =
@@ -5191,7 +5266,7 @@ void MultiTouchInputMapper::sync(nsecs_t when) {
break; // too many fingers!
}
- PointerData& outPointer = mCurrentTouch.pointers[outCount];
+ RawPointerData::Pointer& outPointer = mCurrentRawPointerData.pointers[outCount];
outPointer.x = inSlot->getX();
outPointer.y = inSlot->getY();
outPointer.pressure = inSlot->getPressure();
@@ -5210,8 +5285,9 @@ void MultiTouchInputMapper::sync(nsecs_t when) {
}
}
- outPointer.isHovering = mTouchButtonAccumulator.isHovering()
+ bool isHovering = mTouchButtonAccumulator.isHovering()
|| inSlot->getDistance() > 0;
+ outPointer.isHovering = isHovering;
// Assign pointer id using tracking id if available.
if (havePointerIds) {
@@ -5219,37 +5295,37 @@ void MultiTouchInputMapper::sync(nsecs_t when) {
int32_t id = -1;
if (trackingId >= 0) {
for (BitSet32 idBits(mPointerIdBits); !idBits.isEmpty(); ) {
- uint32_t n = idBits.firstMarkedBit();
- idBits.clearBit(n);
-
+ uint32_t n = idBits.clearFirstMarkedBit();
if (mPointerTrackingIdMap[n] == trackingId) {
id = n;
}
}
if (id < 0 && !mPointerIdBits.isFull()) {
- id = mPointerIdBits.firstUnmarkedBit();
- mPointerIdBits.markBit(id);
+ id = mPointerIdBits.markFirstUnmarkedBit();
mPointerTrackingIdMap[id] = trackingId;
}
}
if (id < 0) {
havePointerIds = false;
- mCurrentTouch.idBits.clear();
+ mCurrentRawPointerData.clearIdBits();
+ newPointerIdBits.clear();
} else {
outPointer.id = id;
- mCurrentTouch.idToIndex[id] = outCount;
- mCurrentTouch.idBits.markBit(id);
+ mCurrentRawPointerData.idToIndex[id] = outCount;
+ mCurrentRawPointerData.markIdBit(id, isHovering);
+ newPointerIdBits.markBit(id);
}
}
outCount += 1;
}
- mCurrentTouch.pointerCount = outCount;
- mCurrentTouch.buttonState = mTouchButtonAccumulator.getButtonState();
+ mCurrentRawPointerData.pointerCount = outCount;
+ mCurrentButtonState = mTouchButtonAccumulator.getButtonState()
+ | mCursorButtonAccumulator.getButtonState();
- mPointerIdBits = mCurrentTouch.idBits;
+ mPointerIdBits = newPointerIdBits;
syncTouch(when, havePointerIds);
@@ -5258,26 +5334,27 @@ void MultiTouchInputMapper::sync(nsecs_t when) {
}
}
-void MultiTouchInputMapper::configureRawAxes() {
- TouchInputMapper::configureRawAxes();
+void MultiTouchInputMapper::configureRawPointerAxes() {
+ TouchInputMapper::configureRawPointerAxes();
mTouchButtonAccumulator.configure(getDevice());
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_X, &mRawAxes.x);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_POSITION_Y, &mRawAxes.y);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MAJOR, &mRawAxes.touchMajor);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TOUCH_MINOR, &mRawAxes.touchMinor);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MAJOR, &mRawAxes.toolMajor);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_WIDTH_MINOR, &mRawAxes.toolMinor);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_ORIENTATION, &mRawAxes.orientation);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_PRESSURE, &mRawAxes.pressure);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_DISTANCE, &mRawAxes.distance);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_TRACKING_ID, &mRawAxes.trackingId);
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), ABS_MT_SLOT, &mRawAxes.slot);
-
- if (mRawAxes.trackingId.valid
- && mRawAxes.slot.valid && mRawAxes.slot.minValue == 0 && mRawAxes.slot.maxValue > 0) {
- size_t slotCount = mRawAxes.slot.maxValue + 1;
+ getAbsoluteAxisInfo(ABS_MT_POSITION_X, &mRawPointerAxes.x);
+ getAbsoluteAxisInfo(ABS_MT_POSITION_Y, &mRawPointerAxes.y);
+ getAbsoluteAxisInfo(ABS_MT_TOUCH_MAJOR, &mRawPointerAxes.touchMajor);
+ getAbsoluteAxisInfo(ABS_MT_TOUCH_MINOR, &mRawPointerAxes.touchMinor);
+ getAbsoluteAxisInfo(ABS_MT_WIDTH_MAJOR, &mRawPointerAxes.toolMajor);
+ getAbsoluteAxisInfo(ABS_MT_WIDTH_MINOR, &mRawPointerAxes.toolMinor);
+ getAbsoluteAxisInfo(ABS_MT_ORIENTATION, &mRawPointerAxes.orientation);
+ getAbsoluteAxisInfo(ABS_MT_PRESSURE, &mRawPointerAxes.pressure);
+ getAbsoluteAxisInfo(ABS_MT_DISTANCE, &mRawPointerAxes.distance);
+ getAbsoluteAxisInfo(ABS_MT_TRACKING_ID, &mRawPointerAxes.trackingId);
+ getAbsoluteAxisInfo(ABS_MT_SLOT, &mRawPointerAxes.slot);
+
+ if (mRawPointerAxes.trackingId.valid
+ && mRawPointerAxes.slot.valid
+ && mRawPointerAxes.slot.minValue == 0 && mRawPointerAxes.slot.maxValue > 0) {
+ size_t slotCount = mRawPointerAxes.slot.maxValue + 1;
if (slotCount > MAX_SLOTS) {
LOGW("MultiTouch Device %s reported %d slots but the framework "
"only supports a maximum of %d slots at this time.",
@@ -5364,7 +5441,7 @@ void JoystickInputMapper::configure(const InputReaderConfiguration* config, uint
// Collect all axes.
for (int32_t abs = 0; abs <= ABS_MAX; abs++) {
RawAbsoluteAxisInfo rawAxisInfo;
- getEventHub()->getAbsoluteAxisInfo(getDeviceId(), abs, &rawAxisInfo);
+ getAbsoluteAxisInfo(abs, &rawAxisInfo);
if (rawAxisInfo.valid) {
// Map axis.
AxisInfo axisInfo;
@@ -5581,9 +5658,10 @@ void JoystickInputMapper::sync(nsecs_t when, bool force) {
// TODO: Use the input device configuration to control this behavior more finely.
uint32_t policyFlags = 0;
- getDispatcher()->notifyMotion(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, policyFlags,
+ NotifyMotionArgs args(when, getDeviceId(), AINPUT_SOURCE_JOYSTICK, policyFlags,
AMOTION_EVENT_ACTION_MOVE, 0, metaState, buttonState, AMOTION_EVENT_EDGE_FLAG_NONE,
1, &pointerProperties, &pointerCoords, 0, 0, 0);
+ getListener()->notifyMotion(&args);
}
bool JoystickInputMapper::filterAxes(bool force) {