diff options
Diffstat (limited to 'services/input/InputReader.cpp')
-rw-r--r-- | services/input/InputReader.cpp | 171 |
1 files changed, 108 insertions, 63 deletions
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp index 42512d8..71eba52 100644 --- a/services/input/InputReader.cpp +++ b/services/input/InputReader.cpp @@ -237,7 +237,8 @@ InputReader::InputReader(const sp<EventHubInterface>& eventHub, const sp<InputReaderPolicyInterface>& policy, const sp<InputListenerInterface>& listener) : mContext(this), mEventHub(eventHub), mPolicy(policy), - mGlobalMetaState(0), mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX), + mGlobalMetaState(0), mGeneration(1), + mDisableVirtualKeysTimeout(LLONG_MIN), mNextTimeout(LLONG_MAX), mConfigurationChangesToRefresh(0) { mQueuedListener = new QueuedInputListener(listener); @@ -257,18 +258,24 @@ InputReader::~InputReader() { } void InputReader::loopOnce() { + int32_t oldGeneration; int32_t timeoutMillis; + bool inputDevicesChanged = false; + Vector<InputDeviceInfo> inputDevices; { // acquire lock AutoMutex _l(mLock); + oldGeneration = mGeneration; + timeoutMillis = -1; + uint32_t changes = mConfigurationChangesToRefresh; if (changes) { mConfigurationChangesToRefresh = 0; + timeoutMillis = 0; refreshConfigurationLocked(changes); } - timeoutMillis = -1; - if (mNextTimeout != LLONG_MAX) { + if (timeoutMillis < 0 && mNextTimeout != LLONG_MAX) { nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); timeoutMillis = toMillisecondTimeoutDelay(now, mNextTimeout); } @@ -283,7 +290,8 @@ void InputReader::loopOnce() { if (count) { processEventsLocked(mEventBuffer, count); } - if (!count || timeoutMillis == 0) { + + if (mNextTimeout != LLONG_MAX) { nsecs_t now = systemTime(SYSTEM_TIME_MONOTONIC); if (now >= mNextTimeout) { #if DEBUG_RAW_EVENTS @@ -293,8 +301,18 @@ void InputReader::loopOnce() { timeoutExpiredLocked(now); } } + + if (oldGeneration != mGeneration) { + inputDevicesChanged = true; + getInputDevicesLocked(inputDevices); + } } // release lock + // Send out a message that the describes the changed input devices. + if (inputDevicesChanged) { + mPolicy->notifyInputDevicesChanged(inputDevices); + } + // 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 @@ -344,6 +362,12 @@ void InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) { } void InputReader::addDeviceLocked(nsecs_t when, int32_t deviceId) { + ssize_t deviceIndex = mDevices.indexOfKey(deviceId); + if (deviceIndex >= 0) { + ALOGW("Ignoring spurious device added event for deviceId %d.", deviceId); + return; + } + InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(deviceId); uint32_t classes = mEventHub->getDeviceClasses(deviceId); @@ -359,27 +383,22 @@ void InputReader::addDeviceLocked(nsecs_t when, int32_t deviceId) { identifier.name.string(), device->getSources()); } - ssize_t deviceIndex = mDevices.indexOfKey(deviceId); - if (deviceIndex < 0) { - mDevices.add(deviceId, device); - } else { - ALOGW("Ignoring spurious device added event for deviceId %d.", deviceId); - delete device; - return; - } + mDevices.add(deviceId, device); + bumpGenerationLocked(); } void InputReader::removeDeviceLocked(nsecs_t when, int32_t deviceId) { InputDevice* device = NULL; ssize_t deviceIndex = mDevices.indexOfKey(deviceId); - if (deviceIndex >= 0) { - device = mDevices.valueAt(deviceIndex); - mDevices.removeItemsAt(deviceIndex, 1); - } else { + if (deviceIndex < 0) { ALOGW("Ignoring spurious device removed event for deviceId %d.", deviceId); return; } + device = mDevices.valueAt(deviceIndex); + mDevices.removeItemsAt(deviceIndex, 1); + bumpGenerationLocked(); + if (device->isIgnored()) { ALOGI("Device removed: id=%d, name='%s' (ignored non-input device)", device->getId(), device->getName().string()); @@ -394,7 +413,8 @@ void InputReader::removeDeviceLocked(nsecs_t when, int32_t deviceId) { InputDevice* InputReader::createDeviceLocked(int32_t deviceId, const InputDeviceIdentifier& identifier, uint32_t classes) { - InputDevice* device = new InputDevice(&mContext, deviceId, identifier, classes); + InputDevice* device = new InputDevice(&mContext, deviceId, bumpGenerationLocked(), + identifier, classes); // External devices. if (classes & INPUT_DEVICE_CLASS_EXTERNAL) { @@ -577,39 +597,30 @@ void InputReader::requestTimeoutAtTimeLocked(nsecs_t when) { } } +int32_t InputReader::bumpGenerationLocked() { + return ++mGeneration; +} + void InputReader::getInputConfiguration(InputConfiguration* outConfiguration) { AutoMutex _l(mLock); *outConfiguration = mInputConfiguration; } -status_t InputReader::getInputDeviceInfo(int32_t deviceId, InputDeviceInfo* outDeviceInfo) { +void InputReader::getInputDevices(Vector<InputDeviceInfo>& outInputDevices) { AutoMutex _l(mLock); - - 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; - } - - device->getDeviceInfo(outDeviceInfo); - return OK; + getInputDevicesLocked(outInputDevices); } -void InputReader::getInputDeviceIds(Vector<int32_t>& outDeviceIds) { - AutoMutex _l(mLock); - - outDeviceIds.clear(); +void InputReader::getInputDevicesLocked(Vector<InputDeviceInfo>& outInputDevices) { + outInputDevices.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()); + outInputDevices.push(); + device->getDeviceInfo(&outInputDevices.editTop()); } } } @@ -824,6 +835,11 @@ void InputReader::ContextImpl::requestTimeoutAtTime(nsecs_t when) { mReader->requestTimeoutAtTimeLocked(when); } +int32_t InputReader::ContextImpl::bumpGeneration() { + // lock is already held by the input loop + return mReader->bumpGenerationLocked(); +} + InputReaderPolicyInterface* InputReader::ContextImpl::getPolicy() { return mReader->mPolicy.get(); } @@ -854,9 +870,10 @@ bool InputReaderThread::threadLoop() { // --- InputDevice --- -InputDevice::InputDevice(InputReaderContext* context, int32_t id, +InputDevice::InputDevice(InputReaderContext* context, int32_t id, int32_t generation, const InputDeviceIdentifier& identifier, uint32_t classes) : - mContext(context), mId(id), mIdentifier(identifier), mClasses(classes), + mContext(context), mId(id), mGeneration(generation), + mIdentifier(identifier), mClasses(classes), mSources(0), mIsExternal(false), mDropUntilNextSync(false) { } @@ -874,6 +891,7 @@ void InputDevice::dump(String8& dump) { dump.appendFormat(INDENT "Device %d: %s\n", deviceInfo.getId(), deviceInfo.getName().string()); + dump.appendFormat(INDENT2 "Generation: %d\n", mGeneration); dump.appendFormat(INDENT2 "IsExternal: %s\n", toString(mIsExternal)); dump.appendFormat(INDENT2 "Sources: 0x%08x\n", deviceInfo.getSources()); dump.appendFormat(INDENT2 "KeyboardType: %d\n", deviceInfo.getKeyboardType()); @@ -946,14 +964,12 @@ void InputDevice::process(const RawEvent* rawEvents, size_t count) { size_t numMappers = mMappers.size(); for (const RawEvent* rawEvent = rawEvents; count--; rawEvent++) { #if DEBUG_RAW_EVENTS - ALOGD("Input event: device=%d type=0x%04x scancode=0x%04x " - "keycode=0x%04x value=0x%08x flags=0x%08x", - rawEvent->deviceId, rawEvent->type, rawEvent->scanCode, rawEvent->keyCode, - rawEvent->value, rawEvent->flags); + ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x", + rawEvent->deviceId, rawEvent->type, rawEvent->code, rawEvent->value); #endif if (mDropUntilNextSync) { - if (rawEvent->type == EV_SYN && rawEvent->scanCode == SYN_REPORT) { + if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) { mDropUntilNextSync = false; #if DEBUG_RAW_EVENTS ALOGD("Recovered from input event buffer overrun."); @@ -963,7 +979,7 @@ void InputDevice::process(const RawEvent* rawEvents, size_t count) { ALOGD("Dropped input event while waiting for next input sync."); #endif } - } else if (rawEvent->type == EV_SYN && rawEvent->scanCode == SYN_DROPPED) { + } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) { ALOGI("Detected input event buffer overrun for device %s.", getName().string()); mDropUntilNextSync = true; reset(rawEvent->when); @@ -985,7 +1001,7 @@ void InputDevice::timeoutExpired(nsecs_t when) { } void InputDevice::getDeviceInfo(InputDeviceInfo* outDeviceInfo) { - outDeviceInfo->initialize(mId, mIdentifier.name, mIdentifier.descriptor); + outDeviceInfo->initialize(mId, mGeneration, mIdentifier.name, mIdentifier.descriptor); size_t numMappers = mMappers.size(); for (size_t i = 0; i < numMappers; i++) { @@ -1056,6 +1072,10 @@ void InputDevice::fadePointer() { } } +void InputDevice::bumpGeneration() { + mGeneration = mContext->bumpGeneration(); +} + void InputDevice::notifyReset(nsecs_t when) { NotifyDeviceResetArgs args(when, mId); mContext->getListener()->notifyDeviceReset(&args); @@ -1092,7 +1112,7 @@ void CursorButtonAccumulator::clearButtons() { void CursorButtonAccumulator::process(const RawEvent* rawEvent) { if (rawEvent->type == EV_KEY) { - switch (rawEvent->scanCode) { + switch (rawEvent->code) { case BTN_LEFT: mBtnLeft = rawEvent->value; break; @@ -1159,7 +1179,7 @@ void CursorMotionAccumulator::clearRelativeAxes() { void CursorMotionAccumulator::process(const RawEvent* rawEvent) { if (rawEvent->type == EV_REL) { - switch (rawEvent->scanCode) { + switch (rawEvent->code) { case REL_X: mRelX = rawEvent->value; break; @@ -1198,7 +1218,7 @@ void CursorScrollAccumulator::clearRelativeAxes() { void CursorScrollAccumulator::process(const RawEvent* rawEvent) { if (rawEvent->type == EV_REL) { - switch (rawEvent->scanCode) { + switch (rawEvent->code) { case REL_WHEEL: mRelWheel = rawEvent->value; break; @@ -1261,7 +1281,7 @@ void TouchButtonAccumulator::clearButtons() { void TouchButtonAccumulator::process(const RawEvent* rawEvent) { if (rawEvent->type == EV_KEY) { - switch (rawEvent->scanCode) { + switch (rawEvent->code) { case BTN_TOUCH: mBtnTouch = rawEvent->value; break; @@ -1467,7 +1487,7 @@ void SingleTouchMotionAccumulator::clearAbsoluteAxes() { void SingleTouchMotionAccumulator::process(const RawEvent* rawEvent) { if (rawEvent->type == EV_ABS) { - switch (rawEvent->scanCode) { + switch (rawEvent->code) { case ABS_X: mAbsX = rawEvent->value; break; @@ -1551,7 +1571,7 @@ void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) { if (rawEvent->type == EV_ABS) { bool newSlot = false; if (mUsingSlotsProtocol) { - if (rawEvent->scanCode == ABS_MT_SLOT) { + if (rawEvent->code == ABS_MT_SLOT) { mCurrentSlot = rawEvent->value; newSlot = true; } @@ -1570,7 +1590,7 @@ void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) { } else { Slot* slot = &mSlots[mCurrentSlot]; - switch (rawEvent->scanCode) { + switch (rawEvent->code) { case ABS_MT_POSITION_X: slot->mInUse = true; slot->mAbsMTPositionX = rawEvent->value; @@ -1626,7 +1646,7 @@ void MultiTouchMotionAccumulator::process(const RawEvent* rawEvent) { break; } } - } else if (rawEvent->type == EV_SYN && rawEvent->scanCode == SYN_MT_REPORT) { + } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_MT_REPORT) { // MultiTouch Sync: The driver has returned all data for *one* of the pointers. mCurrentSlot += 1; } @@ -1730,6 +1750,10 @@ status_t InputMapper::getAbsoluteAxisInfo(int32_t axis, RawAbsoluteAxisInfo* axi return getEventHub()->getAbsoluteAxisInfo(getDeviceId(), axis, axisInfo); } +void InputMapper::bumpGeneration() { + mDevice->bumpGeneration(); +} + void InputMapper::dumpRawAbsoluteAxisInfo(String8& dump, const RawAbsoluteAxisInfo& axis, const char* name) { if (axis.valid) { @@ -1757,7 +1781,7 @@ uint32_t SwitchInputMapper::getSources() { void SwitchInputMapper::process(const RawEvent* rawEvent) { switch (rawEvent->type) { case EV_SW: - processSwitch(rawEvent->when, rawEvent->scanCode, rawEvent->value); + processSwitch(rawEvent->when, rawEvent->code, rawEvent->value); break; } } @@ -1849,6 +1873,7 @@ void KeyboardInputMapper::reset(nsecs_t when) { mMetaState = AMETA_NONE; mDownTime = 0; mKeyDowns.clear(); + mCurrentHidUsage = 0; resetLedState(); @@ -1858,13 +1883,32 @@ void KeyboardInputMapper::reset(nsecs_t when) { void KeyboardInputMapper::process(const RawEvent* rawEvent) { switch (rawEvent->type) { case EV_KEY: { - int32_t scanCode = rawEvent->scanCode; + int32_t scanCode = rawEvent->code; + int32_t usageCode = mCurrentHidUsage; + mCurrentHidUsage = 0; + if (isKeyboardOrGamepadKey(scanCode)) { - processKey(rawEvent->when, rawEvent->value != 0, rawEvent->keyCode, scanCode, - rawEvent->flags); + int32_t keyCode; + uint32_t flags; + if (getEventHub()->mapKey(getDeviceId(), scanCode, usageCode, &keyCode, &flags)) { + keyCode = AKEYCODE_UNKNOWN; + flags = 0; + } + processKey(rawEvent->when, rawEvent->value != 0, keyCode, scanCode, flags); + } + break; + } + case EV_MSC: { + if (rawEvent->code == MSC_SCAN) { + mCurrentHidUsage = rawEvent->value; } break; } + case EV_SYN: { + if (rawEvent->code == SYN_REPORT) { + mCurrentHidUsage = 0; + } + } } } @@ -2119,6 +2163,7 @@ void CursorInputMapper::configure(nsecs_t when, } else { mOrientation = DISPLAY_ORIENTATION_0; } + bumpGeneration(); } } @@ -2183,7 +2228,7 @@ void CursorInputMapper::process(const RawEvent* rawEvent) { mCursorMotionAccumulator.process(rawEvent); mCursorScrollAccumulator.process(rawEvent); - if (rawEvent->type == EV_SYN && rawEvent->scanCode == SYN_REPORT) { + if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) { sync(rawEvent->when); } } @@ -2980,6 +3025,7 @@ void TouchInputMapper::configureSurface(nsecs_t when, bool* outResetNeeded) { // Inform the dispatcher about the changes. *outResetNeeded = true; + bumpGeneration(); } } @@ -3016,8 +3062,7 @@ void TouchInputMapper::configureVirtualKeys() { virtualKey.scanCode = virtualKeyDefinition.scanCode; int32_t keyCode; uint32_t flags; - if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode, - & keyCode, & flags)) { + if (getEventHub()->mapKey(getDeviceId(), virtualKey.scanCode, 0, &keyCode, &flags)) { ALOGW(INDENT "VirtualKey %d: could not obtain key code, ignoring", virtualKey.scanCode); mVirtualKeys.pop(); // drop the key @@ -3311,7 +3356,7 @@ void TouchInputMapper::process(const RawEvent* rawEvent) { mCursorScrollAccumulator.process(rawEvent); mTouchButtonAccumulator.process(rawEvent); - if (rawEvent->type == EV_SYN && rawEvent->scanCode == SYN_REPORT) { + if (rawEvent->type == EV_SYN && rawEvent->code == SYN_REPORT) { sync(rawEvent->when); } } @@ -5920,7 +5965,7 @@ void JoystickInputMapper::reset(nsecs_t when) { void JoystickInputMapper::process(const RawEvent* rawEvent) { switch (rawEvent->type) { case EV_ABS: { - ssize_t index = mAxes.indexOfKey(rawEvent->scanCode); + ssize_t index = mAxes.indexOfKey(rawEvent->code); if (index >= 0) { Axis& axis = mAxes.editValueAt(index); float newValue, highNewValue; @@ -5956,7 +6001,7 @@ void JoystickInputMapper::process(const RawEvent* rawEvent) { } case EV_SYN: - switch (rawEvent->scanCode) { + switch (rawEvent->code) { case SYN_REPORT: sync(rawEvent->when, false /*force*/); break; |