diff --git a/common/include/input_hub.cpp b/common/include/input_hub.cpp index 1db2a6f..afbbecb 100644 --- a/common/include/input_hub.cpp +++ b/common/include/input_hub.cpp @@ -201,12 +201,6 @@ size_t InputHub::GetEvents(RawEvent *buffer, size_t bufferSize) return event - buffer; } -bool InputHub::IsTouchPad(Device *device) -{ - return ((device->classes & INPUT_DEVICE_CLASS_TOUCH_MT) || (device->classes & INPUT_DEVICE_CLASS_TOUCH)) && - IsTouchPad(device->identifier); -} - bool InputHub::IsTouchPad(const InputDevice &inputDevice) { std::string dhName = inputDevice.name; @@ -260,13 +254,6 @@ void InputHub::RecordDeviceChangeStates(Device *device, struct input_event readB if (event.type == EV_ABS && (event.code == ABS_MT_POSITION_Y || event.code == ABS_Y)) { DInputState::GetInstance().RefreshABSPosition(event.descriptor, -1, event.value); } - - if (IsTouchPad(device) && event.type == EV_KEY && event.code == BTN_MOUSE && event.value == KEY_UP_STATE && - !DInputState::GetInstance().IsDhIdDown(event.descriptor)) { - DHLOGI("Find touchpad UP state that not down effective at sink side, dhId: %s", - event.descriptor.c_str()); - DInputState::GetInstance().SimulateTouchPadUpState(event.descriptor, event); - } DHLOGD("RecordDeviceChangeStates end."); } } diff --git a/common/include/input_hub.h b/common/include/input_hub.h index 9e6e64c..83ff337 100644 --- a/common/include/input_hub.h +++ b/common/include/input_hub.h @@ -151,7 +151,6 @@ private: bool ContainsNonZeroByte(const uint8_t *array, uint32_t startIndex, uint32_t endIndex); int64_t ProcessEventTimestamp(const input_event &event); bool IsTouchPad(const InputDevice &inputDevice); - bool IsTouchPad(Device *device); /* * this macro is used to tell if "bit" is set in "array" diff --git a/services/sink/sinkmanager/src/distributed_input_sink_manager.cpp b/services/sink/sinkmanager/src/distributed_input_sink_manager.cpp index d600479..b4ade68 100644 --- a/services/sink/sinkmanager/src/distributed_input_sink_manager.cpp +++ b/services/sink/sinkmanager/src/distributed_input_sink_manager.cpp @@ -320,7 +320,7 @@ void DistributedInputSinkManager::DInputSinkListener::OnStopRemoteInputDhid(cons stopIndeedOnes.noSharingDhIds = stopIndeedDhIds; DistributedInputCollector::GetInstance().ReportDhIdSharingState(stopIndeedOnes); - DInputState::GetInstance().RecordDhIds(stopOnCmdDhIds, DhIdState::THROUGH_IN, sessionId); + DInputState::GetInstance().RecordDhIds(stopOnCmdDhIds, DhIdState::THROUGH_IN, -1); if (DistributedInputCollector::GetInstance().IsAllDevicesStoped()) { DHLOGE("All dhid stop sharing, sessionId: %d is closed.", sessionId); @@ -387,7 +387,7 @@ void DistributedInputSinkManager::DInputSinkListener::OnRelayStopDhidRemoteInput stopIndeedOnes.noSharingDhIds = stopIndeedDhIds; DistributedInputCollector::GetInstance().ReportDhIdSharingState(stopIndeedOnes); - DInputState::GetInstance().RecordDhIds(stopOnCmdDhIds, DhIdState::THROUGH_IN, toSinkSessionId); + DInputState::GetInstance().RecordDhIds(stopOnCmdDhIds, DhIdState::THROUGH_IN, -1); if (DistributedInputCollector::GetInstance().IsAllDevicesStoped()) { DHLOGE("All dhid stop sharing, sessionId: %d is closed.", toSinkSessionId); diff --git a/services/source/inputinject/include/distributed_input_inject.h b/services/source/inputinject/include/distributed_input_inject.h index cb4951a..c03fd82 100644 --- a/services/source/inputinject/include/distributed_input_inject.h +++ b/services/source/inputinject/include/distributed_input_inject.h @@ -50,6 +50,7 @@ public: void NotifyNodeMgrScanVirNode(const std::string &devId, const std::string &dhId); void GetVirtualKeyboardPaths(const std::string &devId, const std::vector &dhIds, std::vector &virKeyboardPaths); + void ResetTouchPadBtnMouseState(const std::string &deviceId, const std::vector &dhIds); 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 ace7b0e..9e3aec0 100644 --- a/services/source/inputinject/include/distributed_input_node_manager.h +++ b/services/source/inputinject/include/distributed_input_node_manager.h @@ -68,6 +68,7 @@ public: int32_t GetVirtualTouchScreenFd(); void ProcessInjectEvent(const EventBatch &events); + void ResetTouchPadBtnMouseState(const std::string &deviceId, const std::vector &dhIds); /** * @brief Get the Virtual Keyboard Paths By Dh Ids object @@ -114,6 +115,18 @@ private: void SetPathForVirDev(const DhUniqueID &dhUniqueId, const std::string &devicePath); void RunInjectEventCallback(const std::string &dhId, const uint32_t injectEvent); + void RecordEvents(const RawEvent &event, const VirtualDevice* device); + bool IsTouchPad(const std::string &deviceName); + + void AddBtnMouseDownState(int32_t fd); + void RemoveBtnMouseDownState(int32_t fd); + void RecordChangeEventLog(const RawEvent &event); + void RefreshABSPosition(int32_t fd, int32_t absX, int32_t absY); + void ClearCachedState(int32_t fd); + + void SimulateTouchPadUpState(const std::string &deviceId, const std::string &dhId, + int32_t fd, int32_t dx, int32_t dy); + /* the key is {networkId, dhId}, and the value is virtualDevice */ std::map> virtualDeviceMap_; std::mutex virtualDeviceMapMutex_; @@ -129,6 +142,13 @@ private: std::once_flag callOnceFlag_; std::shared_ptr callBackHandler_; sptr SessionStateCallback_; + + std::mutex absPosMtx_; + // Record abs x/y of touchpad, {fd, {dx, dy}} + std::unordered_map> absPositionsMap_; + + std::mutex downBtnMouseFdsMtx_; + std::set downTouchPadBtnMouseFds_; }; } // namespace DistributedInput } // namespace DistributedHardware diff --git a/services/source/inputinject/include/virtual_device.h b/services/source/inputinject/include/virtual_device.h index bcec29e..e92b477 100644 --- a/services/source/inputinject/include/virtual_device.h +++ b/services/source/inputinject/include/virtual_device.h @@ -50,6 +50,7 @@ public: int32_t GetDeviceFd(); uint16_t GetDeviceType(); + std::string GetDeviceName(); private: int32_t fd_ = -1; diff --git a/services/source/inputinject/src/distributed_input_inject.cpp b/services/source/inputinject/src/distributed_input_inject.cpp index 8f53ecf..719882b 100644 --- a/services/source/inputinject/src/distributed_input_inject.cpp +++ b/services/source/inputinject/src/distributed_input_inject.cpp @@ -220,6 +220,17 @@ void DistributedInputInject::NotifyNodeMgrScanVirNode(const std::string &devId, } inputNodeManager_->NotifyNodeMgrScanVirNode(devId, dhId); } + +void DistributedInputInject::ResetTouchPadBtnMouseState(const std::string &deviceId, + const std::vector &dhIds) +{ + std::lock_guard lock(inputNodeManagerMutex_); + if (inputNodeManager_ == nullptr) { + DHLOGE("ResetTouchPadBtnMouseState inputNodeManager is nullptr"); + return; + } + inputNodeManager_->ResetTouchPadBtnMouseState(deviceId, dhIds); +} } // 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 a429a98..34953f8 100644 --- a/services/source/inputinject/src/distributed_input_node_manager.cpp +++ b/services/source/inputinject/src/distributed_input_node_manager.cpp @@ -513,6 +513,202 @@ void DistributedInputNodeManager::RunInjectEventCallback(const std::string &dhId SessionStateCallback_->OnResult(dhId, DINPUT_INJECT_EVENT_FAIL); } +bool DistributedInputNodeManager::IsTouchPad(const std::string &deviceName) +{ + DHLOGD("device name is %s.", deviceName.c_str()); + transform(deviceName.begin(), deviceName.end(), deviceName.begin(), ::tolower); + if (deviceName.find(DH_TOUCH_PAD) == std::string::npos) { + return false; + } + return true; +} + +void DistributedInputNodeManager::AddBtnMouseDownState(int32_t fd) +{ + std::lock_guard mapLock(downBtnMouseFdsMtx_); + downTouchPadBtnMouseFds_.insert(fd); +} + +void DistributedInputNodeManager::RemoveBtnMouseDownState(int32_t fd) +{ + std::lock_guard mapLock(downBtnMouseFdsMtx_); + downTouchPadBtnMouseFds_.erase(fd); +} + +void DistributedInputNodeManager::ClearCachedState(int32_t fd) +{ + std::lock_guard lock(absPosMtx_); + absPositionsMap_.erase(fd); + + std::lock_guard mapLock(downBtnMouseFdsMtx_); + downTouchPadBtnMouseFds_.erase(fd); +} + +void DistributedInputNodeManager::RecordEvents(const RawEvent &event, const VirtualDevice* device) +{ + bool isTouchEvent = false; + if (((device->GetClasses() & INPUT_DEVICE_CLASS_TOUCH_MT) || (device->GetClasses() & INPUT_DEVICE_CLASS_TOUCH)) && + IsTouchPad(device->GetDeviceName())) { + isTouchEvent = true; + } + + if (!isTouchEvent) { + return; + } + + if (event.type == EV_ABS && (event.code == ABS_MT_POSITION_X || event.code == ABS_X)) { + RefreshABSPosition(device->GetDeviceFd(), event.value, -1); + } + + if (event.type == EV_ABS && (event.code == ABS_MT_POSITION_Y || event.code == ABS_Y)) { + RefreshABSPosition(device->GetDeviceFd(), -1, event.value); + } + + // Deal btn mouse state + if (event.type == EV_KEY && event.code == BTN_MOUSE && event.value == KEY_DOWN_STATE) { + AddBtnMouseDownState(event); + RecordChangeEventLog(event); + } + + if (event.type == EV_KEY && event.code == BTN_MOUSE && event.value == KEY_UP_STATE) { + RemoveBtnMouseDownState(event); + RecordChangeEventLog(event); + } +} + +void DistributedInputNodeManager::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; + } + DHLOGI("6.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 DistributedInputNodeManager::RefreshABSPosition(int32_t fd, int32_t absX, int32_t absY) +{ + std::lock_guard lock(absPosMtx_); + if (absX != -1) { + absPositionsMap_[fd].first = absX; + } + + if (absY != -1) { + absPositionsMap_[fd].second = absY; + } +} + +void DistributedInputNodeManager::ResetTouchPadBtnMouseState(const std::string &deviceId, + const std::vector &dhIds) +{ + VirtualDevice* device = nullptr; + bool isTouchPad = false; + for (auto const &dhId : dhIds) { + if (GetDevice(deviceId, dhId, device) < 0 || device == nullptr) { + DHLOGE("could not find the device"); + continue; + } + + if (((device->GetClasses() & INPUT_DEVICE_CLASS_TOUCH_MT) || + (device->GetClasses() & INPUT_DEVICE_CLASS_TOUCH)) && + IsTouchPad(device->GetDeviceName())) { + isTouchPad = true; + } + + if (!isTouchPad) { + continue; + } + + int32_t fd = device->GetDeviceFd(); + + DHLOGI("Find the touchpad stopped, try reset it's state, deviceId: %s, dhId: %s, fd: %d", + deviceId.c_str(), dhId.c_str(), fd); + int32_t dx = -1; + int32_t dy = -1; + { + std::lock_guard lock(downBtnMouseFdsMtx_); + if (downTouchPadBtnMouseFds_.count(fd) == 0) { + continue; + } else { + downTouchPadBtnMouseFds_.erase(fd); + DHLOGI("Find this touchpad fd should reset, fd: %d", fd); + } + } + + { + std::lock_guard lock(absPosMtx_); + if (absPositionsMap_.count(fd) == 0) { + DHLOGE("Find touch pad need reset, but CAN NOT find dx,dy"); + dx = 0; + dy = 0; + } else { + dx = absPositionsMap_[fd].first; + dy = absPositionsMap_[fd].second; + absPositionsMap_.erase(fd); + } + } + SimulateTouchPadUpState(deviceId, dhId, fd, dx, dy); + } +} + +void DistributedInputNodeManager::SimulateTouchPadUpState(const std::string &deviceId, const std::string &dhId, + int32_t fd, int32_t dx, int32_t dy) +{ + DHLOGI("Sinmulate touch pad UP state events, deviceId: %s, dhId: %s, fd: %d, dx: %d, dy: %d", + deviceId.c_str(), dhId.c_str(), fd, dx, dy); + int32_t simTrackingId = 0xffffffff; + input_event touchTrackingIdEv1 = { EV_ABS, ABS_MT_TRACKING_ID, simTrackingId }; + input_event btnToolFingerDownEv = { EV_KEY, BTN_TOOL_FINGER, KEY_DOWN_STATE }; + input_event btnToolDoubleTapUpEv = { EV_KEY, BTN_TOOL_DOUBLETAP, KEY_UP_STATE }; + input_event mscEv1 = { EV_MSC, MSC_TIMESTAMP, 0x0 }; + input_event sycReportEv1 = { EV_SYN, SYN_REPORT, 0x0 }; + + input_event absMtPosX1 = { EV_ABS, ABS_MT_POSITION_X, dx }; + input_event absMtPosY1 = { EV_ABS, ABS_MT_POSITION_Y, dy }; + input_event absPosX1 = { EV_ABS, ABS_X, dx }; + input_event absPosY1 = { EV_ABS, ABS_Y, dy }; + input_event mscEv2 = { EV_MSC, MSC_TIMESTAMP, 0x0 }; + input_event sycReportEv2 = { EV_SYN, SYN_REPORT, 0x0 }; + + input_event absMtPosX2 = { EV_ABS, ABS_MT_POSITION_X, dx }; + input_event absMtPosY2 = { EV_ABS, ABS_MT_POSITION_Y, dy }; + input_event btnMouseUpEv = { EV_KEY, BTN_MOUSE, KEY_UP_STATE }; + input_event absPosX2 = { EV_ABS, ABS_X, dx }; + input_event absPosY2 = { EV_ABS, ABS_Y, dy }; + input_event mscEv3 = { EV_MSC, MSC_TIMESTAMP, 0x0 }; + input_event sycReportEv3 = { EV_SYN, SYN_REPORT, 0x0 }; + + input_event touchTrackingIdEv2 = { EV_ABS, ABS_MT_TRACKING_ID, simTrackingId }; + input_event btnTouchUpEv = { EV_KEY, BTN_TOUCH, KEY_UP_STATE }; + input_event btnToolFingerUpEv = { EV_KEY, BTN_TOOL_FINGER, KEY_UP_STATE }; + input_event mscEv4 = { EV_MSC, MSC_TIMESTAMP, 0x0 }; + input_event sycReportEv4 = { EV_SYN, SYN_REPORT, 0x0 }; + + std::vector simEvents = { + touchTrackingIdEv1, btnToolFingerDownEv, btnToolDoubleTapUpEv, mscEv1, sycReportEv1, + absMtPosX1, absMtPosY1, absPosX1, absPosY1, mscEv2, sycReportEv2, + absMtPosX2, absMtPosY2, btnMouseUpEv, absPosX2, absPosY2, mscEv3, sycReportEv3, + touchTrackingIdEv2, btnTouchUpEv, btnToolFingerUpEv, mscEv4, sycReportEv4 }; + for (auto &event : simEvents) { + WriteEventToDevice(fd, event); + } +} + void DistributedInputNodeManager::ProcessInjectEvent(const EventBatch &events) { std::string deviceId = events.first; @@ -532,6 +728,7 @@ void DistributedInputNodeManager::ProcessInjectEvent(const EventBatch &events) return; } if (device != nullptr) { + RecordEvents(rawEvent, device); device->InjectInputEvent(event); } } diff --git a/services/source/inputinject/src/virtual_device.cpp b/services/source/inputinject/src/virtual_device.cpp index f75dcbf..498bc0f 100644 --- a/services/source/inputinject/src/virtual_device.cpp +++ b/services/source/inputinject/src/virtual_device.cpp @@ -211,6 +211,11 @@ uint16_t VirtualDevice::GetClasses() return classes_; } +std::string VirtualDevice::GetDeviceName() +{ + return deviceName_; +} + void VirtualDevice::RecordEventLog(const input_event &event) { std::string eventType = ""; diff --git a/services/source/transport/src/distributed_input_source_transport.cpp b/services/source/transport/src/distributed_input_source_transport.cpp index 48fd7a7..1ab15f7 100644 --- a/services/source/transport/src/distributed_input_source_transport.cpp +++ b/services/source/transport/src/distributed_input_source_transport.cpp @@ -328,6 +328,7 @@ int32_t DistributedInputSourceTransport::StopRemoteInputDhids(int32_t srcTsrcSeI DHLOGI("StopRemoteInputDhids srcTsrcSeId:%d, sinkSessionId:%d.", srcTsrcSeId, sinkSessionId); std::vector dhIdsVec = SplitDhIdString(dhids); ResetKeyboardKeyState(deviceId, dhIdsVec); + ResetTouchPadBtnMouseState(deviceId, dhIdsVec); nlohmann::json jsonStr; jsonStr[DINPUT_SOFTBUS_KEY_CMD_TYPE] = TRANS_SOURCE_MSG_STOP_DHID_FOR_REL; @@ -775,6 +776,7 @@ int32_t DistributedInputSourceTransport::StopRemoteInput(const std::string &devi } DHLOGI("StopRemoteInput sessionId:%d.", sessionId); ResetKeyboardKeyState(deviceId, dhids); + ResetTouchPadBtnMouseState(deviceId, dhids); nlohmann::json jsonStr; jsonStr[DINPUT_SOFTBUS_KEY_CMD_TYPE] = TRANS_SOURCE_MSG_STOP_DHID; diff --git a/services/state/include/dinput_state.h b/services/state/include/dinput_state.h index 5b217ff..5dfa229 100644 --- a/services/state/include/dinput_state.h +++ b/services/state/include/dinput_state.h @@ -16,7 +16,6 @@ #ifndef DISTRIBUTED_INPUT_STATE_BASE_H #define DISTRIBUTED_INPUT_STATE_BASE_H -#include #include #include #include @@ -65,16 +64,6 @@ public: void RefreshABSPosition(const std::string &dhId, int32_t absX, int32_t absY); std::pair GetAndClearABSPosition(const std::string &dhId); - - void SimulateTouchPadUpState(const std::string &dhId, const struct RawEvent &event); - /** - * @brief check is one device in down state - * - * @param dhId the dhid - * @return true in down state - * @return false NOT in down state - */ - bool IsDhIdDown(const std::string &dhId); private: DInputState() = default; ~DInputState(); @@ -93,7 +82,6 @@ private: std::mutex absPosMtx_; // Record abs x/y of touchpad std::unordered_map> absPositionsMap_; - std::atomic lastSessionId_ {0}; }; } // namespace DistributedInput } // namespace DistributedHardware diff --git a/services/state/src/dinput_state.cpp b/services/state/src/dinput_state.cpp index 9c29850..846b5e2 100644 --- a/services/state/src/dinput_state.cpp +++ b/services/state/src/dinput_state.cpp @@ -70,7 +70,6 @@ int32_t DInputState::RecordDhIds(const std::vector &dhIds, DhIdStat if (state == DhIdState::THROUGH_OUT) { SimulateEventInjectToSrc(sessionId, dhIds); } - lastSessionId_ = sessionId; return DH_SUCCESS; } @@ -168,46 +167,6 @@ void DInputState::SimulateBtnTouchEvent(const int32_t sessionId, const std::stri DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsgBatch(sessionId, simEvents); } -void DInputState::SimulateTouchPadUpState(const std::string &dhId, const struct RawEvent &event) -{ - DHLOGI("Sinmulate touch pad UP state to source, dhId: %s", dhId.c_str()); - int32_t simTrackingId = 0xffffffff; - std::vector simEvents; - RawEvent touchTrackingIdEv1 = { event.when, EV_ABS, ABS_MT_TRACKING_ID, simTrackingId, dhId, event.path }; - simEvents.push_back(touchTrackingIdEv1); - - RawEvent btnToolFingerDownEv = { event.when, EV_KEY, BTN_TOOL_FINGER, KEY_DOWN_STATE, dhId, event.path }; - simEvents.push_back(btnToolFingerDownEv); - - RawEvent btnToolDoubleTapUpEv = { event.when, EV_KEY, BTN_TOOL_DOUBLETAP, KEY_UP_STATE, dhId, event.path }; - simEvents.push_back(btnToolDoubleTapUpEv); - - RawEvent mscEv1 = { event.when, EV_MSC, MSC_TIMESTAMP, 0x0, dhId, event.path }; - simEvents.push_back(mscEv1); - - RawEvent sycReportEv1 = { event.when, EV_SYN, SYN_REPORT, 0x0, dhId, event.path }; - simEvents.push_back(sycReportEv1); - - RawEvent btnMouseUpEv = { event.when, EV_KEY, BTN_MOUSE, KEY_UP_STATE, dhId, event.path }; - simEvents.push_back(btnMouseUpEv); - - RawEvent touchTrackingIdEv2 = { event.when, EV_ABS, ABS_MT_TRACKING_ID, simTrackingId, dhId, event.path }; - simEvents.push_back(touchTrackingIdEv2); - - RawEvent btnTouchUpEv = { event.when, EV_KEY, BTN_TOUCH, KEY_UP_STATE, dhId, event.path }; - simEvents.push_back(btnTouchUpEv); - - RawEvent btnToolFingerUpEv = { event.when, EV_KEY, BTN_TOOL_FINGER, KEY_UP_STATE, dhId, event.path }; - simEvents.push_back(btnToolFingerDownEv); - - RawEvent mscEv2 = { event.when, EV_MSC, MSC_TIMESTAMP, 0x0, dhId, event.path }; - simEvents.push_back(mscEv2); - - RawEvent sycReportEv2 = { event.when, EV_SYN, SYN_REPORT, 0x0, dhId, event.path }; - simEvents.push_back(sycReportEv2); - DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsgBatch(lastSessionId_, simEvents); -} - void DInputState::SimulateNormalEvent(const int32_t sessionId, const std::string &dhId, const struct RawEvent &event) { DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, @@ -241,13 +200,6 @@ std::pair DInputState::GetAndClearABSPosition(const std::strin return absPos; } -bool DInputState::IsDhIdDown(const std::string &dhId) -{ - std::lock_guard mapLock(keyDownStateMapMtx_); - auto iter = keyDownStateMap_.find(dhId); - return iter != keyDownStateMap_.end(); -} - void DInputState::AddKeyDownState(struct RawEvent event) { std::lock_guard mapLock(keyDownStateMapMtx_);