Loading services/inputflinger/VibrationElement.cpp +82 −5 Original line number Diff line number Diff line Loading @@ -24,13 +24,28 @@ using android::base::StringPrintf; namespace android { // VibrationElement implementations VibrationElement::VibrationElement(size_t channelNum) { channels.reserve(channelNum); } VibrationElement::VibrationElement(const VibrationElement& other) { duration = other.duration; channels.resize(other.channels.size()); for (size_t i = 0; i < other.channels.size(); i++) { channels[i].first = other.channels[i].first; channels[i].second = other.channels[i].second; } } const std::string VibrationElement::toString() const { std::string dump; dump += StringPrintf("[duration=%lldms, channels=[", duration.count()); for (auto it = channels.begin(); it != channels.end(); ++it) { dump += std::to_string(*it); dump += std::to_string(it->first); dump += " : "; dump += std::to_string(it->second); if (std::next(it) != channels.end()) { dump += ", "; } Loading @@ -40,17 +55,79 @@ const std::string VibrationElement::toString() const { return dump; } uint16_t VibrationElement::getMagnitude(size_t channelIdx) const { if (channelIdx >= channels.size()) { uint16_t VibrationElement::getMagnitude(int32_t vibratorId) const { auto it = std::find_if(channels.begin(), channels.end(), [vibratorId](const std::pair<int32_t /*vibratorId*/, uint8_t /*amplitude*/> pair) { return pair.first == vibratorId; }); if (it == channels.end()) { return 0; } // convert range [0,255] to [0,65535] (android framework to linux ff ranges) return static_cast<uint16_t>(channels[channelIdx]) << 8; return static_cast<uint16_t>(it->second) << 8; } bool VibrationElement::isOn() const { return std::any_of(channels.begin(), channels.end(), [](uint16_t channel) { return channel != 0; }); [](const auto& channel) { return channel.second != 0; }); } void VibrationElement::addChannel(int32_t vibratorId, uint8_t amplitude) { channels.push_back(std::make_pair(vibratorId, amplitude)); } bool VibrationElement::operator==(const VibrationElement& other) const { if (duration != other.duration || channels.size() != other.channels.size()) { return false; } for (size_t i = 0; i < CHANNEL_SIZE; i++) { if (channels[i] != other.channels[i]) { return false; } } return true; } bool VibrationElement::operator!=(const VibrationElement& other) const { return !(*this == other); } // VibrationSequence implementations VibrationSequence::VibrationSequence(size_t length) { pattern.reserve(length); } void VibrationSequence::operator=(const VibrationSequence& other) { pattern = other.pattern; } bool VibrationSequence::operator==(const VibrationSequence& other) const { if (pattern.size() != other.pattern.size()) { return false; } for (size_t i = 0; i < pattern.size(); i++) { if (pattern[i] != other.pattern[i]) { return false; } } return true; } void VibrationSequence::addElement(VibrationElement element) { pattern.push_back(element); } const std::string VibrationSequence::toString() const { std::string dump; dump += "["; for (const auto& element : pattern) { dump += element.toString(); dump += " "; } dump += "]"; return dump; } } // namespace android services/inputflinger/include/InputReaderBase.h +6 −2 Original line number Diff line number Diff line Loading @@ -101,10 +101,14 @@ public: virtual void requestRefreshConfiguration(uint32_t changes) = 0; /* Controls the vibrator of a particular input device. */ virtual void vibrate(int32_t deviceId, const std::vector<VibrationElement>& pattern, ssize_t repeat, int32_t token) = 0; virtual void vibrate(int32_t deviceId, const VibrationSequence& sequence, ssize_t repeat, int32_t token) = 0; virtual void cancelVibrate(int32_t deviceId, int32_t token) = 0; virtual bool isVibrating(int32_t deviceId) = 0; virtual std::vector<int32_t> getVibratorIds(int32_t deviceId) = 0; /* Return true if the device can send input events to the specified display. */ virtual bool canDispatchToDisplay(int32_t deviceId, int32_t displayId) = 0; }; Loading services/inputflinger/include/VibrationElement.h +33 −2 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <chrono> #include <cstdint> #include <string> #include <vector> namespace android { Loading @@ -32,13 +33,43 @@ constexpr size_t CHANNEL_SIZE = 2; struct VibrationElement { std::chrono::milliseconds duration; // Channel amplitude range 0-255. std::array<uint8_t, CHANNEL_SIZE> channels = {0, 0}; std::vector<std::pair<int32_t /*vibratorId*/, uint8_t /*amplitude*/>> channels; explicit VibrationElement(size_t channelNum); VibrationElement(const VibrationElement& other); bool operator==(const VibrationElement& other) const; bool operator!=(const VibrationElement& other) const; void addChannel(int32_t vibratorId, uint8_t amplitude); const std::string toString() const; uint16_t getMagnitude(size_t channelIndex) const; uint16_t getMagnitude(int32_t vibratorId) const; bool isOn() const; }; /* * Describes a sequence of rumble effect */ struct VibrationSequence { // Pattern of vibration elements std::vector<VibrationElement> pattern; explicit VibrationSequence(size_t length); void operator=(const VibrationSequence& other); bool operator==(const VibrationSequence& other) const; void addElement(VibrationElement element); const std::string toString() const; }; } // namespace android #endif // _VIBRATION_ELEMENT_H services/inputflinger/reader/EventHub.cpp +44 −32 Original line number Diff line number Diff line Loading @@ -61,8 +61,8 @@ static const char* DEVICE_PATH = "/dev/input"; // v4l2 devices go directly into /dev static const char* VIDEO_DEVICE_PATH = "/dev"; static constexpr size_t FF_STRONG_MAGNITUDE_CHANNEL_IDX = 0; static constexpr size_t FF_WEAK_MAGNITUDE_CHANNEL_IDX = 1; static constexpr int32_t FF_STRONG_MAGNITUDE_CHANNEL_IDX = 0; static constexpr int32_t FF_WEAK_MAGNITUDE_CHANNEL_IDX = 1; static inline const char* toString(bool value) { return value ? "true" : "false"; Loading Loading @@ -475,25 +475,25 @@ EventHub::~EventHub(void) { } InputDeviceIdentifier EventHub::getDeviceIdentifier(int32_t deviceId) const { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); return device != nullptr ? device->identifier : InputDeviceIdentifier(); } Flags<InputDeviceClass> EventHub::getDeviceClasses(int32_t deviceId) const { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); return device != nullptr ? device->classes : Flags<InputDeviceClass>(0); } int32_t EventHub::getDeviceControllerNumber(int32_t deviceId) const { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); return device != nullptr ? device->controllerNumber : 0; } void EventHub::getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && device->configuration) { *outConfiguration = *device->configuration; Loading @@ -507,7 +507,7 @@ status_t EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis, outAxisInfo->clear(); if (axis >= 0 && axis <= ABS_MAX) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && device->hasValidFd() && device->absBitmask.test(axis)) { Loading @@ -534,7 +534,7 @@ status_t EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis, bool EventHub::hasRelativeAxis(int32_t deviceId, int axis) const { if (axis >= 0 && axis <= REL_MAX) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); return device != nullptr ? device->relBitmask.test(axis) : false; } Loading @@ -542,7 +542,7 @@ bool EventHub::hasRelativeAxis(int32_t deviceId, int axis) const { } bool EventHub::hasInputProperty(int32_t deviceId, int property) const { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); return property >= 0 && property <= INPUT_PROP_MAX && device != nullptr Loading @@ -552,7 +552,7 @@ bool EventHub::hasInputProperty(int32_t deviceId, int property) const { int32_t EventHub::getScanCodeState(int32_t deviceId, int32_t scanCode) const { if (scanCode >= 0 && scanCode <= KEY_MAX) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && device->hasValidFd() && device->keyBitmask.test(scanCode)) { Loading @@ -565,7 +565,7 @@ int32_t EventHub::getScanCodeState(int32_t deviceId, int32_t scanCode) const { } int32_t EventHub::getKeyCodeState(int32_t deviceId, int32_t keyCode) const { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && device->hasValidFd() && device->keyMap.haveKeyLayout()) { Loading @@ -588,7 +588,7 @@ int32_t EventHub::getKeyCodeState(int32_t deviceId, int32_t keyCode) const { int32_t EventHub::getSwitchState(int32_t deviceId, int32_t sw) const { if (sw >= 0 && sw <= SW_MAX) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && device->hasValidFd() && device->swBitmask.test(sw)) { Loading @@ -604,7 +604,7 @@ status_t EventHub::getAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t* *outValue = 0; if (axis >= 0 && axis <= ABS_MAX) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && device->hasValidFd() && device->absBitmask.test(axis)) { Loading @@ -624,7 +624,7 @@ status_t EventHub::getAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t* bool EventHub::markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && device->keyMap.haveKeyLayout()) { Loading Loading @@ -652,7 +652,7 @@ bool EventHub::markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const in status_t EventHub::mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, int32_t metaState, int32_t* outKeycode, int32_t* outMetaState, uint32_t* outFlags) const { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); status_t status = NAME_NOT_FOUND; Loading Loading @@ -692,7 +692,7 @@ status_t EventHub::mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, } status_t EventHub::mapAxis(int32_t deviceId, int32_t scanCode, AxisInfo* outAxisInfo) const { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && device->keyMap.haveKeyLayout()) { Loading @@ -706,13 +706,13 @@ status_t EventHub::mapAxis(int32_t deviceId, int32_t scanCode, AxisInfo* outAxis } void EventHub::setExcludedDevices(const std::vector<std::string>& devices) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); mExcludedDevices = devices; } bool EventHub::hasScanCode(int32_t deviceId, int32_t scanCode) const { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && scanCode >= 0 && scanCode <= KEY_MAX) { return device->keyBitmask.test(scanCode); Loading @@ -721,7 +721,7 @@ bool EventHub::hasScanCode(int32_t deviceId, int32_t scanCode) const { } bool EventHub::hasLed(int32_t deviceId, int32_t led) const { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); int32_t sc; if (device != nullptr && device->mapLed(led, &sc) == NO_ERROR) { Loading @@ -731,7 +731,7 @@ bool EventHub::hasLed(int32_t deviceId, int32_t led) const { } void EventHub::setLedState(int32_t deviceId, int32_t led, bool on) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && device->hasValidFd()) { device->setLedStateLocked(led, on); Loading @@ -742,7 +742,7 @@ void EventHub::getVirtualKeyDefinitions(int32_t deviceId, std::vector<VirtualKeyDefinition>& outVirtualKeys) const { outVirtualKeys.clear(); std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && device->virtualKeyMap) { const std::vector<VirtualKeyDefinition> virtualKeys = Loading @@ -752,7 +752,7 @@ void EventHub::getVirtualKeyDefinitions(int32_t deviceId, } const std::shared_ptr<KeyCharacterMap> EventHub::getKeyCharacterMap(int32_t deviceId) const { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr) { return device->getKeyCharacterMap(); Loading @@ -761,7 +761,7 @@ const std::shared_ptr<KeyCharacterMap> EventHub::getKeyCharacterMap(int32_t devi } bool EventHub::setKeyboardLayoutOverlay(int32_t deviceId, std::shared_ptr<KeyCharacterMap> map) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && map != nullptr && device->keyMap.keyCharacterMap != nullptr) { device->keyMap.keyCharacterMap->combine(*map); Loading Loading @@ -822,7 +822,7 @@ void EventHub::assignDescriptorLocked(InputDeviceIdentifier& identifier) { } void EventHub::vibrate(int32_t deviceId, const VibrationElement& element) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && device->hasValidFd()) { ff_effect effect; Loading Loading @@ -857,7 +857,7 @@ void EventHub::vibrate(int32_t deviceId, const VibrationElement& element) { } void EventHub::cancelVibrate(int32_t deviceId) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && device->hasValidFd()) { if (device->ffEffectPlaying) { Loading @@ -878,6 +878,18 @@ void EventHub::cancelVibrate(int32_t deviceId) { } } std::vector<int32_t> EventHub::getVibratorIds(int32_t deviceId) { std::scoped_lock _l(mLock); std::vector<int32_t> vibrators; Device* device = getDeviceLocked(deviceId); if (device != nullptr && device->hasValidFd() && device->classes.test(InputDeviceClass::VIBRATOR)) { vibrators.push_back(FF_STRONG_MAGNITUDE_CHANNEL_IDX); vibrators.push_back(FF_WEAK_MAGNITUDE_CHANNEL_IDX); } return vibrators; } EventHub::Device* EventHub::getDeviceByDescriptorLocked(const std::string& descriptor) const { for (const auto& [id, device] : mDevices) { if (descriptor == device->identifier.descriptor) { Loading Loading @@ -930,7 +942,7 @@ EventHub::Device* EventHub::getDeviceByFdLocked(int fd) const { size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) { ALOG_ASSERT(bufferSize >= 1); std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); struct input_event readBuffer[bufferSize]; Loading Loading @@ -1184,7 +1196,7 @@ size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSiz } std::vector<TouchVideoFrame> EventHub::getVideoFrames(int32_t deviceId) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device == nullptr || !device->videoDevice) { Loading Loading @@ -1593,7 +1605,7 @@ bool EventHub::tryAddVideoDevice(EventHub::Device& device, } bool EventHub::isDeviceEnabled(int32_t deviceId) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device == nullptr) { ALOGE("Invalid device id=%" PRId32 " provided to %s", deviceId, __func__); Loading @@ -1603,7 +1615,7 @@ bool EventHub::isDeviceEnabled(int32_t deviceId) { } status_t EventHub::enableDevice(int32_t deviceId) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device == nullptr) { ALOGE("Invalid device id=%" PRId32 " provided to %s", deviceId, __func__); Loading @@ -1625,7 +1637,7 @@ status_t EventHub::enableDevice(int32_t deviceId) { } status_t EventHub::disableDevice(int32_t deviceId) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device == nullptr) { ALOGE("Invalid device id=%" PRId32 " provided to %s", deviceId, __func__); Loading Loading @@ -1809,7 +1821,7 @@ status_t EventHub::scanVideoDirLocked(const std::string& dirname) { void EventHub::requestReopenDevices() { ALOGV("requestReopenDevices() called"); std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); mNeedToReopenDevices = true; } Loading @@ -1817,7 +1829,7 @@ void EventHub::dump(std::string& dump) { dump += "Event Hub State:\n"; { // acquire lock std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); dump += StringPrintf(INDENT "BuiltInKeyboardId: %d\n", mBuiltInKeyboardId); Loading services/inputflinger/reader/InputDevice.cpp +24 −4 Original line number Diff line number Diff line Loading @@ -429,10 +429,9 @@ bool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes, return result; } void InputDevice::vibrate(const std::vector<VibrationElement>& pattern, ssize_t repeat, int32_t token) { for_each_mapper([pattern, repeat, token](InputMapper& mapper) { mapper.vibrate(pattern, repeat, token); 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); }); } Loading @@ -440,6 +439,27 @@ void InputDevice::cancelVibrate(int32_t token) { for_each_mapper([token](InputMapper& mapper) { mapper.cancelVibrate(token); }); } bool InputDevice::isVibrating() { bool vibrating = false; for_each_mapper([&vibrating](InputMapper& mapper) { vibrating |= mapper.isVibrating(); }); return vibrating; } /* There's no guarantee the IDs provided by the different mappers are unique, so if we have two * different vibration mappers then we could have duplicate IDs. * Alternatively, if we have a merged device that has multiple evdev nodes with FF_* capabilities, * we would definitely have duplicate IDs. */ std::vector<int32_t> InputDevice::getVibratorIds() { std::vector<int32_t> vibrators; for_each_mapper([&vibrators](InputMapper& mapper) { std::vector<int32_t> devVibs = mapper.getVibratorIds(); vibrators.reserve(vibrators.size() + devVibs.size()); vibrators.insert(vibrators.end(), devVibs.begin(), devVibs.end()); }); return vibrators; } void InputDevice::cancelTouch(nsecs_t when) { for_each_mapper([when](InputMapper& mapper) { mapper.cancelTouch(when); }); } Loading Loading
services/inputflinger/VibrationElement.cpp +82 −5 Original line number Diff line number Diff line Loading @@ -24,13 +24,28 @@ using android::base::StringPrintf; namespace android { // VibrationElement implementations VibrationElement::VibrationElement(size_t channelNum) { channels.reserve(channelNum); } VibrationElement::VibrationElement(const VibrationElement& other) { duration = other.duration; channels.resize(other.channels.size()); for (size_t i = 0; i < other.channels.size(); i++) { channels[i].first = other.channels[i].first; channels[i].second = other.channels[i].second; } } const std::string VibrationElement::toString() const { std::string dump; dump += StringPrintf("[duration=%lldms, channels=[", duration.count()); for (auto it = channels.begin(); it != channels.end(); ++it) { dump += std::to_string(*it); dump += std::to_string(it->first); dump += " : "; dump += std::to_string(it->second); if (std::next(it) != channels.end()) { dump += ", "; } Loading @@ -40,17 +55,79 @@ const std::string VibrationElement::toString() const { return dump; } uint16_t VibrationElement::getMagnitude(size_t channelIdx) const { if (channelIdx >= channels.size()) { uint16_t VibrationElement::getMagnitude(int32_t vibratorId) const { auto it = std::find_if(channels.begin(), channels.end(), [vibratorId](const std::pair<int32_t /*vibratorId*/, uint8_t /*amplitude*/> pair) { return pair.first == vibratorId; }); if (it == channels.end()) { return 0; } // convert range [0,255] to [0,65535] (android framework to linux ff ranges) return static_cast<uint16_t>(channels[channelIdx]) << 8; return static_cast<uint16_t>(it->second) << 8; } bool VibrationElement::isOn() const { return std::any_of(channels.begin(), channels.end(), [](uint16_t channel) { return channel != 0; }); [](const auto& channel) { return channel.second != 0; }); } void VibrationElement::addChannel(int32_t vibratorId, uint8_t amplitude) { channels.push_back(std::make_pair(vibratorId, amplitude)); } bool VibrationElement::operator==(const VibrationElement& other) const { if (duration != other.duration || channels.size() != other.channels.size()) { return false; } for (size_t i = 0; i < CHANNEL_SIZE; i++) { if (channels[i] != other.channels[i]) { return false; } } return true; } bool VibrationElement::operator!=(const VibrationElement& other) const { return !(*this == other); } // VibrationSequence implementations VibrationSequence::VibrationSequence(size_t length) { pattern.reserve(length); } void VibrationSequence::operator=(const VibrationSequence& other) { pattern = other.pattern; } bool VibrationSequence::operator==(const VibrationSequence& other) const { if (pattern.size() != other.pattern.size()) { return false; } for (size_t i = 0; i < pattern.size(); i++) { if (pattern[i] != other.pattern[i]) { return false; } } return true; } void VibrationSequence::addElement(VibrationElement element) { pattern.push_back(element); } const std::string VibrationSequence::toString() const { std::string dump; dump += "["; for (const auto& element : pattern) { dump += element.toString(); dump += " "; } dump += "]"; return dump; } } // namespace android
services/inputflinger/include/InputReaderBase.h +6 −2 Original line number Diff line number Diff line Loading @@ -101,10 +101,14 @@ public: virtual void requestRefreshConfiguration(uint32_t changes) = 0; /* Controls the vibrator of a particular input device. */ virtual void vibrate(int32_t deviceId, const std::vector<VibrationElement>& pattern, ssize_t repeat, int32_t token) = 0; virtual void vibrate(int32_t deviceId, const VibrationSequence& sequence, ssize_t repeat, int32_t token) = 0; virtual void cancelVibrate(int32_t deviceId, int32_t token) = 0; virtual bool isVibrating(int32_t deviceId) = 0; virtual std::vector<int32_t> getVibratorIds(int32_t deviceId) = 0; /* Return true if the device can send input events to the specified display. */ virtual bool canDispatchToDisplay(int32_t deviceId, int32_t displayId) = 0; }; Loading
services/inputflinger/include/VibrationElement.h +33 −2 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ #include <chrono> #include <cstdint> #include <string> #include <vector> namespace android { Loading @@ -32,13 +33,43 @@ constexpr size_t CHANNEL_SIZE = 2; struct VibrationElement { std::chrono::milliseconds duration; // Channel amplitude range 0-255. std::array<uint8_t, CHANNEL_SIZE> channels = {0, 0}; std::vector<std::pair<int32_t /*vibratorId*/, uint8_t /*amplitude*/>> channels; explicit VibrationElement(size_t channelNum); VibrationElement(const VibrationElement& other); bool operator==(const VibrationElement& other) const; bool operator!=(const VibrationElement& other) const; void addChannel(int32_t vibratorId, uint8_t amplitude); const std::string toString() const; uint16_t getMagnitude(size_t channelIndex) const; uint16_t getMagnitude(int32_t vibratorId) const; bool isOn() const; }; /* * Describes a sequence of rumble effect */ struct VibrationSequence { // Pattern of vibration elements std::vector<VibrationElement> pattern; explicit VibrationSequence(size_t length); void operator=(const VibrationSequence& other); bool operator==(const VibrationSequence& other) const; void addElement(VibrationElement element); const std::string toString() const; }; } // namespace android #endif // _VIBRATION_ELEMENT_H
services/inputflinger/reader/EventHub.cpp +44 −32 Original line number Diff line number Diff line Loading @@ -61,8 +61,8 @@ static const char* DEVICE_PATH = "/dev/input"; // v4l2 devices go directly into /dev static const char* VIDEO_DEVICE_PATH = "/dev"; static constexpr size_t FF_STRONG_MAGNITUDE_CHANNEL_IDX = 0; static constexpr size_t FF_WEAK_MAGNITUDE_CHANNEL_IDX = 1; static constexpr int32_t FF_STRONG_MAGNITUDE_CHANNEL_IDX = 0; static constexpr int32_t FF_WEAK_MAGNITUDE_CHANNEL_IDX = 1; static inline const char* toString(bool value) { return value ? "true" : "false"; Loading Loading @@ -475,25 +475,25 @@ EventHub::~EventHub(void) { } InputDeviceIdentifier EventHub::getDeviceIdentifier(int32_t deviceId) const { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); return device != nullptr ? device->identifier : InputDeviceIdentifier(); } Flags<InputDeviceClass> EventHub::getDeviceClasses(int32_t deviceId) const { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); return device != nullptr ? device->classes : Flags<InputDeviceClass>(0); } int32_t EventHub::getDeviceControllerNumber(int32_t deviceId) const { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); return device != nullptr ? device->controllerNumber : 0; } void EventHub::getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && device->configuration) { *outConfiguration = *device->configuration; Loading @@ -507,7 +507,7 @@ status_t EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis, outAxisInfo->clear(); if (axis >= 0 && axis <= ABS_MAX) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && device->hasValidFd() && device->absBitmask.test(axis)) { Loading @@ -534,7 +534,7 @@ status_t EventHub::getAbsoluteAxisInfo(int32_t deviceId, int axis, bool EventHub::hasRelativeAxis(int32_t deviceId, int axis) const { if (axis >= 0 && axis <= REL_MAX) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); return device != nullptr ? device->relBitmask.test(axis) : false; } Loading @@ -542,7 +542,7 @@ bool EventHub::hasRelativeAxis(int32_t deviceId, int axis) const { } bool EventHub::hasInputProperty(int32_t deviceId, int property) const { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); return property >= 0 && property <= INPUT_PROP_MAX && device != nullptr Loading @@ -552,7 +552,7 @@ bool EventHub::hasInputProperty(int32_t deviceId, int property) const { int32_t EventHub::getScanCodeState(int32_t deviceId, int32_t scanCode) const { if (scanCode >= 0 && scanCode <= KEY_MAX) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && device->hasValidFd() && device->keyBitmask.test(scanCode)) { Loading @@ -565,7 +565,7 @@ int32_t EventHub::getScanCodeState(int32_t deviceId, int32_t scanCode) const { } int32_t EventHub::getKeyCodeState(int32_t deviceId, int32_t keyCode) const { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && device->hasValidFd() && device->keyMap.haveKeyLayout()) { Loading @@ -588,7 +588,7 @@ int32_t EventHub::getKeyCodeState(int32_t deviceId, int32_t keyCode) const { int32_t EventHub::getSwitchState(int32_t deviceId, int32_t sw) const { if (sw >= 0 && sw <= SW_MAX) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && device->hasValidFd() && device->swBitmask.test(sw)) { Loading @@ -604,7 +604,7 @@ status_t EventHub::getAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t* *outValue = 0; if (axis >= 0 && axis <= ABS_MAX) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && device->hasValidFd() && device->absBitmask.test(axis)) { Loading @@ -624,7 +624,7 @@ status_t EventHub::getAbsoluteAxisValue(int32_t deviceId, int32_t axis, int32_t* bool EventHub::markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes, uint8_t* outFlags) const { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && device->keyMap.haveKeyLayout()) { Loading Loading @@ -652,7 +652,7 @@ bool EventHub::markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const in status_t EventHub::mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, int32_t metaState, int32_t* outKeycode, int32_t* outMetaState, uint32_t* outFlags) const { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); status_t status = NAME_NOT_FOUND; Loading Loading @@ -692,7 +692,7 @@ status_t EventHub::mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, } status_t EventHub::mapAxis(int32_t deviceId, int32_t scanCode, AxisInfo* outAxisInfo) const { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && device->keyMap.haveKeyLayout()) { Loading @@ -706,13 +706,13 @@ status_t EventHub::mapAxis(int32_t deviceId, int32_t scanCode, AxisInfo* outAxis } void EventHub::setExcludedDevices(const std::vector<std::string>& devices) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); mExcludedDevices = devices; } bool EventHub::hasScanCode(int32_t deviceId, int32_t scanCode) const { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && scanCode >= 0 && scanCode <= KEY_MAX) { return device->keyBitmask.test(scanCode); Loading @@ -721,7 +721,7 @@ bool EventHub::hasScanCode(int32_t deviceId, int32_t scanCode) const { } bool EventHub::hasLed(int32_t deviceId, int32_t led) const { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); int32_t sc; if (device != nullptr && device->mapLed(led, &sc) == NO_ERROR) { Loading @@ -731,7 +731,7 @@ bool EventHub::hasLed(int32_t deviceId, int32_t led) const { } void EventHub::setLedState(int32_t deviceId, int32_t led, bool on) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && device->hasValidFd()) { device->setLedStateLocked(led, on); Loading @@ -742,7 +742,7 @@ void EventHub::getVirtualKeyDefinitions(int32_t deviceId, std::vector<VirtualKeyDefinition>& outVirtualKeys) const { outVirtualKeys.clear(); std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && device->virtualKeyMap) { const std::vector<VirtualKeyDefinition> virtualKeys = Loading @@ -752,7 +752,7 @@ void EventHub::getVirtualKeyDefinitions(int32_t deviceId, } const std::shared_ptr<KeyCharacterMap> EventHub::getKeyCharacterMap(int32_t deviceId) const { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr) { return device->getKeyCharacterMap(); Loading @@ -761,7 +761,7 @@ const std::shared_ptr<KeyCharacterMap> EventHub::getKeyCharacterMap(int32_t devi } bool EventHub::setKeyboardLayoutOverlay(int32_t deviceId, std::shared_ptr<KeyCharacterMap> map) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && map != nullptr && device->keyMap.keyCharacterMap != nullptr) { device->keyMap.keyCharacterMap->combine(*map); Loading Loading @@ -822,7 +822,7 @@ void EventHub::assignDescriptorLocked(InputDeviceIdentifier& identifier) { } void EventHub::vibrate(int32_t deviceId, const VibrationElement& element) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && device->hasValidFd()) { ff_effect effect; Loading Loading @@ -857,7 +857,7 @@ void EventHub::vibrate(int32_t deviceId, const VibrationElement& element) { } void EventHub::cancelVibrate(int32_t deviceId) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device != nullptr && device->hasValidFd()) { if (device->ffEffectPlaying) { Loading @@ -878,6 +878,18 @@ void EventHub::cancelVibrate(int32_t deviceId) { } } std::vector<int32_t> EventHub::getVibratorIds(int32_t deviceId) { std::scoped_lock _l(mLock); std::vector<int32_t> vibrators; Device* device = getDeviceLocked(deviceId); if (device != nullptr && device->hasValidFd() && device->classes.test(InputDeviceClass::VIBRATOR)) { vibrators.push_back(FF_STRONG_MAGNITUDE_CHANNEL_IDX); vibrators.push_back(FF_WEAK_MAGNITUDE_CHANNEL_IDX); } return vibrators; } EventHub::Device* EventHub::getDeviceByDescriptorLocked(const std::string& descriptor) const { for (const auto& [id, device] : mDevices) { if (descriptor == device->identifier.descriptor) { Loading Loading @@ -930,7 +942,7 @@ EventHub::Device* EventHub::getDeviceByFdLocked(int fd) const { size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) { ALOG_ASSERT(bufferSize >= 1); std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); struct input_event readBuffer[bufferSize]; Loading Loading @@ -1184,7 +1196,7 @@ size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSiz } std::vector<TouchVideoFrame> EventHub::getVideoFrames(int32_t deviceId) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device == nullptr || !device->videoDevice) { Loading Loading @@ -1593,7 +1605,7 @@ bool EventHub::tryAddVideoDevice(EventHub::Device& device, } bool EventHub::isDeviceEnabled(int32_t deviceId) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device == nullptr) { ALOGE("Invalid device id=%" PRId32 " provided to %s", deviceId, __func__); Loading @@ -1603,7 +1615,7 @@ bool EventHub::isDeviceEnabled(int32_t deviceId) { } status_t EventHub::enableDevice(int32_t deviceId) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device == nullptr) { ALOGE("Invalid device id=%" PRId32 " provided to %s", deviceId, __func__); Loading @@ -1625,7 +1637,7 @@ status_t EventHub::enableDevice(int32_t deviceId) { } status_t EventHub::disableDevice(int32_t deviceId) { std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); Device* device = getDeviceLocked(deviceId); if (device == nullptr) { ALOGE("Invalid device id=%" PRId32 " provided to %s", deviceId, __func__); Loading Loading @@ -1809,7 +1821,7 @@ status_t EventHub::scanVideoDirLocked(const std::string& dirname) { void EventHub::requestReopenDevices() { ALOGV("requestReopenDevices() called"); std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); mNeedToReopenDevices = true; } Loading @@ -1817,7 +1829,7 @@ void EventHub::dump(std::string& dump) { dump += "Event Hub State:\n"; { // acquire lock std::lock_guard<std::mutex> lock(mLock); std::scoped_lock _l(mLock); dump += StringPrintf(INDENT "BuiltInKeyboardId: %d\n", mBuiltInKeyboardId); Loading
services/inputflinger/reader/InputDevice.cpp +24 −4 Original line number Diff line number Diff line Loading @@ -429,10 +429,9 @@ bool InputDevice::markSupportedKeyCodes(uint32_t sourceMask, size_t numCodes, return result; } void InputDevice::vibrate(const std::vector<VibrationElement>& pattern, ssize_t repeat, int32_t token) { for_each_mapper([pattern, repeat, token](InputMapper& mapper) { mapper.vibrate(pattern, repeat, token); 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); }); } Loading @@ -440,6 +439,27 @@ void InputDevice::cancelVibrate(int32_t token) { for_each_mapper([token](InputMapper& mapper) { mapper.cancelVibrate(token); }); } bool InputDevice::isVibrating() { bool vibrating = false; for_each_mapper([&vibrating](InputMapper& mapper) { vibrating |= mapper.isVibrating(); }); return vibrating; } /* There's no guarantee the IDs provided by the different mappers are unique, so if we have two * different vibration mappers then we could have duplicate IDs. * Alternatively, if we have a merged device that has multiple evdev nodes with FF_* capabilities, * we would definitely have duplicate IDs. */ std::vector<int32_t> InputDevice::getVibratorIds() { std::vector<int32_t> vibrators; for_each_mapper([&vibrators](InputMapper& mapper) { std::vector<int32_t> devVibs = mapper.getVibratorIds(); vibrators.reserve(vibrators.size() + devVibs.size()); vibrators.insert(vibrators.end(), devVibs.begin(), devVibs.end()); }); return vibrators; } void InputDevice::cancelTouch(nsecs_t when) { for_each_mapper([when](InputMapper& mapper) { mapper.cancelTouch(when); }); } Loading