Loading services/inputflinger/InputListener.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,11 @@ using android::base::StringPrintf; namespace android { std::list<NotifyArgs>& operator+=(std::list<NotifyArgs>& keep, std::list<NotifyArgs>&& consume) { keep.splice(keep.end(), consume); return keep; } // --- InputListenerInterface --- // Helper to std::visit with lambdas. Loading services/inputflinger/NotifyArgs.cpp +23 −0 Original line number Diff line number Diff line Loading @@ -225,4 +225,27 @@ NotifyPointerCaptureChangedArgs::NotifyPointerCaptureChangedArgs( int32_t id, nsecs_t eventTime, const PointerCaptureRequest& request) : id(id), eventTime(eventTime), request(request) {} // Helper to std::visit with lambdas. template <typename... V> struct Visitor : V... {}; // explicit deduction guide (not needed as of C++20) template <typename... V> Visitor(V...) -> Visitor<V...>; const char* toString(const NotifyArgs& args) { Visitor toStringVisitor{ [&](const NotifyConfigurationChangedArgs&) { return "NotifyConfigurationChangedArgs"; }, [&](const NotifyKeyArgs&) { return "NotifyKeyArgs"; }, [&](const NotifyMotionArgs&) { return "NotifyMotionArgs"; }, [&](const NotifySensorArgs&) { return "NotifySensorArgs"; }, [&](const NotifySwitchArgs&) { return "NotifySwitchArgs"; }, [&](const NotifyDeviceResetArgs&) { return "NotifyDeviceResetArgs"; }, [&](const NotifyPointerCaptureChangedArgs&) { return "NotifyPointerCaptureChangedArgs"; }, [&](const NotifyVibratorStateArgs&) { return "NotifyVibratorStateArgs"; }, }; return std::visit(toStringVisitor, args); } } // namespace android services/inputflinger/include/InputListener.h +2 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,8 @@ namespace android { std::list<NotifyArgs>& operator+=(std::list<NotifyArgs>& keep, std::list<NotifyArgs>&& consume); /* * The interface used by the InputReader to notify the InputListener about input events. */ Loading services/inputflinger/include/NotifyArgs.h +2 −0 Original line number Diff line number Diff line Loading @@ -213,4 +213,6 @@ using NotifyArgs = std::variant<NotifyConfigurationChangedArgs, NotifyKeyArgs, N NotifySensorArgs, NotifySwitchArgs, NotifyDeviceResetArgs, NotifyPointerCaptureChangedArgs, NotifyVibratorStateArgs>; const char* toString(const NotifyArgs& args); } // namespace android services/inputflinger/reader/InputDevice.cpp +50 −33 Original line number Diff line number Diff line Loading @@ -65,7 +65,8 @@ bool InputDevice::isEnabled() { return enabled; } void InputDevice::setEnabled(bool enabled, nsecs_t when) { std::list<NotifyArgs> InputDevice::setEnabled(bool enabled, nsecs_t when) { std::list<NotifyArgs> out; if (enabled && mAssociatedDisplayPort && !mAssociatedViewport) { ALOGW("Cannot enable input device %s because it is associated with port %" PRIu8 ", " "but the corresponding viewport is not found", Loading @@ -74,7 +75,7 @@ void InputDevice::setEnabled(bool enabled, nsecs_t when) { } if (isEnabled() == enabled) { return; return out; } // When resetting some devices, the driver needs to be queried to ensure that a proper reset is Loading @@ -82,13 +83,14 @@ void InputDevice::setEnabled(bool enabled, nsecs_t when) { // but before disabling the device. See MultiTouchMotionAccumulator::reset for more information. if (enabled) { for_each_subdevice([](auto& context) { context.enableDevice(); }); reset(when); out += reset(when); } else { reset(when); out += reset(when); for_each_subdevice([](auto& context) { context.disableDevice(); }); } // Must change generation to flag this device as changed bumpGeneration(); return out; } void InputDevice::dump(std::string& dump, const std::string& eventHubDevStr) { Loading Loading @@ -241,8 +243,9 @@ void InputDevice::removeEventHubDevice(int32_t eventHubId) { mDevices.erase(eventHubId); } void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config, std::list<NotifyArgs> InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes) { std::list<NotifyArgs> out; mSources = 0; mClasses = ftl::Flags<InputDeviceClass>(0); mControllerNumber = 0; Loading Loading @@ -313,7 +316,7 @@ void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config if (!changes || (changes & InputReaderConfiguration::CHANGE_ENABLED_STATE)) { auto it = config->disabledDevices.find(mId); bool enabled = it == config->disabledDevices.end(); setEnabled(enabled, when); out += setEnabled(enabled, when); } if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) { Loading Loading @@ -366,37 +369,42 @@ void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config // For first-time configuration, only allow device to be disabled after mappers have // finished configuring. This is because we need to read some of the properties from // the device's open fd. setEnabled(enabled, when); out += setEnabled(enabled, when); } } for_each_mapper([this, when, config, changes](InputMapper& mapper) { mapper.configure(when, config, changes); for_each_mapper([this, when, &config, changes, &out](InputMapper& mapper) { out += mapper.configure(when, config, changes); mSources |= mapper.getSources(); }); // If a device is just plugged but it might be disabled, we need to update some info like // axis range of touch from each InputMapper first, then disable it. if (!changes) { setEnabled(config->disabledDevices.find(mId) == config->disabledDevices.end(), when); out += setEnabled(config->disabledDevices.find(mId) == config->disabledDevices.end(), when); } } return out; } void InputDevice::reset(nsecs_t when) { for_each_mapper([when](InputMapper& mapper) { mapper.reset(when); }); std::list<NotifyArgs> InputDevice::reset(nsecs_t when) { std::list<NotifyArgs> out; for_each_mapper([&](InputMapper& mapper) { out += mapper.reset(when); }); mContext->updateGlobalMetaState(); notifyReset(when); out.push_back(notifyReset(when)); return out; } void InputDevice::process(const RawEvent* rawEvents, size_t count) { std::list<NotifyArgs> InputDevice::process(const RawEvent* rawEvents, size_t count) { // Process all of the events in order for each mapper. // We cannot simply ask each mapper to process them in bulk because mappers may // have side-effects that must be interleaved. For example, joystick movement events and // gamepad button presses are handled by different mappers but they should be dispatched // in the order received. std::list<NotifyArgs> out; for (const RawEvent* rawEvent = rawEvents; count != 0; rawEvent++) { if (DEBUG_RAW_EVENTS) { ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x when=%" PRId64, Loading @@ -418,22 +426,27 @@ void InputDevice::process(const RawEvent* rawEvents, size_t count) { } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) { ALOGI("Detected input event buffer overrun for device %s.", getName().c_str()); mDropUntilNextSync = true; reset(rawEvent->when); out += reset(rawEvent->when); } else { for_each_mapper_in_subdevice(rawEvent->deviceId, [rawEvent](InputMapper& mapper) { mapper.process(rawEvent); for_each_mapper_in_subdevice(rawEvent->deviceId, [&](InputMapper& mapper) { out += mapper.process(rawEvent); }); } --count; } return out; } void InputDevice::timeoutExpired(nsecs_t when) { for_each_mapper([when](InputMapper& mapper) { mapper.timeoutExpired(when); }); std::list<NotifyArgs> InputDevice::timeoutExpired(nsecs_t when) { std::list<NotifyArgs> out; for_each_mapper([&](InputMapper& mapper) { out += mapper.timeoutExpired(when); }); return out; } void InputDevice::updateExternalStylusState(const StylusState& state) { for_each_mapper([state](InputMapper& mapper) { mapper.updateExternalStylusState(state); }); std::list<NotifyArgs> InputDevice::updateExternalStylusState(const StylusState& state) { std::list<NotifyArgs> out; for_each_mapper([&](InputMapper& mapper) { out += mapper.updateExternalStylusState(state); }); return out; } InputDeviceInfo InputDevice::getDeviceInfo() { Loading Loading @@ -511,14 +524,17 @@ int32_t InputDevice::getKeyCodeForKeyLocation(int32_t locationKeyCode) const { return *result; } void InputDevice::vibrate(const VibrationSequence& sequence, ssize_t repeat, int32_t token) { for_each_mapper([sequence, repeat, token](InputMapper& mapper) { mapper.vibrate(sequence, repeat, token); }); std::list<NotifyArgs> InputDevice::vibrate(const VibrationSequence& sequence, ssize_t repeat, int32_t token) { std::list<NotifyArgs> out; for_each_mapper([&](InputMapper& mapper) { out += mapper.vibrate(sequence, repeat, token); }); return out; } void InputDevice::cancelVibrate(int32_t token) { for_each_mapper([token](InputMapper& mapper) { mapper.cancelVibrate(token); }); std::list<NotifyArgs> InputDevice::cancelVibrate(int32_t token) { std::list<NotifyArgs> out; for_each_mapper([&](InputMapper& mapper) { out += mapper.cancelVibrate(token); }); return out; } bool InputDevice::isVibrating() { Loading Loading @@ -561,8 +577,10 @@ void InputDevice::flushSensor(InputDeviceSensorType sensorType) { for_each_mapper([sensorType](InputMapper& mapper) { mapper.flushSensor(sensorType); }); } void InputDevice::cancelTouch(nsecs_t when, nsecs_t readTime) { for_each_mapper([when, readTime](InputMapper& mapper) { mapper.cancelTouch(when, readTime); }); std::list<NotifyArgs> InputDevice::cancelTouch(nsecs_t when, nsecs_t readTime) { std::list<NotifyArgs> out; for_each_mapper([&](InputMapper& mapper) { out += mapper.cancelTouch(when, readTime); }); return out; } bool InputDevice::setLightColor(int32_t lightId, int32_t color) { Loading Loading @@ -601,9 +619,8 @@ void InputDevice::bumpGeneration() { mGeneration = mContext->bumpGeneration(); } void InputDevice::notifyReset(nsecs_t when) { NotifyDeviceResetArgs args(mContext->getNextId(), when, mId); mContext->getListener().notifyDeviceReset(&args); NotifyDeviceResetArgs InputDevice::notifyReset(nsecs_t when) { return NotifyDeviceResetArgs(mContext->getNextId(), when, mId); } std::optional<int32_t> InputDevice::getAssociatedDisplayId() { Loading Loading
services/inputflinger/InputListener.cpp +5 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,11 @@ using android::base::StringPrintf; namespace android { std::list<NotifyArgs>& operator+=(std::list<NotifyArgs>& keep, std::list<NotifyArgs>&& consume) { keep.splice(keep.end(), consume); return keep; } // --- InputListenerInterface --- // Helper to std::visit with lambdas. Loading
services/inputflinger/NotifyArgs.cpp +23 −0 Original line number Diff line number Diff line Loading @@ -225,4 +225,27 @@ NotifyPointerCaptureChangedArgs::NotifyPointerCaptureChangedArgs( int32_t id, nsecs_t eventTime, const PointerCaptureRequest& request) : id(id), eventTime(eventTime), request(request) {} // Helper to std::visit with lambdas. template <typename... V> struct Visitor : V... {}; // explicit deduction guide (not needed as of C++20) template <typename... V> Visitor(V...) -> Visitor<V...>; const char* toString(const NotifyArgs& args) { Visitor toStringVisitor{ [&](const NotifyConfigurationChangedArgs&) { return "NotifyConfigurationChangedArgs"; }, [&](const NotifyKeyArgs&) { return "NotifyKeyArgs"; }, [&](const NotifyMotionArgs&) { return "NotifyMotionArgs"; }, [&](const NotifySensorArgs&) { return "NotifySensorArgs"; }, [&](const NotifySwitchArgs&) { return "NotifySwitchArgs"; }, [&](const NotifyDeviceResetArgs&) { return "NotifyDeviceResetArgs"; }, [&](const NotifyPointerCaptureChangedArgs&) { return "NotifyPointerCaptureChangedArgs"; }, [&](const NotifyVibratorStateArgs&) { return "NotifyVibratorStateArgs"; }, }; return std::visit(toStringVisitor, args); } } // namespace android
services/inputflinger/include/InputListener.h +2 −0 Original line number Diff line number Diff line Loading @@ -25,6 +25,8 @@ namespace android { std::list<NotifyArgs>& operator+=(std::list<NotifyArgs>& keep, std::list<NotifyArgs>&& consume); /* * The interface used by the InputReader to notify the InputListener about input events. */ Loading
services/inputflinger/include/NotifyArgs.h +2 −0 Original line number Diff line number Diff line Loading @@ -213,4 +213,6 @@ using NotifyArgs = std::variant<NotifyConfigurationChangedArgs, NotifyKeyArgs, N NotifySensorArgs, NotifySwitchArgs, NotifyDeviceResetArgs, NotifyPointerCaptureChangedArgs, NotifyVibratorStateArgs>; const char* toString(const NotifyArgs& args); } // namespace android
services/inputflinger/reader/InputDevice.cpp +50 −33 Original line number Diff line number Diff line Loading @@ -65,7 +65,8 @@ bool InputDevice::isEnabled() { return enabled; } void InputDevice::setEnabled(bool enabled, nsecs_t when) { std::list<NotifyArgs> InputDevice::setEnabled(bool enabled, nsecs_t when) { std::list<NotifyArgs> out; if (enabled && mAssociatedDisplayPort && !mAssociatedViewport) { ALOGW("Cannot enable input device %s because it is associated with port %" PRIu8 ", " "but the corresponding viewport is not found", Loading @@ -74,7 +75,7 @@ void InputDevice::setEnabled(bool enabled, nsecs_t when) { } if (isEnabled() == enabled) { return; return out; } // When resetting some devices, the driver needs to be queried to ensure that a proper reset is Loading @@ -82,13 +83,14 @@ void InputDevice::setEnabled(bool enabled, nsecs_t when) { // but before disabling the device. See MultiTouchMotionAccumulator::reset for more information. if (enabled) { for_each_subdevice([](auto& context) { context.enableDevice(); }); reset(when); out += reset(when); } else { reset(when); out += reset(when); for_each_subdevice([](auto& context) { context.disableDevice(); }); } // Must change generation to flag this device as changed bumpGeneration(); return out; } void InputDevice::dump(std::string& dump, const std::string& eventHubDevStr) { Loading Loading @@ -241,8 +243,9 @@ void InputDevice::removeEventHubDevice(int32_t eventHubId) { mDevices.erase(eventHubId); } void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config, std::list<NotifyArgs> InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config, uint32_t changes) { std::list<NotifyArgs> out; mSources = 0; mClasses = ftl::Flags<InputDeviceClass>(0); mControllerNumber = 0; Loading Loading @@ -313,7 +316,7 @@ void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config if (!changes || (changes & InputReaderConfiguration::CHANGE_ENABLED_STATE)) { auto it = config->disabledDevices.find(mId); bool enabled = it == config->disabledDevices.end(); setEnabled(enabled, when); out += setEnabled(enabled, when); } if (!changes || (changes & InputReaderConfiguration::CHANGE_DISPLAY_INFO)) { Loading Loading @@ -366,37 +369,42 @@ void InputDevice::configure(nsecs_t when, const InputReaderConfiguration* config // For first-time configuration, only allow device to be disabled after mappers have // finished configuring. This is because we need to read some of the properties from // the device's open fd. setEnabled(enabled, when); out += setEnabled(enabled, when); } } for_each_mapper([this, when, config, changes](InputMapper& mapper) { mapper.configure(when, config, changes); for_each_mapper([this, when, &config, changes, &out](InputMapper& mapper) { out += mapper.configure(when, config, changes); mSources |= mapper.getSources(); }); // If a device is just plugged but it might be disabled, we need to update some info like // axis range of touch from each InputMapper first, then disable it. if (!changes) { setEnabled(config->disabledDevices.find(mId) == config->disabledDevices.end(), when); out += setEnabled(config->disabledDevices.find(mId) == config->disabledDevices.end(), when); } } return out; } void InputDevice::reset(nsecs_t when) { for_each_mapper([when](InputMapper& mapper) { mapper.reset(when); }); std::list<NotifyArgs> InputDevice::reset(nsecs_t when) { std::list<NotifyArgs> out; for_each_mapper([&](InputMapper& mapper) { out += mapper.reset(when); }); mContext->updateGlobalMetaState(); notifyReset(when); out.push_back(notifyReset(when)); return out; } void InputDevice::process(const RawEvent* rawEvents, size_t count) { std::list<NotifyArgs> InputDevice::process(const RawEvent* rawEvents, size_t count) { // Process all of the events in order for each mapper. // We cannot simply ask each mapper to process them in bulk because mappers may // have side-effects that must be interleaved. For example, joystick movement events and // gamepad button presses are handled by different mappers but they should be dispatched // in the order received. std::list<NotifyArgs> out; for (const RawEvent* rawEvent = rawEvents; count != 0; rawEvent++) { if (DEBUG_RAW_EVENTS) { ALOGD("Input event: device=%d type=0x%04x code=0x%04x value=0x%08x when=%" PRId64, Loading @@ -418,22 +426,27 @@ void InputDevice::process(const RawEvent* rawEvents, size_t count) { } else if (rawEvent->type == EV_SYN && rawEvent->code == SYN_DROPPED) { ALOGI("Detected input event buffer overrun for device %s.", getName().c_str()); mDropUntilNextSync = true; reset(rawEvent->when); out += reset(rawEvent->when); } else { for_each_mapper_in_subdevice(rawEvent->deviceId, [rawEvent](InputMapper& mapper) { mapper.process(rawEvent); for_each_mapper_in_subdevice(rawEvent->deviceId, [&](InputMapper& mapper) { out += mapper.process(rawEvent); }); } --count; } return out; } void InputDevice::timeoutExpired(nsecs_t when) { for_each_mapper([when](InputMapper& mapper) { mapper.timeoutExpired(when); }); std::list<NotifyArgs> InputDevice::timeoutExpired(nsecs_t when) { std::list<NotifyArgs> out; for_each_mapper([&](InputMapper& mapper) { out += mapper.timeoutExpired(when); }); return out; } void InputDevice::updateExternalStylusState(const StylusState& state) { for_each_mapper([state](InputMapper& mapper) { mapper.updateExternalStylusState(state); }); std::list<NotifyArgs> InputDevice::updateExternalStylusState(const StylusState& state) { std::list<NotifyArgs> out; for_each_mapper([&](InputMapper& mapper) { out += mapper.updateExternalStylusState(state); }); return out; } InputDeviceInfo InputDevice::getDeviceInfo() { Loading Loading @@ -511,14 +524,17 @@ int32_t InputDevice::getKeyCodeForKeyLocation(int32_t locationKeyCode) const { return *result; } void InputDevice::vibrate(const VibrationSequence& sequence, ssize_t repeat, int32_t token) { for_each_mapper([sequence, repeat, token](InputMapper& mapper) { mapper.vibrate(sequence, repeat, token); }); std::list<NotifyArgs> InputDevice::vibrate(const VibrationSequence& sequence, ssize_t repeat, int32_t token) { std::list<NotifyArgs> out; for_each_mapper([&](InputMapper& mapper) { out += mapper.vibrate(sequence, repeat, token); }); return out; } void InputDevice::cancelVibrate(int32_t token) { for_each_mapper([token](InputMapper& mapper) { mapper.cancelVibrate(token); }); std::list<NotifyArgs> InputDevice::cancelVibrate(int32_t token) { std::list<NotifyArgs> out; for_each_mapper([&](InputMapper& mapper) { out += mapper.cancelVibrate(token); }); return out; } bool InputDevice::isVibrating() { Loading Loading @@ -561,8 +577,10 @@ void InputDevice::flushSensor(InputDeviceSensorType sensorType) { for_each_mapper([sensorType](InputMapper& mapper) { mapper.flushSensor(sensorType); }); } void InputDevice::cancelTouch(nsecs_t when, nsecs_t readTime) { for_each_mapper([when, readTime](InputMapper& mapper) { mapper.cancelTouch(when, readTime); }); std::list<NotifyArgs> InputDevice::cancelTouch(nsecs_t when, nsecs_t readTime) { std::list<NotifyArgs> out; for_each_mapper([&](InputMapper& mapper) { out += mapper.cancelTouch(when, readTime); }); return out; } bool InputDevice::setLightColor(int32_t lightId, int32_t color) { Loading Loading @@ -601,9 +619,8 @@ void InputDevice::bumpGeneration() { mGeneration = mContext->bumpGeneration(); } void InputDevice::notifyReset(nsecs_t when) { NotifyDeviceResetArgs args(mContext->getNextId(), when, mId); mContext->getListener().notifyDeviceReset(&args); NotifyDeviceResetArgs InputDevice::notifyReset(nsecs_t when) { return NotifyDeviceResetArgs(mContext->getNextId(), when, mId); } std::optional<int32_t> InputDevice::getAssociatedDisplayId() { Loading