From 74b6ea965500858c863792ed12984968f43bab43 Mon Sep 17 00:00:00 2001 From: hwzhangchuang Date: Sun, 12 Nov 2023 23:16:10 +0800 Subject: [PATCH 1/5] modify the problem of mouse jump while using touchpad Signed-off-by: hwzhangchuang --- common/include/constants_dinput.h | 20 +- common/include/input_hub.cpp | 306 +++++++++++++++--- common/include/input_hub.h | 87 +++-- distributedinput.gni | 2 + inputdevicehandler/BUILD.gn | 2 + .../test/inputhandlertest/BUILD.gn | 1 + services/sink/inputcollector/BUILD.gn | 2 + .../include/distributed_input_collector.h | 4 + .../src/distributed_input_collector.cpp | 13 +- .../test/sinkcollectorunittest/BUILD.gn | 1 + .../src/distributed_input_sink_manager.cpp | 3 + .../test/sinkmanagerunittest/BUILD.gn | 1 + .../distributed_input_sink_transport.h | 5 +- .../src/distributed_input_sink_transport.cpp | 31 +- services/source/inputinject/BUILD.gn | 3 +- .../include/distributed_input_inject.h | 3 - .../include/distributed_input_node_manager.h | 5 - .../src/distributed_input_inject.cpp | 20 -- .../src/distributed_input_node_manager.cpp | 61 +--- .../test/sourceinjectunittest/BUILD.gn | 1 + services/source/sourcemanager/BUILD.gn | 2 - .../distributed_input_source_manager.h | 2 - .../src/dinput_source_listener.cpp | 1 - .../src/distributed_input_source_manager.cpp | 13 - .../test/sourcemanagerunittest/BUILD.gn | 2 + services/source/transport/BUILD.gn | 2 - .../distributed_input_source_transport.h | 2 +- .../distributed_input_source_transport.cpp | 17 +- services/state/BUILD.gn | 2 - services/state/include/dinput_state.h | 47 ++- services/state/src/dinput_state.cpp | 269 +++++++-------- services/transportbase/BUILD.gn | 2 - .../src/distributed_input_transport_base.cpp | 4 +- utils/include/dinput_utils_tool.h | 9 + utils/src/dinput_utils_tool.cpp | 88 ++++- 35 files changed, 676 insertions(+), 357 deletions(-) diff --git a/common/include/constants_dinput.h b/common/include/constants_dinput.h index 34d7ed1..d7bc53d 100644 --- a/common/include/constants_dinput.h +++ b/common/include/constants_dinput.h @@ -39,8 +39,7 @@ namespace DistributedInput { const char INPUT_STRING_SPLIT_POINT = '.'; const uint32_t KEY_DOWN_STATE = 1; const uint32_t KEY_UP_STATE = 0; - const uint32_t KEY_LONGPRESS_STATE = 2; - const uint32_t KEY_OTHER_TYPE = 5; + const uint32_t KEY_REPEAT = 2; const uint32_t READ_SLEEP_TIME_MS = 50; const uint32_t READ_RETRY_MAX = 5; const uint32_t DH_ID_LENGTH_MAX = 256; @@ -49,6 +48,7 @@ namespace DistributedInput { const uint32_t SCREEN_MSG_MAX = 40 * 1024 * 1024; const uint32_t AUTH_SESSION_SIDE_SERVER = 0; const uint32_t IPC_VECTOR_MAX_SIZE = 32; + const uint32_t SIM_TOUCH_TRACKING_ID = 0x0001; /* * Device Type definitions @@ -243,6 +243,12 @@ namespace DistributedInput { int32_t value; std::string descriptor; std::string path; + + bool operator == (const RawEvent &e) + { + return this->type == e.type && this->code == e.code && + this->descriptor == e.descriptor && this->path == e.path; + } }; /* @@ -337,16 +343,6 @@ namespace DistributedInput { OPENED = 0x02, CLOSING = 0x03, }; - - /* - * This enumeration class represents the two states of the peropheral: - * THROUGH_IN : The state indicates the peripheral takes effect on the local device. - * THROUGH_OUT : The state indicates that the peripheral takes effect at the remote device. - */ - enum class DhIdState { - THROUGH_IN = 0, - THROUGH_OUT, - }; } // namespace DistributedInput } // namespace DistributedHardware } // namespace OHOS diff --git a/common/include/input_hub.cpp b/common/include/input_hub.cpp index 069a884..96736d8 100644 --- a/common/include/input_hub.cpp +++ b/common/include/input_hub.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -32,6 +33,7 @@ #include "dinput_context.h" #include "dinput_errcode.h" #include "dinput_log.h" +#include "dinput_state.h" #include "dinput_utils_tool.h" namespace OHOS { @@ -39,6 +41,7 @@ namespace DistributedHardware { namespace DistributedInput { namespace { const uint32_t SLEEP_TIME_US = 100 * 1000; +const std::string MOUSE_NODE_KEY = "mouse"; } InputHub::InputHub() : epollFd_(0), iNotifyFd_(0), inputWd_(0), needToScanDevices_(true), nextDeviceId_(1), @@ -93,28 +96,50 @@ int32_t InputHub::Release() return DH_SUCCESS; } +bool InputHub::IsInputNodeNoNeedScan(const std::string &path) +{ + { + std::lock_guard deviceLock(devicesMutex_); + auto iter = devices_.find(path); + if (iter != devices_.end()) { + return true; + } + } + + if (path.find(MOUSE_NODE_KEY) != std::string::npos) { + DHLOGI("Skip mouse node for no permission, path: %s", path.c_str()); + return true; + } + + return IsSkipDevicePath(path); +} + +void InputHub::ScanAndRecordInputDevices() +{ + DHLOGI("Scan local input devices."); + ScanInputDevices(DEVICE_PATH); + + { + std::lock_guard deviceLock(devicesMutex_); + while (!openingDevices_.empty()) { + std::unique_ptr device = std::move(*openingDevices_.rbegin()); + openingDevices_.pop_back(); + DHLOGI("Reporting device opened: path=%s, name=%s\n", + device->path.c_str(), device->identifier.name.c_str()); + auto [dev_it, inserted] = devices_.insert_or_assign(device->path, std::move(device)); + if (!inserted) { + DHLOGI("Device with this path %s exists, replaced. \n", device->path.c_str()); + } + } + } +} + size_t InputHub::StartCollectInputEvents(RawEvent *buffer, size_t bufferSize) { size_t count = 0; isStartCollectEvent_ = true; while (isStartCollectEvent_) { - if (needToScanDevices_) { - needToScanDevices_ = false; - ScanInputDevices(DEVICE_PATH); - } - { - std::lock_guard deviceLock(devicesMutex_); - while (!openingDevices_.empty()) { - std::unique_ptr device = std::move(*openingDevices_.rbegin()); - openingDevices_.pop_back(); - DHLOGI("Reporting device opened: id=%s, name=%s\n", - GetAnonyInt32(device->id).c_str(), device->path.c_str()); - auto [dev_it, inserted] = devices_.insert_or_assign(device->id, std::move(device)); - if (!inserted) { - DHLOGI("Device id %s exists, replaced. \n", GetAnonyInt32(device->id).c_str()); - } - } - } + ScanAndRecordInputDevices(); deviceChanged_ = false; count = GetEvents(buffer, bufferSize); @@ -175,6 +200,7 @@ size_t InputHub::GetEvents(RawEvent *buffer, size_t bufferSize) continue; } if (!sharedDHIds_[device->identifier.descriptor]) { + RecordDeviceChangeStates(device, readBuffer, count); DHLOGE("Not in sharing stat, device descriptor: %s", GetAnonyString(device->identifier.descriptor).c_str()); continue; @@ -208,6 +234,52 @@ bool InputHub::IsTouchPad(const InputDevice &inputDevice) return true; } +void InputHub::RecordDeviceChangeStates(Device *device, struct input_event readBuffer[], const size_t count) +{ + DHLOGD("RecordDeviceChangeStates enter."); + bool isTouchEvent = false; + if ((device->classes & INPUT_DEVICE_CLASS_TOUCH_MT) || (device->classes & INPUT_DEVICE_CLASS_TOUCH)) { + if (!IsTouchPad(device->identifier)) { + isTouchEvent = true; + } + } + + for (size_t i = 0; i < count; i++) { + RawEvent event; + const struct input_event& iev = readBuffer[i]; + event.when = ProcessEventTimestamp(iev); + event.type = iev.type; + event.code = iev.code; + event.value = iev.value; + event.path = device->path; + event.descriptor = isTouchEvent ? touchDescriptor : device->identifier.descriptor; + + // Deal key state + if (event.type == EV_KEY && event.code != BTN_TOOL_FINGER && event.value == KEY_DOWN_STATE) { + DInputState::GetInstance().AddKeyDownState(event); + RecordChangeEventLog(event); + } + + if (event.type == EV_KEY && event.value == KEY_UP_STATE) { + DInputState::GetInstance().RemoveKeyDownState(event); + RecordChangeEventLog(event); + } + + if (event.type == EV_KEY && event.value == KEY_REPEAT) { + DInputState::GetInstance().CheckAndSetLongPressedKeyOrder(event); + } + + if (event.type == EV_ABS && (event.code == ABS_MT_POSITION_X || event.code == ABS_X)) { + DInputState::GetInstance().RefreshABSPosition(event.descriptor, event.value, -1); + } + + if (event.type == EV_ABS && (event.code == ABS_MT_POSITION_Y || event.code == ABS_Y)) { + DInputState::GetInstance().RefreshABSPosition(event.descriptor, -1, event.value); + } + DHLOGD("RecordDeviceChangeStates end."); + } +} + size_t InputHub::CollectEvent(RawEvent *buffer, size_t &capacity, Device *device, struct input_event readBuffer[], const size_t count) { @@ -272,7 +344,7 @@ size_t InputHub::DeviceIsExists(InputDeviceEvent *buffer, size_t bufferSize) for (auto it = closingDevices_.begin(); it != closingDevices_.end();) { std::unique_ptr device = std::move(*it); DHLOGI("Reporting device closed: id=%s, name=%s\n", - GetAnonyInt32(device->id).c_str(), device->path.c_str()); + device->path.c_str(), device->identifier.name.c_str()); event->type = DeviceType::DEVICE_REMOVED; event->deviceInfo = device->identifier; event += 1; @@ -295,14 +367,14 @@ size_t InputHub::DeviceIsExists(InputDeviceEvent *buffer, size_t bufferSize) std::unique_ptr device = std::move(*openingDevices_.rbegin()); openingDevices_.pop_back(); DHLOGI("Reporting device opened: id=%s, name=%s\n", - GetAnonyInt32(device->id).c_str(), device->path.c_str()); + device->path.c_str(), device->identifier.name.c_str()); event->type = DeviceType::DEVICE_ADDED; event->deviceInfo = device->identifier; event += 1; - auto [dev_it, inserted] = devices_.insert_or_assign(device->id, std::move(device)); + auto [dev_it, inserted] = devices_.insert_or_assign(device->path, std::move(device)); if (!inserted) { - DHLOGI("Device id %s exists, replaced. \n", GetAnonyInt32(device->id).c_str()); + DHLOGI("Device path %s exists, replaced. \n", device->path.c_str()); } if (capacity == 0) { break; @@ -428,6 +500,10 @@ void InputHub::ScanInputDevices(const std::string &dirName) std::vector inputDevPaths; ScanInputDevicesPath(dirName, inputDevPaths); for (const auto &tempPath: inputDevPaths) { + if (IsInputNodeNoNeedScan(tempPath)) { + DHLOGI("This input node path should skip. Path: %s", tempPath.c_str()); + continue; + } OpenInputDeviceLocked(tempPath); } } @@ -455,12 +531,12 @@ int32_t InputHub::OpenInputDeviceLocked(const std::string &devicePath) int fd = OpenInputDeviceFdByPath(devicePath); if (fd == UN_INIT_FD_VALUE) { DHLOGE("The fd open failed, devicePath %s.", devicePath.c_str()); + RecordSkipDevicePath(devicePath); return ERR_DH_INPUT_HUB_OPEN_DEVICEPATH_FAIL; } // Allocate device. (The device object takes ownership of the fd at this point.) - int32_t deviceId = nextDeviceId_++; - std::unique_ptr device = std::make_unique(fd, deviceId, devicePath); + std::unique_ptr device = std::make_unique(fd, devicePath); if (QueryInputDeviceInfo(fd, device) < 0) { CloseFd(fd); @@ -468,7 +544,7 @@ int32_t InputHub::OpenInputDeviceLocked(const std::string &devicePath) } GenerateDescriptor(device->identifier); - RecordDeviceLog(deviceId, devicePath, device->identifier); + RecordDeviceLog(devicePath, device->identifier); if (MakeDevice(fd, std::move(device)) < 0) { CloseFd(fd); @@ -480,6 +556,18 @@ int32_t InputHub::OpenInputDeviceLocked(const std::string &devicePath) return DH_SUCCESS; } +void InputHub::RecordSkipDevicePath(std::string path) +{ + std::lock_guard lock(skipDevicePathsMutex_); + skipDevicePaths_.insert(path); +} + +bool InputHub::IsSkipDevicePath(const std::string &path) +{ + std::lock_guard lock(skipDevicePathsMutex_); + return skipDevicePaths_.find(path) != skipDevicePaths_.end(); +} + int32_t InputHub::QueryInputDeviceInfo(int fd, std::unique_ptr &device) { char buffer[INPUT_EVENT_BUFFER_SIZE] = {0}; @@ -494,6 +582,7 @@ int32_t InputHub::QueryInputDeviceInfo(int fd, std::unique_ptr &device) DHLOGD("QueryInputDeviceInfo deviceName: %s", buffer); // If the device is already a virtual device, don't monitor it. if (device->identifier.name.find(VIRTUAL_DEVICE_NAME) != std::string::npos) { + RecordSkipDevicePath(device->path); return ERR_DH_INPUT_HUB_IS_VIRTUAL_DEVICE; } // Get device driver version. @@ -865,7 +954,7 @@ int32_t InputHub::RegisterDeviceForEpollLocked(const Device &device) { int32_t result = RegisterFdForEpoll(device.fd); if (result != DH_SUCCESS) { - DHLOGE("Could not add input device fd to epoll for device %d", device.id); + DHLOGE("Could not add input device fd to epoll for device, path: %s", device.path.c_str()); return result; } return result; @@ -891,29 +980,27 @@ void InputHub::AddDeviceLocked(std::unique_ptr device) void InputHub::CloseDeviceLocked(Device &device) { - DHLOGI("Removed device: path=%s name=%s id=%s fd=%d classes=0x%x", - device.path.c_str(), device.identifier.name.c_str(), GetAnonyInt32(device.id).c_str(), - device.fd, device.classes); + DHLOGI("Removed device: path=%s name=%s fd=%d classes=0x%x", + device.path.c_str(), device.identifier.name.c_str(), device.fd, device.classes); UnregisterDeviceFromEpollLocked(device); device.Close(); { std::lock_guard devicesLock(devicesMutex_); - closingDevices_.push_back(std::move(devices_[device.id])); - devices_.erase(device.id); + closingDevices_.push_back(std::move(devices_[device.path])); + devices_.erase(device.path); } } void InputHub::CloseDeviceForAllLocked(Device &device) { - DHLOGI("Removed device: path=%s name=%s id=%s fd=%d classes=0x%x", - device.path.c_str(), device.identifier.name.c_str(), GetAnonyInt32(device.id).c_str(), - device.fd, device.classes); + DHLOGI("Removed device: path=%s name=%s fd=%d classes=0x%x", + device.path.c_str(), device.identifier.name.c_str(), device.fd, device.classes); UnregisterDeviceFromEpollLocked(device); device.Close(); - closingDevices_.push_back(std::move(devices_[device.id])); - devices_.erase(device.id); + closingDevices_.push_back(std::move(devices_[device.path])); + devices_.erase(device.path); } int32_t InputHub::UnregisterDeviceFromEpollLocked(const Device &device) const @@ -921,8 +1008,7 @@ int32_t InputHub::UnregisterDeviceFromEpollLocked(const Device &device) const if (device.HasValidFd()) { int32_t result = UnregisterFdFromEpoll(device.fd); if (result != DH_SUCCESS) { - DHLOGE("Could not remove input device fd from epoll for device %s", - GetAnonyInt32(device.id).c_str()); + DHLOGE("Could not remove input device fd from epoll for device, path: %s", device.path.c_str()); return result; } } @@ -1032,7 +1118,7 @@ InputHub::Device* InputHub::GetSupportDeviceByFd(int fd) std::lock_guard deviceLock(devicesMutex_); for (const auto &[id, device] : devices_) { if (device != nullptr && device->fd == fd) { - DHLOGI("GetSupportDeviceByFd device: %d, fd: %d, path: %s, dhId: %s, classes=0x%x", id, device->fd, + DHLOGI("GetSupportDeviceByFd device fd: %d, path: %s, dhId: %s, classes=0x%x", device->fd, device->path.c_str(), GetAnonyString(device->identifier.descriptor).c_str(), device->classes); return device.get(); } @@ -1215,9 +1301,9 @@ bool InputHub::IsAllDevicesStoped() return true; } -void InputHub::RecordDeviceLog(const int32_t deviceId, const std::string &devicePath, const InputDevice &identifier) +void InputHub::RecordDeviceLog(const std::string &devicePath, const InputDevice &identifier) { - DHLOGI("add device %d: %s\n", deviceId, devicePath.c_str()); + DHLOGI("add device: %s\n", devicePath.c_str()); DHLOGI(" bus: %04x\n" " vendor %04x\n" " product %04x\n" @@ -1229,6 +1315,31 @@ void InputHub::RecordDeviceLog(const int32_t deviceId, const std::string &device DHLOGI(" descriptor: \"%s\"\n", GetAnonyString(identifier.descriptor).c_str()); } +void InputHub::RecordChangeEventLog(const RawEvent &event) +{ + std::string eventType = ""; + switch (event.type) { + case EV_KEY: + eventType = "EV_KEY"; + break; + case EV_REL: + eventType = "EV_REL"; + break; + case EV_ABS: + eventType = "EV_ABS"; + break; + case EV_SYN: + eventType = "EV_SYN"; + break; + default: + eventType = "other type " + std::to_string(event.type); + break; + } + DHLOGD("0.E2E-Test Sink collect change event, EventType: %s, Code: %d, Value: %d, Path: %s, descriptor: %s," + "When:%" PRId64 "", eventType.c_str(), event.code, event.value, event.path.c_str(), + GetAnonyString(event.descriptor).c_str(), event.when); +} + void InputHub::RecordEventLog(const RawEvent *event) { std::string eventType = ""; @@ -1326,11 +1437,120 @@ bool InputHub::CheckTouchPointRegion(struct input_event readBuffer[], const AbsI return false; } -InputHub::Device::Device(int fd, int32_t id, const std::string &path) - : next(nullptr), fd(fd), id(id), path(path), identifier({}), classes(0), enabled(false), +std::vector InputHub::CollectTargetDevices() +{ + std::lock_guard deviceLock(devicesMutex_); + std::vector tarVec; + for (const auto &dev : devices_) { + if (((dev.second->classes & INPUT_DEVICE_CLASS_TOUCH) != 0) || + ((dev.second->classes & INPUT_DEVICE_CLASS_TOUCH_MT) != 0) || + ((dev.second->classes & INPUT_DEVICE_CLASS_CURSOR) != 0) || + ((dev.second->classes & INPUT_DEVICE_CLASS_KEYBOARD) != 0)) { + DHLOGI("Find target devs need check stat, path: %s, name: %s", + dev.first.c_str(), dev.second->identifier.name.c_str()); + tarVec.push_back(dev.second.get()); + } + } + + return tarVec; +} + +void InputHub::SavePressedKeyState(const InputHub::Device *dev, int32_t keyCode) +{ + struct RawEvent event = { + .type = EV_KEY, + .code = keyCode, + .value = KEY_DOWN_STATE, + .descriptor = dev->identifier.descriptor, + .path = dev->path + }; + DInputState::GetInstance().AddKeyDownState(event); + DHLOGI("Find Pressed key: %d, device path: %s, dhId: %s", keyCode, dev->path.c_str(), + dev->identifier.descriptor.c_str()); +} + +void InputHub::CheckTargetKeyState(const InputHub::Device *dev, const unsigned long *keyState) +{ + //If device is a mouse, record the mouse pressed key. + if ((dev->classes & INPUT_DEVICE_CLASS_CURSOR) != 0) { + int mouseLeftBtnState = BitIsSet(keyState, BTN_LEFT); + if (mouseLeftBtnState != 0) { + SavePressedKeyState(dev, BTN_LEFT); + } + + int mouseRightBtnState = BitIsSet(keyState, BTN_RIGHT); + if (mouseRightBtnState != 0) { + SavePressedKeyState(dev, BTN_RIGHT); + } + + int mouseMidBtnState = BitIsSet(keyState, BTN_MIDDLE); + if (mouseMidBtnState != 0) { + SavePressedKeyState(dev, BTN_MIDDLE); + } + } + + // If device is a keyboard, record all the pressed keys. + if ((dev->classes & INPUT_DEVICE_CLASS_KEYBOARD) != 0) { + for (int32_t keyIndex = 0; keyIndex < KEY_MAX; keyIndex++) { + if (BitIsSet(keyState, keyIndex) != 0) { + SavePressedKeyState(dev, keyIndex); + } + } + } + + // If device is a touchscreen or touchpad, record the touch event. + if ((dev->classes & INPUT_DEVICE_CLASS_TOUCH) != 0 || (dev->classes & INPUT_DEVICE_CLASS_TOUCH_MT) != 0) { + int btnTouchState = BitIsSet(keyState, BTN_TOUCH); + if (btnTouchState != 0) { + SavePressedKeyState(dev, BTN_TOUCH); + } + } +} + +void InputHub::CheckTargetDevicesState(std::vector targetDevices) +{ + uint32_t count = 0; + unsigned long keyState[NLONGS(KEY_CNT)] = { 0 }; + for (const auto *dev : targetDevices) { + while (true) { + if (count > READ_RETRY_MAX) { + break; + } + // Query all key state + int rc = ioctl(dev->fd, EVIOCGKEY(sizeof(keyState)), keyState); + if (rc < 0) { + DHLOGE("read all key state failed, rc=%d", rc); + count += 1; + std::this_thread::sleep_for(std::chrono::milliseconds(READ_SLEEP_TIME_MS)); + continue; + } + CheckTargetKeyState(dev, keyState); + break; + } + } +} + +void InputHub::RecordDeviceStates() +{ + DHLOGI("Start Record keys states"); + ScanAndRecordInputDevices(); + std::vector tarDevices = CollectTargetDevices(); + DHLOGI("Check target states device num: %d", tarDevices.size()); + CheckTargetDevicesState(tarDevices); + DHLOGI("Finish Record Keys states"); +} + +void InputHub::ClearDeviceStates() +{ + DHLOGI("Clear Device state"); + DInputState::GetInstance().ClearDeviceStates(); +} + +InputHub::Device::Device(int fd, const std::string &path) + : next(nullptr), fd(fd), path(path), identifier({}), classes(0), enabled(false), isShare(false), isVirtual(fd < 0) { // Figure out the kinds of events the device reports. - DHLOGE("Ctor Device for get event mask, fd: %d, id: %d, path: %s", fd, id, path.c_str()); + DHLOGE("Ctor Device for get event mask, fd: %d, path: %s", fd, path.c_str()); ioctl(fd, EVIOCGBIT(0, sizeof(evBitmask)), evBitmask); ioctl(fd, EVIOCGBIT(EV_KEY, sizeof(keyBitmask)), keyBitmask); ioctl(fd, EVIOCGBIT(EV_ABS, sizeof(absBitmask)), absBitmask); diff --git a/common/include/input_hub.h b/common/include/input_hub.h index b9fada6..bd1403f 100644 --- a/common/include/input_hub.h +++ b/common/include/input_hub.h @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -43,33 +44,10 @@ inline constexpr size_t NBYTES(size_t nbits) } class InputHub { -public: - InputHub(); - ~InputHub(); - size_t StartCollectInputEvents(RawEvent *buffer, size_t bufferSize); - size_t StartCollectInputHandler(InputDeviceEvent *buffer, size_t bufferSize); - void StopCollectInputEvents(); - void StopCollectInputHandler(); - size_t DeviceIsExists(InputDeviceEvent *buffer, size_t bufferSize); - std::vector GetAllInputDevices(); - // return efftive dhids - AffectDhIds SetSupportInputType(bool enabled, const uint32_t &inputTypes); - // return efftive dhids - AffectDhIds SetSharingDevices(bool enabled, std::vector dhIds); - void GetDevicesInfoByType(const uint32_t inputTypes, std::map &datas); - void GetDevicesInfoByDhId(std::vector dhidsVec, std::map &datas); - void GetSharedMousePathByDhId(const std::vector &dhIds, std::string &sharedMousePath, - std::string &sharedMouseDhId); - void GetSharedKeyboardPathsByDhIds(const std::vector &dhIds, - std::vector &sharedKeyboardPaths, std::vector &sharedKeyboardDhIds); - bool IsAllDevicesStoped(); - void ScanInputDevices(const std::string &dirName); - private: struct Device { Device* next; int fd; // may be -1 if device is closed - const int32_t id; const std::string path; InputDevice identifier; uint32_t classes; @@ -78,7 +56,7 @@ private: uint8_t absBitmask[NBYTES(ABS_MAX)] {}; uint8_t relBitmask[NBYTES(REL_MAX)] {}; - Device(int fd, int32_t id, const std::string &path); + Device(int fd, const std::string &path); ~Device(); void Close(); bool enabled; // initially true @@ -95,7 +73,34 @@ private: int32_t absXIndex; int32_t absYIndex; }; +public: + InputHub(); + ~InputHub(); + size_t StartCollectInputEvents(RawEvent *buffer, size_t bufferSize); + size_t StartCollectInputHandler(InputDeviceEvent *buffer, size_t bufferSize); + void StopCollectInputEvents(); + void StopCollectInputHandler(); + size_t DeviceIsExists(InputDeviceEvent *buffer, size_t bufferSize); + std::vector GetAllInputDevices(); + // return efftive dhids + AffectDhIds SetSupportInputType(bool enabled, const uint32_t &inputTypes); + // return efftive dhids + AffectDhIds SetSharingDevices(bool enabled, std::vector dhIds); + void GetDevicesInfoByType(const uint32_t inputTypes, std::map &datas); + void GetDevicesInfoByDhId(std::vector dhidsVec, std::map &datas); + void GetSharedMousePathByDhId(const std::vector &dhIds, std::string &sharedMousePath, + std::string &sharedMouseDhId); + void GetSharedKeyboardPathsByDhIds(const std::vector &dhIds, + std::vector &sharedKeyboardPaths, std::vector &sharedKeyboardDhIds); + bool IsAllDevicesStoped(); + void ScanInputDevices(const std::string &dirName); + void RecordDeviceStates(); + void CheckTargetDevicesState(std::vector targetDevices); + void CheckTargetKeyState(const InputHub::Device *dev, const unsigned long *keyState); + void SavePressedKeyState(const Device *dev, int32_t keyCode); + void ClearDeviceStates(); +private: int32_t Initialize(); int32_t Release(); @@ -156,7 +161,9 @@ private: /* this macro computes the number of bytes needed to represent a bit array of the specified size */ uint32_t SizeofBitArray(uint32_t bit); void RecordEventLog(const RawEvent *event); - void RecordDeviceLog(const int32_t deviceId, const std::string &devicePath, const InputDevice &identifier); + // Record Event log that will change the key state. + void RecordChangeEventLog(const RawEvent &event); + void RecordDeviceLog(const std::string &devicePath, const InputDevice &identifier); void HandleTouchScreenEvent(struct input_event readBuffer[], const size_t count, std::vector &needFilted); int32_t QueryLocalTouchScreenInfo(int fd, std::unique_ptr &device); bool CheckTouchPointRegion(struct input_event readBuffer[], const AbsInfo &absInfo); @@ -166,16 +173,44 @@ private: * isEnable: true for sharing dhid, false for no sharing dhid */ void SaveAffectDhId(bool isEnable, const std::string &dhId, AffectDhIds &affDhIds); + /* + * Record Mouse/KeyBoard/TouchPad state such as key down. + */ + void RecordDeviceChangeStates(Device *device, struct input_event readBuffer[], const size_t count); + + /* + * Scan the input device node and save info. + */ + void ScanAndRecordInputDevices(); + + /* + * Check is this node has been scaned for collecting info. + * Return: True for scaned and cached. False for not scaned. + */ + bool IsInputNodeNoNeedScan(const std::string &path); + + /* + * Some input device should simulate state for pass through, such as Mouse, KeyBoard, TouchPad, etc. + * Before we prepare the pass through, we need check and get the key states of these devices. + */ + std::vector CollectTargetDevices(); + void RecordSkipDevicePath(std::string path); + bool IsSkipDevicePath(const std::string &path); + +private: int epollFd_; int iNotifyFd_; int inputWd_; std::vector> openingDevices_; std::vector> closingDevices_; - std::unordered_map> devices_; + std::unordered_map> devices_; std::mutex devicesMutex_; + std::mutex skipDevicePathsMutex_; + std::set skipDevicePaths_; + std::atomic needToScanDevices_; std::string deviceId_; std::string touchDescriptor; diff --git a/distributedinput.gni b/distributedinput.gni index 9493eec..6a39015 100644 --- a/distributedinput.gni +++ b/distributedinput.gni @@ -28,6 +28,8 @@ services_source_path = "${distributedinput_path}/services/source" services_sink_path = "${distributedinput_path}/services/sink" +services_state_path = "${distributedinput_path}/services/state" + innerkits_path = "${distributedinput_path}/interfaces/inner_kits" ipc_path = "${distributedinput_path}/interfaces/ipc" diff --git a/inputdevicehandler/BUILD.gn b/inputdevicehandler/BUILD.gn index db108f3..5a45911 100755 --- a/inputdevicehandler/BUILD.gn +++ b/inputdevicehandler/BUILD.gn @@ -29,6 +29,7 @@ ohos_shared_library("libdinput_handler") { "${av_transport_path}/common/include", "include", "${common_path}/include", + "${services_state_path}/include", "${fwk_common_path}/log/include", "${fwk_common_path}/utils/include", "${service_common}/include", @@ -52,6 +53,7 @@ ohos_shared_library("libdinput_handler") { deps = [ "${utils_path}:libdinput_utils", + "${services_state_path}:libdinput_state", "//third_party/libevdev:libevdev", "//third_party/openssl:libcrypto_shared", ] diff --git a/inputdevicehandler/test/inputhandlertest/BUILD.gn b/inputdevicehandler/test/inputhandlertest/BUILD.gn index be88283..66d54bb 100644 --- a/inputdevicehandler/test/inputhandlertest/BUILD.gn +++ b/inputdevicehandler/test/inputhandlertest/BUILD.gn @@ -30,6 +30,7 @@ ohos_unittest("distributed_input_handler_test") { include_dirs = [ "${av_transport_path}/common/include", "${common_path}/include", + "${services_state_path}/include", "${fwk_common_path}/log/include", "${fwk_common_path}/utils/include", "${service_common}/include", diff --git a/services/sink/inputcollector/BUILD.gn b/services/sink/inputcollector/BUILD.gn index 1eebab6..582372f 100755 --- a/services/sink/inputcollector/BUILD.gn +++ b/services/sink/inputcollector/BUILD.gn @@ -29,6 +29,7 @@ ohos_shared_library("libdinput_collector") { "${av_transport_path}/common/include", "include", "${common_path}/include", + "${services_state_path}/include", "${frameworks_path}/include", "${fwk_common_path}/log/include", "${fwk_common_path}/utils/include", @@ -51,6 +52,7 @@ ohos_shared_library("libdinput_collector") { deps = [ "${utils_path}:libdinput_utils", + "${services_state_path}:libdinput_state", "//third_party/libevdev:libevdev", "//third_party/openssl:libcrypto_shared", ] diff --git a/services/sink/inputcollector/include/distributed_input_collector.h b/services/sink/inputcollector/include/distributed_input_collector.h index 952b685..5d49ef5 100644 --- a/services/sink/inputcollector/include/distributed_input_collector.h +++ b/services/sink/inputcollector/include/distributed_input_collector.h @@ -38,6 +38,9 @@ namespace DistributedInput { class DistributedInputCollector { public: static DistributedInputCollector &GetInstance(); + // PreInit for get the local input devices basic info. + // Collect all the local input basic info cost too much time(200+ ms). + void PreInit(); int32_t Init(std::shared_ptr sinkHandler); void Release(); AffectDhIds SetSharingTypes(bool enabled, const uint32_t &inputType); @@ -50,6 +53,7 @@ public: int32_t RegisterSharingDhIdListener(sptr sharingDhIdListener); void ReportDhIdSharingState(const AffectDhIds &dhIds); void GetDeviceInfoByType(const uint32_t inputTypes, std::map &deviceInfo); + void ResetSpecEventStatus(); private: DistributedInputCollector(); diff --git a/services/sink/inputcollector/src/distributed_input_collector.cpp b/services/sink/inputcollector/src/distributed_input_collector.cpp index 3f60ca8..52015c0 100644 --- a/services/sink/inputcollector/src/distributed_input_collector.cpp +++ b/services/sink/inputcollector/src/distributed_input_collector.cpp @@ -53,13 +53,21 @@ DistributedInputCollector &DistributedInputCollector::GetInstance() return instance; } +void DistributedInputCollector::PreInit() +{ + DHLOGI("PreInit for record local device infos"); + inputHub_->RecordDeviceStates(); +} + int32_t DistributedInputCollector::Init(std::shared_ptr sinkHandler) { sinkHandler_ = sinkHandler; - if (sinkHandler_ == nullptr) { - DHLOGE("DistributedInputCollector::Init sinkHandler_ failed \n"); + if (sinkHandler_ == nullptr || inputHub_ == nullptr) { + DHLOGE("DistributedInputCollector::Init sinkHandler_ or inputHub_ invalid \n"); return ERR_DH_INPUT_SERVER_SINK_COLLECTOR_INIT_FAIL; } + + DHLOGI("Try start collect thread"); if (!isStartGetDeviceHandlerThread) { InitCollectEventsThread(); isStartGetDeviceHandlerThread = true; @@ -151,6 +159,7 @@ void DistributedInputCollector::StopCollectEventsThread() pthread_join(collectThreadID_, NULL); collectThreadID_ = (pthread_t)(-1); } + inputHub_->ClearDeviceStates(); DHLOGW("DistributedInputCollector::StopCollectEventsThread exit!"); } diff --git a/services/sink/inputcollector/test/sinkcollectorunittest/BUILD.gn b/services/sink/inputcollector/test/sinkcollectorunittest/BUILD.gn index 286653c..ef849ad 100644 --- a/services/sink/inputcollector/test/sinkcollectorunittest/BUILD.gn +++ b/services/sink/inputcollector/test/sinkcollectorunittest/BUILD.gn @@ -31,6 +31,7 @@ ohos_unittest("distributed_input_inner_sinkcollector_test") { "${av_transport_path}/common/include", "${services_sink_path}/inputcollector/include", "${common_path}/include", + "${services_state_path}/include", "${frameworks_path}/include", "${fwk_common_path}/log/include", "${fwk_common_path}/utils/include", diff --git a/services/sink/sinkmanager/src/distributed_input_sink_manager.cpp b/services/sink/sinkmanager/src/distributed_input_sink_manager.cpp index 27bd793..34b08a5 100644 --- a/services/sink/sinkmanager/src/distributed_input_sink_manager.cpp +++ b/services/sink/sinkmanager/src/distributed_input_sink_manager.cpp @@ -654,6 +654,9 @@ int32_t DistributedInputSinkManager::Init() } projectWindowListener_ = new ProjectWindowListener(this); dhFwkKit->RegisterPublisherListener(DHTopic::TOPIC_SINK_PROJECT_WINDOW_INFO, projectWindowListener_); + + DistributedInputCollector::GetInstance().PreInit(); + return DH_SUCCESS; } diff --git a/services/sink/sinkmanager/test/sinkmanagerunittest/BUILD.gn b/services/sink/sinkmanager/test/sinkmanagerunittest/BUILD.gn index d60aceb..9473409 100755 --- a/services/sink/sinkmanager/test/sinkmanagerunittest/BUILD.gn +++ b/services/sink/sinkmanager/test/sinkmanagerunittest/BUILD.gn @@ -38,6 +38,7 @@ ohos_unittest("distributed_input_sinkmanager_test") { "${services_sink_path}/sinkmanager/include", "${frameworks_path}/include", "${common_path}/include", + "${services_state_path}/include", "${fwk_common_path}/log/include", "${fwk_common_path}/utils/include", "${service_common}/include", diff --git a/services/sink/transport/include/distributed_input_sink_transport.h b/services/sink/transport/include/distributed_input_sink_transport.h index 34b8162..e948a1c 100644 --- a/services/sink/transport/include/distributed_input_sink_transport.h +++ b/services/sink/transport/include/distributed_input_sink_transport.h @@ -58,7 +58,8 @@ public: int32_t RespStartRemoteInput(const int32_t sessionId, std::string &smsg); int32_t RespStopRemoteInput(const int32_t sessionId, std::string &smsg); int32_t RespLatency(const int32_t sessionId, std::string &smsg); - void SendKeyStateNodeMsg(const int32_t sessionId, const std::string &dhId, const uint32_t btnCode); + void SendKeyStateNodeMsg(const int32_t sessionId, const std::string &dhId, uint32_t type, const uint32_t btnCode, + int32_t value); class DInputSinkEventHandler : public AppExecFwk::EventHandler { public: @@ -90,6 +91,8 @@ private: void NotifyRelayStopDhidRemoteInput(int32_t sessionId, const nlohmann::json &recMsg); void NotifyRelayStartTypeRemoteInput(int32_t sessionId, const nlohmann::json &recMsg); void NotifyRelayStopTypeRemoteInput(int32_t sessionId, const nlohmann::json &recMsg); + + void RecordEventLog(const std::string &dhId, int32_t type, int32_t code, int32_t value); private: std::string mySessionName_; std::shared_ptr eventHandler_; diff --git a/services/sink/transport/src/distributed_input_sink_transport.cpp b/services/sink/transport/src/distributed_input_sink_transport.cpp index 876a3f1..af2aefb 100644 --- a/services/sink/transport/src/distributed_input_sink_transport.cpp +++ b/services/sink/transport/src/distributed_input_sink_transport.cpp @@ -204,7 +204,7 @@ int32_t DistributedInputSinkTransport::RespLatency(const int32_t sessionId, std: } void DistributedInputSinkTransport::SendKeyStateNodeMsg(const int32_t sessionId, const std::string &dhId, - const uint32_t btnCode) + uint32_t type, const uint32_t btnCode, int32_t value) { if (sessionId <= 0) { DHLOGE("SendKeyStateNodeMsg error, sessionId <= 0."); @@ -214,14 +214,37 @@ void DistributedInputSinkTransport::SendKeyStateNodeMsg(const int32_t sessionId, nlohmann::json jsonStr; jsonStr[DINPUT_SOFTBUS_KEY_CMD_TYPE] = TRANS_SINK_MSG_KEY_STATE; jsonStr[DINPUT_SOFTBUS_KEY_KEYSTATE_DHID] = dhId; - jsonStr[DINPUT_SOFTBUS_KEY_KEYSTATE_TYPE] = EV_KEY; + jsonStr[DINPUT_SOFTBUS_KEY_KEYSTATE_TYPE] = type; jsonStr[DINPUT_SOFTBUS_KEY_KEYSTATE_CODE] = btnCode; - jsonStr[DINPUT_SOFTBUS_KEY_KEYSTATE_VALUE] = KEY_DOWN_STATE; + jsonStr[DINPUT_SOFTBUS_KEY_KEYSTATE_VALUE] = value; std::string msg = jsonStr.dump(); int32_t ret = SendMessage(sessionId, msg); if (ret != DH_SUCCESS) { DHLOGE("SendKeyStateNodeMsg error, SendMessage fail."); } + RecordEventLog(dhId, type, btnCode, value); +} + +void DistributedInputSinkTransport::RecordEventLog(const std::string &dhId, int32_t type, int32_t code, int32_t value) +{ + std::string eventType; + switch (type) { + case EV_KEY: + eventType = "EV_KEY"; + break; + case EV_REL: + eventType = "EV_REL"; + break; + case EV_ABS: + eventType = "EV_ABS"; + break; + default: + eventType = "other type " + std::to_string(type); + break; + } + + DHLOGD("2.E2E-Test Sink softBus send, EventType: %s, Code: %d, Value: %d, dhId: %s", + eventType.c_str(), code, value, dhId.c_str()); } int32_t DistributedInputSinkTransport::SendMessage(int32_t sessionId, std::string &message) @@ -518,7 +541,7 @@ void DistributedInputSinkTransport::DInputSinkEventHandler::RecordEventLog( eventType = "EV_ABS"; break; default: - eventType = "other type"; + eventType = "other type " + std::to_string(evType); break; } int64_t when = event[INPUT_KEY_WHEN]; diff --git a/services/source/inputinject/BUILD.gn b/services/source/inputinject/BUILD.gn index 3926d47..035da10 100644 --- a/services/source/inputinject/BUILD.gn +++ b/services/source/inputinject/BUILD.gn @@ -29,6 +29,7 @@ ohos_shared_library("libdinput_inject") { "${av_transport_path}/common/include", "include", "${common_path}/include", + "${services_state_path}/include", "${frameworks_path}/include", "${fwk_common_path}/log/include", "${fwk_common_path}/utils/include", @@ -39,7 +40,6 @@ ohos_shared_library("libdinput_inject") { "${fwk_interfaces_path}/include", "${fwk_interfaces_path}/include/ipc", "${distributedinput_path}/inputdevicehandler/include", - "${distributedinput_path}/services/state/include", ] sources = [ @@ -58,6 +58,7 @@ ohos_shared_library("libdinput_inject") { deps = [ "${dfx_utils_path}:libdinput_dfx_utils", "${utils_path}:libdinput_utils", + "${services_state_path}:libdinput_state", "//third_party/libevdev:libevdev", "//third_party/openssl:libcrypto_shared", ] diff --git a/services/source/inputinject/include/distributed_input_inject.h b/services/source/inputinject/include/distributed_input_inject.h index 65b9757..d9f3c63 100644 --- a/services/source/inputinject/include/distributed_input_inject.h +++ b/services/source/inputinject/include/distributed_input_inject.h @@ -57,9 +57,6 @@ public: const std::string &sinkNodeDesc); void GetVirtualKeyboardPathsByDhIds(const std::vector &dhIds, std::vector &virKeyboardPaths, std::vector &virKeyboardDhIds); - void UpdateSpecEventFirstStatus(bool status); - void UpdateSpecEventState(DhIdState state); - private: DistributedInputInject(); ~DistributedInputInject(); diff --git a/services/source/inputinject/include/distributed_input_node_manager.h b/services/source/inputinject/include/distributed_input_node_manager.h index fd6c022..25c4dbc 100644 --- a/services/source/inputinject/include/distributed_input_node_manager.h +++ b/services/source/inputinject/include/distributed_input_node_manager.h @@ -63,9 +63,6 @@ public: void GetVirtualKeyboardPathsByDhIds(const std::vector &dhIds, std::vector &virKeyboardPaths, std::vector &virKeyboardDhIds); void NotifyNodeMgrScanVirNode(const std::string &dhId); - void UpdateSpecEventFirstStatus(bool status); - void UpdateSpecEventState(DhIdState state); - void InjectInputEvent(const std::string &dhId, const struct input_event &event); void RegisterInjectEventCb(sptr callback); void UnregisterInjectEventCb(); @@ -115,8 +112,6 @@ private: int32_t virtualTouchScreenFd_; std::once_flag callOnceFlag_; std::shared_ptr callBackHandler_; - std::atomic isFirst_; - DhIdState specEventState_; sptr SessionStateCallback_; }; } // namespace DistributedInput diff --git a/services/source/inputinject/src/distributed_input_inject.cpp b/services/source/inputinject/src/distributed_input_inject.cpp index f09795d..792ca4a 100644 --- a/services/source/inputinject/src/distributed_input_inject.cpp +++ b/services/source/inputinject/src/distributed_input_inject.cpp @@ -292,26 +292,6 @@ void DistributedInputInject::NotifyNodeMgrScanVirNode(const std::string &dhId) } inputNodeManager_->NotifyNodeMgrScanVirNode(dhId); } - -void DistributedInputInject::UpdateSpecEventFirstStatus(bool status) -{ - std::lock_guard lock(inputNodeManagerMutex_); - if (inputNodeManager_ == nullptr) { - DHLOGE("inputNodeManager is nullptr"); - return; - } - inputNodeManager_->UpdateSpecEventFirstStatus(status); -} - -void DistributedInputInject::UpdateSpecEventState(DhIdState state) -{ - std::lock_guard lock(inputNodeManagerMutex_); - if (inputNodeManager_ == nullptr) { - DHLOGE("inputNodeManager is nullptr"); - return; - } - inputNodeManager_->UpdateSpecEventState(state); -} } // namespace DistributedInput } // namespace DistributedHardware } // namespace OHOS \ No newline at end of file diff --git a/services/source/inputinject/src/distributed_input_node_manager.cpp b/services/source/inputinject/src/distributed_input_node_manager.cpp index 40139e1..9fc137e 100644 --- a/services/source/inputinject/src/distributed_input_node_manager.cpp +++ b/services/source/inputinject/src/distributed_input_node_manager.cpp @@ -32,8 +32,7 @@ namespace OHOS { namespace DistributedHardware { namespace DistributedInput { DistributedInputNodeManager::DistributedInputNodeManager() : isInjectThreadCreated_(false), - isInjectThreadRunning_(false), inputHub_(std::make_unique()), virtualTouchScreenFd_(UN_INIT_FD_VALUE), - isFirst_(false), specEventState_(DhIdState::THROUGH_OUT) + isInjectThreadRunning_(false), inputHub_(std::make_unique()), virtualTouchScreenFd_(UN_INIT_FD_VALUE) { DHLOGI("DistributedInputNodeManager ctor"); std::shared_ptr runner = AppExecFwk::EventRunner::Create(true); @@ -202,18 +201,6 @@ void DistributedInputNodeManager::DInputNodeManagerEventHandler::ScanAllNode( nodeManagerObj_->ScanSinkInputDevices(devicedhId); } -void DistributedInputNodeManager::UpdateSpecEventFirstStatus(bool status) -{ - DHLOGI("UpdateSpecEventFirstStatus enter, status is %d", status); - isFirst_.store(status); -} - -void DistributedInputNodeManager::UpdateSpecEventState(DhIdState state) -{ - DHLOGI("UpdateSpecEventState enter."); - specEventState_ = state; -} - void DistributedInputNodeManager::NotifyNodeMgrScanVirNode(const std::string &dhId) { DHLOGI("NotifyNodeMgrScanVirNode enter."); @@ -470,19 +457,6 @@ void DistributedInputNodeManager::InjectEvent() DHLOGI("end"); } -void DistributedInputNodeManager::InjectInputEvent(const std::string &dhId, const struct input_event &event) -{ - VirtualDevice* device = nullptr; - if (GetDevice(dhId, device) < 0) { - DHLOGE("could not find the device"); - RunInjectEventCallback(dhId, DINPUT_INJECT_EVENT_FAIL); - return; - } - if (device != nullptr) { - device->InjectInputEvent(event); - } -} - void DistributedInputNodeManager::RegisterInjectEventCb(sptr callback) { DHLOGI("RegisterInjectEventCb"); @@ -515,33 +489,14 @@ void DistributedInputNodeManager::ProcessInjectEvent(const std::shared_ptrwhen); - if (event.type == EV_KEY) { - if (event.value == KEY_UP_STATE) { - UpdateSpecEventFirstStatus(false); - } - - if (event.value == KEY_LONGPRESS_STATE && !isFirst_.load() && specEventState_ == DhIdState::THROUGH_IN) { - struct input_event inputEvent = { - .type = event.type, - .code = event.code, - .value = KEY_DOWN_STATE - }; - DHLOGI("Spec Inject KEY DOWN dhId: %s, eventType: %d, eventCode: %d, eventValue: %d, when: " PRId64"", - GetAnonyString(dhId).c_str(), event.type, event.code, event.value, rawEvent->when); - InjectInputEvent(dhId, inputEvent); - - inputEvent = { - .type = KEY_OTHER_TYPE, - .code = 0, - .value = 0 - }; - DHLOGI("Spec Inject KEY SYNC dhId: %s, eventType: %d, eventCode: %d, eventValue: %d, when: " PRId64"", - GetAnonyString(dhId).c_str(), event.type, event.code, event.value, rawEvent->when); - InjectInputEvent(dhId, inputEvent); - UpdateSpecEventFirstStatus(true); - } + VirtualDevice* device = nullptr; + if (GetDevice(dhId, device) < 0) { + DHLOGE("could not find the device"); + return; + } + if (device != nullptr) { + device->InjectInputEvent(event); } - InjectInputEvent(dhId, event); } int32_t DistributedInputNodeManager::GetDeviceInfo(std::string &deviceId) diff --git a/services/source/inputinject/test/sourceinjectunittest/BUILD.gn b/services/source/inputinject/test/sourceinjectunittest/BUILD.gn index d0ad852..335e137 100755 --- a/services/source/inputinject/test/sourceinjectunittest/BUILD.gn +++ b/services/source/inputinject/test/sourceinjectunittest/BUILD.gn @@ -34,6 +34,7 @@ ohos_unittest("distributed_input_inner_sourceinject_test") { "${services_source_path}/inputinject/include", "${frameworks_path}/include", "${common_path}/include", + "${services_state_path}/include", "${frameworks_path}/include", "${fwk_common_path}/log/include", "${fwk_common_path}/utils/include", diff --git a/services/source/sourcemanager/BUILD.gn b/services/source/sourcemanager/BUILD.gn index 7d8458b..c727c29 100644 --- a/services/source/sourcemanager/BUILD.gn +++ b/services/source/sourcemanager/BUILD.gn @@ -45,7 +45,6 @@ ohos_shared_library("libdinput_source") { "${fwk_interfaces_path}/include", "${fwk_interfaces_path}/include/ipc", "${distributedinput_path}/inputdevicehandler/include", - "${distributedinput_path}/services/state/include", "${distributedinput_path}/services/transportbase/include", ] @@ -101,7 +100,6 @@ ohos_shared_library("libdinput_source") { deps = [ "${dfx_utils_path}:libdinput_dfx_utils", - "${distributedinput_path}/services/state:libdinput_state", "${distributedinput_path}/services/transportbase:libdinput_trans_base", "${innerkits_path}:libdinput_sdk", "${services_source_path}/inputinject:libdinput_inject", diff --git a/services/source/sourcemanager/include/distributed_input_source_manager.h b/services/source/sourcemanager/include/distributed_input_source_manager.h index dfad600..a25cb84 100644 --- a/services/source/sourcemanager/include/distributed_input_source_manager.h +++ b/services/source/sourcemanager/include/distributed_input_source_manager.h @@ -38,7 +38,6 @@ #include "distributed_input_source_event_handler.h" #include "distributed_input_source_sa_cli_mgr.h" #include "distributed_input_source_stub.h" -#include "dinput_state.h" #include "dinput_source_listener.h" #include "dinput_source_manager_event_handler.h" @@ -283,7 +282,6 @@ public: uint32_t GetInputTypesMap(const std::string deviceId); uint32_t GetAllInputTypesMap(); void ClearResourcesStatus(); - void UpdateSpecEventStatus(); public: void RunRelayPrepareCallback(const std::string &srcId, const std::string &sinkId, const int32_t status); diff --git a/services/source/sourcemanager/src/dinput_source_listener.cpp b/services/source/sourcemanager/src/dinput_source_listener.cpp index cedd3db..6a84d50 100644 --- a/services/source/sourcemanager/src/dinput_source_listener.cpp +++ b/services/source/sourcemanager/src/dinput_source_listener.cpp @@ -257,7 +257,6 @@ void DInputSourceListener::OnResponseStartRemoteInputDhid( std::vector devDhIds; SplitStringToVector(dhids, INPUT_STRING_SPLIT_POINT, devDhIds); - DInputState::GetInstance().RecordDhIds(devDhIds, DhIdState::THROUGH_IN, -1); auto jsonArrayMsg = std::make_shared(); nlohmann::json tmpJson; diff --git a/services/source/sourcemanager/src/distributed_input_source_manager.cpp b/services/source/sourcemanager/src/distributed_input_source_manager.cpp index a8b2a5e..56297eb 100644 --- a/services/source/sourcemanager/src/distributed_input_source_manager.cpp +++ b/services/source/sourcemanager/src/distributed_input_source_manager.cpp @@ -28,7 +28,6 @@ #include "dinput_errcode.h" #include "dinput_hitrace.h" #include "dinput_log.h" -#include "dinput_state.h" #include "dinput_utils_tool.h" #include "distributed_input_client.h" #include "distributed_input_inject.h" @@ -80,7 +79,6 @@ void DistributedInputSourceManager::DInputSrcMgrListener::ResetSrcMgrResStatus() return; } sourceManagerObj_->ClearResourcesStatus(); - sourceManagerObj_->UpdateSpecEventStatus(); } void DistributedInputSourceManager::OnStart() @@ -164,11 +162,6 @@ int32_t DistributedInputSourceManager::Init() dhFwkKit->RegisterPublisherListener(DHTopic::TOPIC_STOP_DSCREEN, stopDScreenListener_); dhFwkKit->RegisterPublisherListener(DHTopic::TOPIC_DEV_OFFLINE, deviceOfflineListener_); - ret = DInputState::GetInstance().Init(); - if (ret != DH_SUCCESS) { - DHLOGE("DInputState init fail!"); - return ERR_DH_INPUT_SERVER_SOURCE_MANAGER_INIT_FAIL; - } return DH_SUCCESS; } @@ -1718,12 +1711,6 @@ void DistributedInputSourceManager::ClearResourcesStatus() relayUnpreCallbacks_.clear(); } -void DistributedInputSourceManager::UpdateSpecEventStatus() -{ - DistributedInputInject::GetInstance().UpdateSpecEventFirstStatus(false); - DistributedInputInject::GetInstance().UpdateSpecEventState(DhIdState::THROUGH_OUT); -} - void DistributedInputSourceManager::SetInputTypesMap(const std::string deviceId, uint32_t value) { if (value == static_cast(DInputDeviceType::NONE)) { diff --git a/services/source/sourcemanager/test/sourcemanagerunittest/BUILD.gn b/services/source/sourcemanager/test/sourcemanagerunittest/BUILD.gn index 3fdd814..e19e566 100755 --- a/services/source/sourcemanager/test/sourcemanagerunittest/BUILD.gn +++ b/services/source/sourcemanager/test/sourcemanagerunittest/BUILD.gn @@ -37,6 +37,7 @@ ohos_unittest("distributed_input_sourcemanager_test") { "${frameworks_path}/include", "${distributedinput_path}/inputdevicehandler/include", "${common_path}/include", + "${services_state_path}/include", "${fwk_common_path}/log/include", "${fwk_common_path}/utils/include", "${service_common}/include", @@ -111,6 +112,7 @@ ohos_unittest("distributed_input_sourcemanager_test") { deps = [ "${dfx_utils_path}:libdinput_dfx_utils", + "${utils_path}:libdinput_utils", "${distributedinput_path}/services/state:libdinput_state", "${innerkits_path}:libdinput_sdk", "${services_source_path}/transport:libdinput_source_trans", diff --git a/services/source/transport/BUILD.gn b/services/source/transport/BUILD.gn index 96e4ff5..daeb068 100755 --- a/services/source/transport/BUILD.gn +++ b/services/source/transport/BUILD.gn @@ -40,7 +40,6 @@ ohos_shared_library("libdinput_source_trans") { "${frameworks_path}/include", "${distributedinput_path}/inputdevicehandler/include", "${distributedinput_path}/services/transportbase/include", - "${distributedinput_path}/services/state/include", ] sources = [ "src/distributed_input_source_transport.cpp" ] @@ -53,7 +52,6 @@ ohos_shared_library("libdinput_source_trans") { deps = [ "${dfx_utils_path}:libdinput_dfx_utils", - "${distributedinput_path}/services/state:libdinput_state", "${distributedinput_path}/services/transportbase:libdinput_trans_base", "${services_source_path}/inputinject:libdinput_inject", "${utils_path}:libdinput_utils", diff --git a/services/source/transport/include/distributed_input_source_transport.h b/services/source/transport/include/distributed_input_source_transport.h index dd7f680..170bff4 100644 --- a/services/source/transport/include/distributed_input_source_transport.h +++ b/services/source/transport/include/distributed_input_source_transport.h @@ -29,7 +29,6 @@ #include "nlohmann/json.hpp" #include "securec.h" -#include "dinput_state.h" #include "dinput_source_trans_callback.h" #include "dinput_transbase_source_callback.h" @@ -138,6 +137,7 @@ private: std::string JointDhIds(const std::vector &dhids); void RegRespFunMap(); + void ResetKeyboardKeyState(const std::vector &dhids); private: std::mutex operationMutex_; std::set sessionIdSet_; diff --git a/services/source/transport/src/distributed_input_source_transport.cpp b/services/source/transport/src/distributed_input_source_transport.cpp index 8c61fc5..e0a846e 100644 --- a/services/source/transport/src/distributed_input_source_transport.cpp +++ b/services/source/transport/src/distributed_input_source_transport.cpp @@ -296,10 +296,6 @@ int32_t DistributedInputSourceTransport::StartRemoteInputDhids(int32_t srcTsrcSe } DHLOGI("StartRemoteInputDhids srcTsrcSeId:%d, sinkSessionId:%d.", srcTsrcSeId, sinkSessionId); - std::vector devDhIds; - SplitStringToVector(dhids, INPUT_STRING_SPLIT_POINT, devDhIds); - DInputState::GetInstance().RecordDhIds(devDhIds, DhIdState::THROUGH_IN, -1); - nlohmann::json jsonStr; jsonStr[DINPUT_SOFTBUS_KEY_CMD_TYPE] = TRANS_SOURCE_MSG_START_DHID_FOR_REL; jsonStr[DINPUT_SOFTBUS_KEY_DEVICE_ID] = deviceId; @@ -753,6 +749,16 @@ int32_t DistributedInputSourceTransport::StartRemoteInput(const std::string &dev return DH_SUCCESS; } +void DistributedInputSourceTransport::ResetKeyboardKeyState(const std::vector &dhids) +{ + std::vector keyboardNodePaths; + std::vector keyboardNodeDhIds; + DistributedInputInject::GetInstance().GetVirtualKeyboardPathsByDhIds(dhids, keyboardNodePaths, keyboardNodeDhIds); + DHLOGI("Try reset keyboard states, dhIds: %s, nodePaths: %s", + GetString(keyboardNodeDhIds).c_str(), GetString(keyboardNodePaths).c_str()); + ResetVirtualDevicePressedKeys(keyboardNodePaths); +} + int32_t DistributedInputSourceTransport::StopRemoteInput(const std::string &deviceId, const std::vector &dhids) { @@ -762,8 +768,7 @@ int32_t DistributedInputSourceTransport::StopRemoteInput(const std::string &devi return ERR_DH_INPUT_SERVER_SOURCE_TRANSPORT_STOP_FAIL; } DHLOGI("StopRemoteInput sessionId:%d.", sessionId); - - DInputState::GetInstance().RecordDhIds(dhids, DhIdState::THROUGH_OUT, -1); + ResetKeyboardKeyState(dhids); nlohmann::json jsonStr; jsonStr[DINPUT_SOFTBUS_KEY_CMD_TYPE] = TRANS_SOURCE_MSG_STOP_DHID; diff --git a/services/state/BUILD.gn b/services/state/BUILD.gn index 211e11d..bde060c 100644 --- a/services/state/BUILD.gn +++ b/services/state/BUILD.gn @@ -48,9 +48,7 @@ ohos_shared_library("libdinput_state") { deps = [ "${dfx_utils_path}:libdinput_dfx_utils", - "${services_sink_path}/inputcollector:libdinput_collector", "${services_sink_path}/transport:libdinput_sink_trans", - "${services_source_path}/inputinject:libdinput_inject", "${utils_path}:libdinput_utils", "//third_party/libevdev:libevdev", ] diff --git a/services/state/include/dinput_state.h b/services/state/include/dinput_state.h index 623a74e..e2f71e2 100644 --- a/services/state/include/dinput_state.h +++ b/services/state/include/dinput_state.h @@ -27,6 +27,16 @@ namespace OHOS { namespace DistributedHardware { namespace DistributedInput { +/* + * This enumeration class represents the two states of the peropheral: + * THROUGH_IN : The state indicates the peripheral takes effect on the local device. + * THROUGH_OUT : The state indicates that the peripheral takes effect at the remote device. + */ +enum class DhIdState { + THROUGH_IN = 0, + THROUGH_OUT, +}; + class DInputState { DECLARE_SINGLE_INSTANCE_BASE(DInputState); public: @@ -36,22 +46,41 @@ public: int32_t RemoveDhIds(const std::vector &dhIds); DhIdState GetStateByDhid(const std::string &dhId); + void AddKeyDownState(struct RawEvent event); + void RemoveKeyDownState(struct RawEvent event); + /** + * If user pressed some keys before we prepare distributed input sucess, because the monitor thread not start, + * we CAN NOT monitor those keys. + * So, we check all keys state before start input device monitor thread. + * But the keys state not contain the pressed order, so we use the key REPEAT event to move the corresponding + * cached key last. + */ + void CheckAndSetLongPressedKeyOrder(struct RawEvent event); + + /** + * Clear Device stats if unprepare. + */ + void ClearDeviceStates(); + + void RefreshABSPosition(const std::string &dhId, int32_t absX, int32_t absY); + std::pair GetAndClearABSPosition(const std::string &dhId); private: DInputState() = default; ~DInputState(); - - void CreateSpecialEventInjectThread(const int32_t sessionId, const std::vector &dhIds); - void CheckKeyboardState(const std::string &dhId, const std::string &keyboardNodePath, - std::vector &pressedKeys, int &fd); - void SpecEventInject(const int32_t sessionId, const std::vector &dhIds); - void RecordEventLog(const input_event &event); - void WriteEventToDev(const int fd, const input_event &event); - void SyncMouseKeyState(const int32_t sessionId, const std::string &mouseNodePath, - const std::string &mouseNodeDhId); + // Simulate device state to the pass through target device. + void SimulateEventInjectToSrc(const int32_t sessionId, const std::vector &dhIds); private: std::mutex operationMutex_; std::map dhIdStateMap_; + + std::mutex keyDownStateMapMtx_; + // Record key down state of each device dhid + std::unordered_map> keyDownStateMap_; + + std::mutex absPosMtx_; + // Record abs x/y of touchpad + std::unordered_map> absPositionsMap_; }; } // namespace DistributedInput } // namespace DistributedHardware diff --git a/services/state/src/dinput_state.cpp b/services/state/src/dinput_state.cpp index 1671728..b929e3e 100644 --- a/services/state/src/dinput_state.cpp +++ b/services/state/src/dinput_state.cpp @@ -22,12 +22,10 @@ #include #include -#include "constants_dinput.h" #include "dinput_errcode.h" #include "dinput_log.h" #include "dinput_utils_tool.h" #include "distributed_input_collector.h" -#include "distributed_input_inject.h" #include "distributed_input_sink_transport.h" namespace OHOS { @@ -48,8 +46,15 @@ int32_t DInputState::Init() int32_t DInputState::Release() { DHLOGI("DInputState Release."); - std::lock_guard mapLock(operationMutex_); - dhIdStateMap_.clear(); + { + std::lock_guard mapLock(operationMutex_); + dhIdStateMap_.clear(); + } + ClearDeviceStates(); + { + std::lock_guard lock(absPosMtx_); + absPositionsMap_.clear(); + } return DH_SUCCESS; } @@ -63,12 +68,8 @@ int32_t DInputState::RecordDhIds(const std::vector &dhIds, DhIdStat } if (state == DhIdState::THROUGH_OUT) { - CreateSpecialEventInjectThread(sessionId, dhIds); + SimulateEventInjectToSrc(sessionId, dhIds); } - - DistributedInputInject::GetInstance().UpdateSpecEventFirstStatus(false); - DistributedInputInject::GetInstance().UpdateSpecEventState(state); - return DH_SUCCESS; } @@ -93,171 +94,151 @@ DhIdState DInputState::GetStateByDhid(const std::string &dhId) return dhIdStateMap_[dhId]; } -void DInputState::CreateSpecialEventInjectThread(const int32_t sessionId, const std::vector &dhIds) +void DInputState::SimulateEventInjectToSrc(const int32_t sessionId, const std::vector &dhIds) { - DHLOGI("CreateSpecialEventInjectThread enter, dhIds.size = %d, sessionId = %d.", dhIds.size(), sessionId); - std::thread specEventInjectThread = - std::thread(&DInputState::SpecEventInject, this, sessionId, dhIds); - int32_t ret = pthread_setname_np(specEventInjectThread.native_handle(), CHECK_KEY_STATUS_THREAD_NAME); - if (ret != 0) { - DHLOGE("specEventInjectThread setname failed."); + DHLOGI("SimulateEventInject enter, sessionId %d, dhIds size %d", sessionId, dhIds.size()); + // mouse/keyboard/touchpad/touchscreen event send to remote device if these device pass through. + if (sessionId == -1) { + DHLOGE("SimulateEventInjectToSrc SessionId invalid"); + return; } - specEventInjectThread.detach(); -} -void DInputState::RecordEventLog(const input_event &event) -{ - std::string eventType = ""; - switch (event.type) { - case EV_KEY: - eventType = "EV_KEY"; - break; - case EV_SYN: - eventType = "EV_SYN"; - break; - default: - eventType = "other type " + std::to_string(event.type); - break; + for (const std::string &dhId : dhIds) { + // check if this device is key event + std::lock_guard mapLock(keyDownStateMapMtx_); + auto iter = keyDownStateMap_.find(dhId); + if (iter == keyDownStateMap_.end()) { + DHLOGI("The shared Device not has down state key, dhId: %s", dhId.c_str()); + continue; + } + + for (const auto &event : iter->second) { + if (event.code == BTN_TOUCH) { + DHLOGI("Simulate Touch Down event for device path: %s, dhId: %s", + event.path.c_str(), event.descriptor.c_str()); + DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, + EV_ABS, ABS_MT_TRACKING_ID, SIM_TOUCH_TRACKING_ID); + std::pair absPos = GetAndClearABSPosition(event.descriptor); + if (absPos.first != -1) { + DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, + EV_ABS, ABS_MT_POSITION_X, absPos.first); + } + + if (absPos.second != -1) { + DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, + EV_ABS, ABS_MT_POSITION_Y, absPos.second); + } + + DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, + EV_KEY, event.code, KEY_DOWN_STATE); + DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, + EV_KEY, BTN_TOOL_FINGER, KEY_DOWN_STATE); + + if (absPos.first != -1) { + DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, + EV_ABS, ABS_X, absPos.first); + } + + if (absPos.second != -1) { + DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, + EV_ABS, ABS_Y, absPos.second); + } + DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, + EV_MSC, MSC_TIMESTAMP, 0x0); + DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, + EV_SYN, SYN_REPORT, 0x0); + } else { + DHLOGI("Simulate Key event for device path: %s, dhId: %s", + event.path.c_str(), event.descriptor.c_str()); + DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, + EV_KEY, event.code, KEY_DOWN_STATE); + DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, + EV_SYN, SYN_REPORT, 0x0); + } + } + + keyDownStateMap_.erase(dhId); } - DHLOGD("5.E2E-Test Source write event into input driver, EventType: %s, Code: %d, Value: %d", - eventType.c_str(), event.code, event.value); } -void DInputState::WriteEventToDev(const int fd, const input_event &event) +void DInputState::RefreshABSPosition(const std::string &dhId, int32_t absX, int32_t absY) { - if (write(fd, &event, sizeof(event)) < static_cast(sizeof(event))) { - DHLOGE("could not inject event, removed? (fd: %d)", fd); - return; + std::lock_guard lock(absPosMtx_); + if (absX != -1) { + absPositionsMap_[dhId].first = absX; + } + + if (absY != -1) { + absPositionsMap_[dhId].second = absY; } - RecordEventLog(event); } -void DInputState::SpecEventInject(const int32_t sessionId, const std::vector &dhIds) +std::pair DInputState::GetAndClearABSPosition(const std::string &dhId) { - DHLOGI("SpecEveInject enter, sessionId %d, dhIds size %d", sessionId, dhIds.size()); - // mouse event send to remote device - if (sessionId != -1) { - std::string mouseNodePath; - std::string mouseNodeDhId; - DistributedInputCollector::GetInstance().GetMouseNodePath(dhIds, mouseNodePath, mouseNodeDhId); - SyncMouseKeyState(sessionId, mouseNodePath, mouseNodeDhId); + std::lock_guard lock(absPosMtx_); + std::pair absPos = { -1, -1 }; + if (absPositionsMap_.find(dhId) == absPositionsMap_.end()) { + return absPos; } - // keyboard up event inject local device - std::vector keyboardNodePaths; - std::vector keyboardNodeDhIds; - DistributedInputInject::GetInstance().GetVirtualKeyboardPathsByDhIds(dhIds, keyboardNodePaths, keyboardNodeDhIds); - size_t len = keyboardNodePaths.size(); - for (size_t i = 0; i < len; ++i) { - std::vector pressedKeys; - int fd = UN_INIT_FD_VALUE; - CheckKeyboardState(keyboardNodeDhIds[i], keyboardNodePaths[i], pressedKeys, fd); - struct input_event event = { - .type = EV_KEY, - .code = 0, - .value = KEY_UP_STATE - }; - for (auto &code : pressedKeys) { - event.type = EV_KEY; - event.code = code; - WriteEventToDev(fd, event); - event.type = EV_SYN; - event.code = 0; - WriteEventToDev(fd, event); - } - CloseFd(fd); - } + absPos = absPositionsMap_[dhId]; + absPositionsMap_.erase(dhId); + return absPos; } -void DInputState::CheckKeyboardState(const std::string &dhId, const std::string &keyboardNodePath, - std::vector &pressedKeys, int &fd) +void DInputState::AddKeyDownState(struct RawEvent event) { - DHLOGI("CheckKeyboardState enter, dhId %s, keyboardNodePath %s.", GetAnonyString(dhId).c_str(), - keyboardNodePath.c_str()); - char canonicalPath[PATH_MAX] = {0x00}; - if (keyboardNodePath.length() == 0 || keyboardNodePath.length() >= PATH_MAX || - realpath(keyboardNodePath.c_str(), canonicalPath) == nullptr) { - DHLOGE("keyboard Nodepath check fail, error path: %s", keyboardNodePath.c_str()); + std::lock_guard mapLock(keyDownStateMapMtx_); + keyDownStateMap_[event.descriptor].push_back(event); +} + +void DInputState::RemoveKeyDownState(struct RawEvent event) +{ + std::lock_guard mapLock(keyDownStateMapMtx_); + auto iter = keyDownStateMap_.find(event.descriptor); + if (iter == keyDownStateMap_.end()) { return; } - fd = open(canonicalPath, O_WRONLY | O_NONBLOCK); - if (fd < 0) { - DHLOGE("open keyboard Node Path error:", errno); + + auto evIter = std::find(keyDownStateMap_[event.descriptor].begin(), + keyDownStateMap_[event.descriptor].end(), event); + if (evIter == keyDownStateMap_[event.descriptor].end()) { return; } - uint32_t count = 0; - unsigned long keyState[NLONGS(KEY_CNT)] = { 0 }; - while (true) { - if (count > READ_RETRY_MAX) { - break; - } - int rc = ioctl(fd, EVIOCGKEY(sizeof(keyState)), keyState); - if (rc < 0) { - DHLOGE("read all key state failed, rc=%d ", rc); - count += 1; - std::this_thread::sleep_for(std::chrono::milliseconds(READ_SLEEP_TIME_MS)); - continue; - } - for (int32_t keyIndex = 0; keyIndex < KEY_MAX; keyIndex++) { - if (BitIsSet(keyState, keyIndex)) { - DHLOGD("keyIndex = %d, not up.", keyIndex); - pressedKeys.push_back(keyIndex); - } - } - break; + keyDownStateMap_[event.descriptor].erase(evIter); + if (keyDownStateMap_[event.descriptor].empty()) { + keyDownStateMap_.erase(event.descriptor); } } -void DInputState::SyncMouseKeyState(const int32_t sessionId, const std::string &mouseNodePath, - const std::string &mouseNodeDhId) +void DInputState::CheckAndSetLongPressedKeyOrder(struct RawEvent event) { - DHLOGI("SyncMouseKeyState enter, mouseNodePath %s, mouseNodeDhId %s, sessionId %d.", mouseNodePath.c_str(), - GetAnonyString(mouseNodeDhId).c_str(), sessionId); - char canonicalPath[PATH_MAX] = {0x00}; - if (mouseNodePath.length() == 0 || mouseNodePath.length() >= PATH_MAX || - realpath(mouseNodePath.c_str(), canonicalPath) == nullptr) { - DHLOGE("mouse Nodepath check fail, error path: %s", mouseNodePath.c_str()); + std::lock_guard mapLock(keyDownStateMapMtx_); + auto iter = keyDownStateMap_.find(event.descriptor); + if (iter == keyDownStateMap_.end()) { return; } - int fd = open(canonicalPath, O_RDONLY | O_NONBLOCK); - if (fd < 0) { - DHLOGE("open mouse Node Path error:", errno); + + auto evIter = std::find(keyDownStateMap_[event.descriptor].begin(), + keyDownStateMap_[event.descriptor].end(), event); + // If not find the cache key on pressing, or it is already the last one, just return + if (evIter == keyDownStateMap_[event.descriptor].end() || + evIter == (keyDownStateMap_[event.descriptor].end() - 1)) { return; } - uint32_t count = 0; - int leftKeyVal = 0; - int rightKeyVal = 0; - int midKeyVal = 0; - unsigned long keyState[NLONGS(KEY_CNT)] = { 0 }; - while (true) { - if (count > READ_RETRY_MAX) { - break; - } - // Query all key state - int rc = ioctl(fd, EVIOCGKEY(sizeof(keyState)), keyState); - if (rc < 0) { - DHLOGE("read all key state failed, rc=%d ", rc); - count += 1; - std::this_thread::sleep_for(std::chrono::milliseconds(READ_SLEEP_TIME_MS)); - continue; - } - leftKeyVal = BitIsSet(keyState, BTN_LEFT); - if (leftKeyVal != 0) { - DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, mouseNodeDhId, BTN_LEFT); - } - rightKeyVal = BitIsSet(keyState, BTN_RIGHT); - if (rightKeyVal != 0) { - DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, mouseNodeDhId, BTN_RIGHT); - } - midKeyVal = BitIsSet(keyState, BTN_MIDDLE); - if (midKeyVal != 0) { - DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, mouseNodeDhId, BTN_MIDDLE); - } - break; - } - CloseFd(fd); + // Ohterwhise, move the key to the last cached position. + RawEvent backEv = *evIter; + keyDownStateMap_[event.descriptor].erase(evIter); + keyDownStateMap_[event.descriptor].push_back(backEv); + DHLOGI("Find long pressed key: %d, move the cached pressed key: %d to the last position", event.code, backEv.code); +} + +void DInputState::ClearDeviceStates() +{ + std::lock_guard mapLock(keyDownStateMapMtx_); + keyDownStateMap_.clear(); } } // namespace DistributedInput } // namespace DistributedHardware diff --git a/services/transportbase/BUILD.gn b/services/transportbase/BUILD.gn index 1591138..922dce7 100644 --- a/services/transportbase/BUILD.gn +++ b/services/transportbase/BUILD.gn @@ -39,7 +39,6 @@ ohos_shared_library("libdinput_trans_base") { "${fwk_interfaces_path}/include", "${fwk_interfaces_path}/include/ipc", "${distributedinput_path}/services/transportbase/include", - "${distributedinput_path}/services/source/inputinject/include", "${distributedinput_path}/inputdevicehandler/include", ] @@ -53,7 +52,6 @@ ohos_shared_library("libdinput_trans_base") { deps = [ "${dfx_utils_path}:libdinput_dfx_utils", - "${services_source_path}/inputinject:libdinput_inject", "${utils_path}:libdinput_utils", "//third_party/libevdev:libevdev", ] diff --git a/services/transportbase/src/distributed_input_transport_base.cpp b/services/transportbase/src/distributed_input_transport_base.cpp index 43ce5aa..3c80bcb 100644 --- a/services/transportbase/src/distributed_input_transport_base.cpp +++ b/services/transportbase/src/distributed_input_transport_base.cpp @@ -30,7 +30,6 @@ #include "dinput_log.h" #include "dinput_softbus_define.h" #include "dinput_utils_tool.h" -#include "distributed_input_inject.h" #include "hidumper.h" #ifndef COMPILE_TEST_MODE @@ -189,7 +188,8 @@ int32_t DistributedInputTransportBase::StartSession(const std::string &remoteDev } std::string peerSessionName = SESSION_NAME + remoteDevId.substr(0, INTERCEPT_STRING_LENGTH); - DHLOGI("OpenInputSoftbus peerSessionName:%s", peerSessionName.c_str()); + DHLOGI("OpenInputSoftbus localSessionName: %s, peerSessionName:%s, remoteDevId: %s", + localSessionName_.c_str(), peerSessionName.c_str(), remoteDevId.c_str()); StartAsyncTrace(DINPUT_HITRACE_LABEL, DINPUT_OPEN_SESSION_START, DINPUT_OPEN_SESSION_TASK); int32_t sessionId = OpenSession(localSessionName_.c_str(), peerSessionName.c_str(), remoteDevId.c_str(), diff --git a/utils/include/dinput_utils_tool.h b/utils/include/dinput_utils_tool.h index 819e6f3..8069c16 100644 --- a/utils/include/dinput_utils_tool.h +++ b/utils/include/dinput_utils_tool.h @@ -17,6 +17,7 @@ #define OHOS_DISTRIBUTED_INPUT_UTILS_TOOL_H #include +#include #include #include "nlohmann/json.hpp" @@ -56,6 +57,14 @@ void SplitStringToVector(const std::string &str, const char split, std::vector &vecInputDevPath); + +/** + * If we pressed the sink keyboard while mouse pass throuth from source to sink, we need reset the virtual keyboard + * key states at the source side. + */ +void ResetVirtualDevicePressedKeys(const std::vector &nodePaths); + +std::string GetString(const std::vector &vec); } // namespace DistributedInput } // namespace DistributedHardware } // namespace OHOS diff --git a/utils/src/dinput_utils_tool.cpp b/utils/src/dinput_utils_tool.cpp index 9d08470..9eb87b7 100644 --- a/utils/src/dinput_utils_tool.cpp +++ b/utils/src/dinput_utils_tool.cpp @@ -51,7 +51,7 @@ namespace { constexpr int32_t DOUBLE_TIMES = 2; constexpr int32_t INT32_STRING_LENGTH = 40; constexpr uint32_t ERROR_MSG_MAX_LEN = 256; - constexpr int32_t MAX_RETRY_COUNT = 5; + constexpr int32_t MAX_RETRY_COUNT = 3; constexpr uint32_t SLEEP_TIME_US = 10 * 1000; } DevInfo GetLocalDeviceInfo() @@ -353,6 +353,92 @@ void ScanInputDevicesPath(const std::string &dirName, std::vector & } closedir(dir); } + +void RecordEventLog(const input_event &event) +{ + std::string eventType = ""; + switch (event.type) { + case EV_KEY: + eventType = "EV_KEY"; + break; + case EV_SYN: + eventType = "EV_SYN"; + break; + default: + eventType = "other type " + std::to_string(event.type); + break; + } + DHLOGD("5.E2E-Test Source write event into input driver, EventType: %s, Code: %d, Value: %d", + eventType.c_str(), event.code, event.value); +} + +void WriteEventToDevice(const int fd, const input_event &event) +{ + if (write(fd, &event, sizeof(event)) < static_cast(sizeof(event))) { + DHLOGE("could not inject event, fd: %d", fd); + return; + } + RecordEventLog(event); +} + +void ResetVirtualDevicePressedKeys(const std::vector &nodePaths) +{ + unsigned long keyState[NLONGS(KEY_CNT)] = { 0 }; + for (const auto &path : nodePaths) { + DHLOGI("Check and reset key state, path: %s", path.c_str()); + std::vector pressedKeys; + int fd = OpenInputDeviceFdByPath(path); + if (fd == -1) { + DHLOGE("Open virtual keyboard node failed, path: %s", path.c_str()); + continue; + } + + int rc = ioctl(fd, EVIOCGKEY(sizeof(keyState)), keyState); + if (rc < 0) { + DHLOGE("Read all key state failed, rc: %d, path: %s", rc, path.c_str()); + continue; + } + + for (int32_t keyIndex = 0; keyIndex < KEY_MAX; keyIndex++) { + if (BitIsSet(keyState, keyIndex)) { + DHLOGI("key index: %d pressed.", keyIndex); + pressedKeys.push_back(keyIndex); + } + } + + if (pressedKeys.empty()) { + continue; + } + + struct input_event event = { + .type = EV_KEY, + .code = 0, + .value = KEY_UP_STATE + }; + for (auto &code : pressedKeys) { + event.type = EV_KEY; + event.code = code; + WriteEventToDevice(fd, event); + event.type = EV_SYN; + event.code = 0; + WriteEventToDevice(fd, event); + } + } +} + +std::string GetString(const std::vector &vec) +{ + std::string retStr = "["; + for (uint32_t i = 0; i < vec.size(); i++) { + if (i != (vec.size() - 1)) { + retStr += vec[i] + ", "; + } else { + retStr += vec[i]; + } + } + retStr += "]"; + return retStr; +} } // namespace DistributedInput } // namespace DistributedHardware } // namespace OHOS \ No newline at end of file -- Gitee From 350ff0279fa664c924799b9eb05fdf90f9cab567 Mon Sep 17 00:00:00 2001 From: hwzhangchuang Date: Mon, 13 Nov 2023 11:24:50 +0800 Subject: [PATCH 2/5] modify gn format Signed-off-by: hwzhangchuang --- inputdevicehandler/BUILD.gn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inputdevicehandler/BUILD.gn b/inputdevicehandler/BUILD.gn index 5a45911..10e95fb 100755 --- a/inputdevicehandler/BUILD.gn +++ b/inputdevicehandler/BUILD.gn @@ -52,8 +52,8 @@ ohos_shared_library("libdinput_handler") { ] deps = [ - "${utils_path}:libdinput_utils", "${services_state_path}:libdinput_state", + "${utils_path}:libdinput_utils", "//third_party/libevdev:libevdev", "//third_party/openssl:libcrypto_shared", ] -- Gitee From 89d691a08f39b9696b0f6db471aa84d761345e6c Mon Sep 17 00:00:00 2001 From: hwzhangchuang Date: Mon, 13 Nov 2023 11:58:31 +0800 Subject: [PATCH 3/5] modify compile error Signed-off-by: hwzhangchuang --- common/include/input_hub.cpp | 2 +- common/include/input_hub.h | 4 +- .../test/sinkcollectorunittest/BUILD.gn | 1 + services/state/include/dinput_state.h | 3 +- services/state/src/dinput_state.cpp | 78 ++++++++++--------- utils/include/dinput_utils_tool.h | 2 +- 6 files changed, 50 insertions(+), 40 deletions(-) diff --git a/common/include/input_hub.cpp b/common/include/input_hub.cpp index 96736d8..c3afa22 100644 --- a/common/include/input_hub.cpp +++ b/common/include/input_hub.cpp @@ -1471,7 +1471,7 @@ void InputHub::SavePressedKeyState(const InputHub::Device *dev, int32_t keyCode) void InputHub::CheckTargetKeyState(const InputHub::Device *dev, const unsigned long *keyState) { - //If device is a mouse, record the mouse pressed key. + // If device is a mouse, record the mouse pressed key. if ((dev->classes & INPUT_DEVICE_CLASS_CURSOR) != 0) { int mouseLeftBtnState = BitIsSet(keyState, BTN_LEFT); if (mouseLeftBtnState != 0) { diff --git a/common/include/input_hub.h b/common/include/input_hub.h index bd1403f..8964fb8 100644 --- a/common/include/input_hub.h +++ b/common/include/input_hub.h @@ -44,7 +44,7 @@ inline constexpr size_t NBYTES(size_t nbits) } class InputHub { -private: +public: struct Device { Device* next; int fd; // may be -1 if device is closed @@ -73,7 +73,7 @@ private: int32_t absXIndex; int32_t absYIndex; }; -public: + InputHub(); ~InputHub(); size_t StartCollectInputEvents(RawEvent *buffer, size_t bufferSize); diff --git a/services/sink/inputcollector/test/sinkcollectorunittest/BUILD.gn b/services/sink/inputcollector/test/sinkcollectorunittest/BUILD.gn index ef849ad..0e65594 100644 --- a/services/sink/inputcollector/test/sinkcollectorunittest/BUILD.gn +++ b/services/sink/inputcollector/test/sinkcollectorunittest/BUILD.gn @@ -63,6 +63,7 @@ ohos_unittest("distributed_input_inner_sinkcollector_test") { deps = [ "${utils_path}:libdinput_utils", + "${services_state_path}:libdinput_state", "//third_party/libevdev:libevdev", "//third_party/openssl:libcrypto_shared", ] diff --git a/services/state/include/dinput_state.h b/services/state/include/dinput_state.h index e2f71e2..5dfa229 100644 --- a/services/state/include/dinput_state.h +++ b/services/state/include/dinput_state.h @@ -69,7 +69,8 @@ private: ~DInputState(); // Simulate device state to the pass through target device. void SimulateEventInjectToSrc(const int32_t sessionId, const std::vector &dhIds); - + void SimulateBtnTouchEvent(const int32_t sessionId, const std::string &dhId, const struct RawEvent &event); + void SimulateNormalEvent(const int32_t sessionId, const std::string &dhId, const struct RawEvent &event); private: std::mutex operationMutex_; std::map dhIdStateMap_; diff --git a/services/state/src/dinput_state.cpp b/services/state/src/dinput_state.cpp index b929e3e..fae078f 100644 --- a/services/state/src/dinput_state.cpp +++ b/services/state/src/dinput_state.cpp @@ -116,44 +116,11 @@ void DInputState::SimulateEventInjectToSrc(const int32_t sessionId, const std::v if (event.code == BTN_TOUCH) { DHLOGI("Simulate Touch Down event for device path: %s, dhId: %s", event.path.c_str(), event.descriptor.c_str()); - DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, - EV_ABS, ABS_MT_TRACKING_ID, SIM_TOUCH_TRACKING_ID); - std::pair absPos = GetAndClearABSPosition(event.descriptor); - if (absPos.first != -1) { - DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, - EV_ABS, ABS_MT_POSITION_X, absPos.first); - } - - if (absPos.second != -1) { - DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, - EV_ABS, ABS_MT_POSITION_Y, absPos.second); - } - - DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, - EV_KEY, event.code, KEY_DOWN_STATE); - DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, - EV_KEY, BTN_TOOL_FINGER, KEY_DOWN_STATE); - - if (absPos.first != -1) { - DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, - EV_ABS, ABS_X, absPos.first); - } - - if (absPos.second != -1) { - DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, - EV_ABS, ABS_Y, absPos.second); - } - DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, - EV_MSC, MSC_TIMESTAMP, 0x0); - DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, - EV_SYN, SYN_REPORT, 0x0); + SimulateBtnTouchEvent(sessionId, dhId, event); } else { DHLOGI("Simulate Key event for device path: %s, dhId: %s", event.path.c_str(), event.descriptor.c_str()); - DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, - EV_KEY, event.code, KEY_DOWN_STATE); - DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, - EV_SYN, SYN_REPORT, 0x0); + SimulateNormalEvent(sessionId, dhId, event); } } @@ -161,6 +128,47 @@ void DInputState::SimulateEventInjectToSrc(const int32_t sessionId, const std::v } } +void DInputState::SimulateBtnTouchEvent(const int32_t sessionId, const std::string &dhId, const struct RawEvent &event) +{ + DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, + EV_ABS, ABS_MT_TRACKING_ID, SIM_TOUCH_TRACKING_ID); + std::pair absPos = GetAndClearABSPosition(event.descriptor); + if (absPos.first != -1) { + DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, + EV_ABS, ABS_MT_POSITION_X, absPos.first); + } + if (absPos.second != -1) { + DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, + EV_ABS, ABS_MT_POSITION_Y, absPos.second); + } + + DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, + EV_KEY, event.code, KEY_DOWN_STATE); + DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, + EV_KEY, BTN_TOOL_FINGER, KEY_DOWN_STATE); + + if (absPos.first != -1) { + DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, + EV_ABS, ABS_X, absPos.first); + } + if (absPos.second != -1) { + DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, + EV_ABS, ABS_Y, absPos.second); + } + DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, + EV_MSC, MSC_TIMESTAMP, 0x0); + DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, + EV_SYN, SYN_REPORT, 0x0); +} + +void DInputState::SimulateNormalEvent(const int32_t sessionId, const std::string &dhId, const struct RawEvent &event) +{ + DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, + EV_KEY, event.code, KEY_DOWN_STATE); + DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, + EV_SYN, SYN_REPORT, 0x0); +} + void DInputState::RefreshABSPosition(const std::string &dhId, int32_t absX, int32_t absY) { std::lock_guard lock(absPosMtx_); diff --git a/utils/include/dinput_utils_tool.h b/utils/include/dinput_utils_tool.h index 8069c16..3176520 100644 --- a/utils/include/dinput_utils_tool.h +++ b/utils/include/dinput_utils_tool.h @@ -17,9 +17,9 @@ #define OHOS_DISTRIBUTED_INPUT_UTILS_TOOL_H #include -#include #include +#include #include "nlohmann/json.hpp" #include "dinput_log.h" -- Gitee From 2a9b4d837e4a0360ba2517535e96e03da9e1b57f Mon Sep 17 00:00:00 2001 From: hwzhangchuang Date: Mon, 13 Nov 2023 14:35:10 +0800 Subject: [PATCH 4/5] modify gn format Signed-off-by: hwzhangchuang --- services/sink/inputcollector/BUILD.gn | 2 +- services/source/inputinject/BUILD.gn | 2 +- .../source/sourcemanager/test/sourcemanagerunittest/BUILD.gn | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/services/sink/inputcollector/BUILD.gn b/services/sink/inputcollector/BUILD.gn index 582372f..7ff67cd 100755 --- a/services/sink/inputcollector/BUILD.gn +++ b/services/sink/inputcollector/BUILD.gn @@ -51,8 +51,8 @@ ohos_shared_library("libdinput_collector") { ] deps = [ - "${utils_path}:libdinput_utils", "${services_state_path}:libdinput_state", + "${utils_path}:libdinput_utils", "//third_party/libevdev:libevdev", "//third_party/openssl:libcrypto_shared", ] diff --git a/services/source/inputinject/BUILD.gn b/services/source/inputinject/BUILD.gn index 035da10..5b7a6da 100644 --- a/services/source/inputinject/BUILD.gn +++ b/services/source/inputinject/BUILD.gn @@ -57,8 +57,8 @@ ohos_shared_library("libdinput_inject") { deps = [ "${dfx_utils_path}:libdinput_dfx_utils", - "${utils_path}:libdinput_utils", "${services_state_path}:libdinput_state", + "${utils_path}:libdinput_utils", "//third_party/libevdev:libevdev", "//third_party/openssl:libcrypto_shared", ] diff --git a/services/source/sourcemanager/test/sourcemanagerunittest/BUILD.gn b/services/source/sourcemanager/test/sourcemanagerunittest/BUILD.gn index e19e566..9018a55 100755 --- a/services/source/sourcemanager/test/sourcemanagerunittest/BUILD.gn +++ b/services/source/sourcemanager/test/sourcemanagerunittest/BUILD.gn @@ -112,10 +112,10 @@ ohos_unittest("distributed_input_sourcemanager_test") { deps = [ "${dfx_utils_path}:libdinput_dfx_utils", - "${utils_path}:libdinput_utils", "${distributedinput_path}/services/state:libdinput_state", "${innerkits_path}:libdinput_sdk", "${services_source_path}/transport:libdinput_source_trans", + "${utils_path}:libdinput_utils", "//third_party/libevdev:libevdev", "//third_party/openssl:libcrypto_shared", ] -- Gitee From 8afd1919a9da9db5191b949114f747165b89f31d Mon Sep 17 00:00:00 2001 From: hwzhangchuang Date: Mon, 13 Nov 2023 15:14:09 +0800 Subject: [PATCH 5/5] modify gn format Signed-off-by: hwzhangchuang --- .../sink/inputcollector/test/sinkcollectorunittest/BUILD.gn | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/sink/inputcollector/test/sinkcollectorunittest/BUILD.gn b/services/sink/inputcollector/test/sinkcollectorunittest/BUILD.gn index 0e65594..7fa5be6 100644 --- a/services/sink/inputcollector/test/sinkcollectorunittest/BUILD.gn +++ b/services/sink/inputcollector/test/sinkcollectorunittest/BUILD.gn @@ -62,8 +62,8 @@ ohos_unittest("distributed_input_inner_sinkcollector_test") { ] deps = [ - "${utils_path}:libdinput_utils", "${services_state_path}:libdinput_state", + "${utils_path}:libdinput_utils", "//third_party/libevdev:libevdev", "//third_party/openssl:libcrypto_shared", ] -- Gitee