diff --git a/common/include/input_hub.cpp b/common/include/input_hub.cpp index afbbecb..7de764f 100644 --- a/common/include/input_hub.cpp +++ b/common/include/input_hub.cpp @@ -201,6 +201,12 @@ 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; @@ -254,6 +260,13 @@ 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 83ff337..9e6e64c 100644 --- a/common/include/input_hub.h +++ b/common/include/input_hub.h @@ -151,6 +151,7 @@ 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 b4ade68..d600479 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, -1); + DInputState::GetInstance().RecordDhIds(stopOnCmdDhIds, DhIdState::THROUGH_IN, sessionId); 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, -1); + DInputState::GetInstance().RecordDhIds(stopOnCmdDhIds, DhIdState::THROUGH_IN, toSinkSessionId); if (DistributedInputCollector::GetInstance().IsAllDevicesStoped()) { DHLOGE("All dhid stop sharing, sessionId: %d is closed.", toSinkSessionId); diff --git a/services/state/include/dinput_state.h b/services/state/include/dinput_state.h index 5dfa229..5b217ff 100644 --- a/services/state/include/dinput_state.h +++ b/services/state/include/dinput_state.h @@ -16,6 +16,7 @@ #ifndef DISTRIBUTED_INPUT_STATE_BASE_H #define DISTRIBUTED_INPUT_STATE_BASE_H +#include #include #include #include @@ -64,6 +65,16 @@ 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(); @@ -82,6 +93,7 @@ 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 846b5e2..9c29850 100644 --- a/services/state/src/dinput_state.cpp +++ b/services/state/src/dinput_state.cpp @@ -70,6 +70,7 @@ int32_t DInputState::RecordDhIds(const std::vector &dhIds, DhIdStat if (state == DhIdState::THROUGH_OUT) { SimulateEventInjectToSrc(sessionId, dhIds); } + lastSessionId_ = sessionId; return DH_SUCCESS; } @@ -167,6 +168,46 @@ 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, @@ -200,6 +241,13 @@ 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_);