12d4d9a4dSopenharmony_ci/* 22d4d9a4dSopenharmony_ci * Copyright (c) 2023-2024 Huawei Device Co., Ltd. 32d4d9a4dSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 42d4d9a4dSopenharmony_ci * you may not use this file except in compliance with the License. 52d4d9a4dSopenharmony_ci * You may obtain a copy of the License at 62d4d9a4dSopenharmony_ci * 72d4d9a4dSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 82d4d9a4dSopenharmony_ci * 92d4d9a4dSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 102d4d9a4dSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 112d4d9a4dSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 122d4d9a4dSopenharmony_ci * See the License for the specific language governing permissions and 132d4d9a4dSopenharmony_ci * limitations under the License. 142d4d9a4dSopenharmony_ci */ 152d4d9a4dSopenharmony_ci 162d4d9a4dSopenharmony_ci#include "dinput_sink_state.h" 172d4d9a4dSopenharmony_ci 182d4d9a4dSopenharmony_ci#include <dirent.h> 192d4d9a4dSopenharmony_ci#include <fcntl.h> 202d4d9a4dSopenharmony_ci#include <pthread.h> 212d4d9a4dSopenharmony_ci#include <thread> 222d4d9a4dSopenharmony_ci#include <unistd.h> 232d4d9a4dSopenharmony_ci#include <vector> 242d4d9a4dSopenharmony_ci 252d4d9a4dSopenharmony_ci#include "dinput_errcode.h" 262d4d9a4dSopenharmony_ci#include "dinput_log.h" 272d4d9a4dSopenharmony_ci#include "dinput_utils_tool.h" 282d4d9a4dSopenharmony_ci#include "distributed_input_collector.h" 292d4d9a4dSopenharmony_ci#include "distributed_input_sink_transport.h" 302d4d9a4dSopenharmony_ci 312d4d9a4dSopenharmony_cinamespace OHOS { 322d4d9a4dSopenharmony_cinamespace DistributedHardware { 332d4d9a4dSopenharmony_cinamespace DistributedInput { 342d4d9a4dSopenharmony_ciIMPLEMENT_SINGLE_INSTANCE(DInputSinkState); 352d4d9a4dSopenharmony_ciDInputSinkState::~DInputSinkState() 362d4d9a4dSopenharmony_ci{ 372d4d9a4dSopenharmony_ci Release(); 382d4d9a4dSopenharmony_ci} 392d4d9a4dSopenharmony_ci 402d4d9a4dSopenharmony_ciint32_t DInputSinkState::Init() 412d4d9a4dSopenharmony_ci{ 422d4d9a4dSopenharmony_ci DHLOGI("DInputSinkState Init."); 432d4d9a4dSopenharmony_ci touchPadEventFragMgr_ = std::make_shared<TouchPadEventFragmentMgr>(); 442d4d9a4dSopenharmony_ci return DH_SUCCESS; 452d4d9a4dSopenharmony_ci} 462d4d9a4dSopenharmony_ci 472d4d9a4dSopenharmony_ciint32_t DInputSinkState::Release() 482d4d9a4dSopenharmony_ci{ 492d4d9a4dSopenharmony_ci DHLOGI("DInputSinkState Release."); 502d4d9a4dSopenharmony_ci { 512d4d9a4dSopenharmony_ci std::lock_guard<std::mutex> mapLock(operationMutex_); 522d4d9a4dSopenharmony_ci dhIdStateMap_.clear(); 532d4d9a4dSopenharmony_ci } 542d4d9a4dSopenharmony_ci ClearDeviceStates(); 552d4d9a4dSopenharmony_ci return DH_SUCCESS; 562d4d9a4dSopenharmony_ci} 572d4d9a4dSopenharmony_ci 582d4d9a4dSopenharmony_ciint32_t DInputSinkState::RecordDhIds(const std::vector<std::string> &dhIds, DhIdState state, const int32_t sessionId) 592d4d9a4dSopenharmony_ci{ 602d4d9a4dSopenharmony_ci DHLOGI("RecordDhIds dhIds size = %{public}zu", dhIds.size()); 612d4d9a4dSopenharmony_ci std::lock_guard<std::mutex> mapLock(operationMutex_); 622d4d9a4dSopenharmony_ci for (const auto &dhid : dhIds) { 632d4d9a4dSopenharmony_ci DHLOGD("add dhid : %{public}s, state : %{public}d.", GetAnonyString(dhid).c_str(), state); 642d4d9a4dSopenharmony_ci dhIdStateMap_[dhid] = state; 652d4d9a4dSopenharmony_ci } 662d4d9a4dSopenharmony_ci 672d4d9a4dSopenharmony_ci if (state == DhIdState::THROUGH_OUT) { 682d4d9a4dSopenharmony_ci SimulateEventInjectToSrc(sessionId, dhIds); 692d4d9a4dSopenharmony_ci } 702d4d9a4dSopenharmony_ci lastSessionId_ = sessionId; 712d4d9a4dSopenharmony_ci return DH_SUCCESS; 722d4d9a4dSopenharmony_ci} 732d4d9a4dSopenharmony_ci 742d4d9a4dSopenharmony_ciint32_t DInputSinkState::RemoveDhIds(const std::vector<std::string> &dhIds) 752d4d9a4dSopenharmony_ci{ 762d4d9a4dSopenharmony_ci DHLOGI("RemoveDhIds dhIds size = %{public}zu", dhIds.size()); 772d4d9a4dSopenharmony_ci std::lock_guard<std::mutex> mapLock(operationMutex_); 782d4d9a4dSopenharmony_ci for (const auto &dhid : dhIds) { 792d4d9a4dSopenharmony_ci DHLOGD("delete dhid : %{public}s", GetAnonyString(dhid).c_str()); 802d4d9a4dSopenharmony_ci dhIdStateMap_.erase(dhid); 812d4d9a4dSopenharmony_ci } 822d4d9a4dSopenharmony_ci return DH_SUCCESS; 832d4d9a4dSopenharmony_ci} 842d4d9a4dSopenharmony_ci 852d4d9a4dSopenharmony_cistd::shared_ptr<TouchPadEventFragmentMgr> DInputSinkState::GetTouchPadEventFragMgr() 862d4d9a4dSopenharmony_ci{ 872d4d9a4dSopenharmony_ci return this->touchPadEventFragMgr_; 882d4d9a4dSopenharmony_ci} 892d4d9a4dSopenharmony_ci 902d4d9a4dSopenharmony_ciDhIdState DInputSinkState::GetStateByDhid(const std::string &dhId) 912d4d9a4dSopenharmony_ci{ 922d4d9a4dSopenharmony_ci std::lock_guard<std::mutex> mapLock(operationMutex_); 932d4d9a4dSopenharmony_ci if (dhIdStateMap_.find(dhId) == dhIdStateMap_.end()) { 942d4d9a4dSopenharmony_ci DHLOGE("dhId : %{public}s not exist.", GetAnonyString(dhId).c_str()); 952d4d9a4dSopenharmony_ci return DhIdState::THROUGH_IN; 962d4d9a4dSopenharmony_ci } 972d4d9a4dSopenharmony_ci return dhIdStateMap_[dhId]; 982d4d9a4dSopenharmony_ci} 992d4d9a4dSopenharmony_ci 1002d4d9a4dSopenharmony_civoid DInputSinkState::SimulateMouseBtnMouseUpState(const std::string &dhId, const struct RawEvent &event) 1012d4d9a4dSopenharmony_ci{ 1022d4d9a4dSopenharmony_ci DHLOGI("Sinmulate Mouse BTN_MOUSE UP state to source, dhId: %{public}s", GetAnonyString(dhId).c_str()); 1032d4d9a4dSopenharmony_ci int32_t scanId = GetRandomInt32(0, INT32_MAX); 1042d4d9a4dSopenharmony_ci RawEvent mscScanEv = { event.when, EV_MSC, MSC_SCAN, scanId, dhId, event.path }; 1052d4d9a4dSopenharmony_ci RawEvent btnMouseUpEv = { event.when, EV_KEY, BTN_MOUSE, KEY_UP_STATE, dhId, event.path }; 1062d4d9a4dSopenharmony_ci RawEvent sycReportEv = { event.when, EV_SYN, SYN_REPORT, 0x0, dhId, event.path }; 1072d4d9a4dSopenharmony_ci 1082d4d9a4dSopenharmony_ci std::vector<RawEvent> simEvents = { mscScanEv, btnMouseUpEv, sycReportEv }; 1092d4d9a4dSopenharmony_ci DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsgBatch(lastSessionId_, simEvents); 1102d4d9a4dSopenharmony_ci} 1112d4d9a4dSopenharmony_ci 1122d4d9a4dSopenharmony_civoid DInputSinkState::SimulateTouchPadStateReset(const std::vector<RawEvent> &events) 1132d4d9a4dSopenharmony_ci{ 1142d4d9a4dSopenharmony_ci DHLOGI("SimulateTouchPadStateReset events size: %{public}zu", events.size()); 1152d4d9a4dSopenharmony_ci DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsgBatch(lastSessionId_, events); 1162d4d9a4dSopenharmony_ci} 1172d4d9a4dSopenharmony_ci 1182d4d9a4dSopenharmony_civoid DInputSinkState::SimulateEventInjectToSrc(const int32_t sessionId, const std::vector<std::string> &dhIds) 1192d4d9a4dSopenharmony_ci{ 1202d4d9a4dSopenharmony_ci DHLOGI("SimulateEventInject enter, sessionId %{public}d, dhIds size %{public}zu", sessionId, dhIds.size()); 1212d4d9a4dSopenharmony_ci // mouse/keyboard/touchpad/touchscreen event send to remote device if these device pass through. 1222d4d9a4dSopenharmony_ci if (sessionId == -1) { 1232d4d9a4dSopenharmony_ci DHLOGE("SimulateEventInjectToSrc SessionId invalid"); 1242d4d9a4dSopenharmony_ci return; 1252d4d9a4dSopenharmony_ci } 1262d4d9a4dSopenharmony_ci 1272d4d9a4dSopenharmony_ci for (const std::string &dhId : dhIds) { 1282d4d9a4dSopenharmony_ci SimulateKeyDownEvents(sessionId, dhId); 1292d4d9a4dSopenharmony_ci SimulateTouchPadEvents(sessionId, dhId); 1302d4d9a4dSopenharmony_ci } 1312d4d9a4dSopenharmony_ci} 1322d4d9a4dSopenharmony_ci 1332d4d9a4dSopenharmony_civoid DInputSinkState::SimulateKeyDownEvents(const int32_t sessionId, const std::string &dhId) 1342d4d9a4dSopenharmony_ci{ 1352d4d9a4dSopenharmony_ci // check if this device is key event 1362d4d9a4dSopenharmony_ci std::lock_guard<std::mutex> mapLock(keyDownStateMapMtx_); 1372d4d9a4dSopenharmony_ci auto iter = keyDownStateMap_.find(dhId); 1382d4d9a4dSopenharmony_ci if (iter == keyDownStateMap_.end()) { 1392d4d9a4dSopenharmony_ci DHLOGI("The shared Device not has down state key, dhId: %{public}s", GetAnonyString(dhId).c_str()); 1402d4d9a4dSopenharmony_ci return; 1412d4d9a4dSopenharmony_ci } 1422d4d9a4dSopenharmony_ci 1432d4d9a4dSopenharmony_ci for (const auto &event : iter->second) { 1442d4d9a4dSopenharmony_ci DHLOGI("Simulate Key event for device path: %{public}s, dhId: %{public}s", 1452d4d9a4dSopenharmony_ci event.path.c_str(), GetAnonyString(event.descriptor).c_str()); 1462d4d9a4dSopenharmony_ci SimulateKeyDownEvent(sessionId, dhId, event); 1472d4d9a4dSopenharmony_ci } 1482d4d9a4dSopenharmony_ci 1492d4d9a4dSopenharmony_ci keyDownStateMap_.erase(dhId); 1502d4d9a4dSopenharmony_ci} 1512d4d9a4dSopenharmony_ci 1522d4d9a4dSopenharmony_civoid DInputSinkState::SimulateKeyDownEvent(const int32_t sessionId, const std::string &dhId, 1532d4d9a4dSopenharmony_ci const struct RawEvent &event) 1542d4d9a4dSopenharmony_ci{ 1552d4d9a4dSopenharmony_ci DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, 1562d4d9a4dSopenharmony_ci EV_KEY, event.code, KEY_DOWN_STATE); 1572d4d9a4dSopenharmony_ci DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhId, 1582d4d9a4dSopenharmony_ci EV_SYN, SYN_REPORT, 0x0); 1592d4d9a4dSopenharmony_ci} 1602d4d9a4dSopenharmony_ci 1612d4d9a4dSopenharmony_civoid DInputSinkState::SimulateTouchPadEvents(const int32_t sessionId, const std::string &dhId) 1622d4d9a4dSopenharmony_ci{ 1632d4d9a4dSopenharmony_ci std::vector<RawEvent> events = this->touchPadEventFragMgr_->GetAndClearEvents(dhId); 1642d4d9a4dSopenharmony_ci if (events.empty()) { 1652d4d9a4dSopenharmony_ci return; 1662d4d9a4dSopenharmony_ci } 1672d4d9a4dSopenharmony_ci 1682d4d9a4dSopenharmony_ci DHLOGI("SimulateTouchPadEvents dhId: %{public}s, event size: %{public}zu", GetAnonyString(dhId).c_str(), 1692d4d9a4dSopenharmony_ci events.size()); 1702d4d9a4dSopenharmony_ci DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsgBatch(sessionId, events); 1712d4d9a4dSopenharmony_ci} 1722d4d9a4dSopenharmony_ci 1732d4d9a4dSopenharmony_cibool DInputSinkState::IsDhIdDown(const std::string &dhId) 1742d4d9a4dSopenharmony_ci{ 1752d4d9a4dSopenharmony_ci std::lock_guard<std::mutex> mapLock(keyDownStateMapMtx_); 1762d4d9a4dSopenharmony_ci auto iter = keyDownStateMap_.find(dhId); 1772d4d9a4dSopenharmony_ci return iter != keyDownStateMap_.end(); 1782d4d9a4dSopenharmony_ci} 1792d4d9a4dSopenharmony_ci 1802d4d9a4dSopenharmony_civoid DInputSinkState::AddKeyDownState(struct RawEvent event) 1812d4d9a4dSopenharmony_ci{ 1822d4d9a4dSopenharmony_ci std::lock_guard<std::mutex> mapLock(keyDownStateMapMtx_); 1832d4d9a4dSopenharmony_ci keyDownStateMap_[event.descriptor].push_back(event); 1842d4d9a4dSopenharmony_ci} 1852d4d9a4dSopenharmony_ci 1862d4d9a4dSopenharmony_civoid DInputSinkState::RemoveKeyDownState(struct RawEvent event) 1872d4d9a4dSopenharmony_ci{ 1882d4d9a4dSopenharmony_ci std::lock_guard<std::mutex> mapLock(keyDownStateMapMtx_); 1892d4d9a4dSopenharmony_ci auto iter = keyDownStateMap_.find(event.descriptor); 1902d4d9a4dSopenharmony_ci if (iter == keyDownStateMap_.end()) { 1912d4d9a4dSopenharmony_ci return; 1922d4d9a4dSopenharmony_ci } 1932d4d9a4dSopenharmony_ci 1942d4d9a4dSopenharmony_ci auto evIter = std::find(keyDownStateMap_[event.descriptor].begin(), 1952d4d9a4dSopenharmony_ci keyDownStateMap_[event.descriptor].end(), event); 1962d4d9a4dSopenharmony_ci if (evIter == keyDownStateMap_[event.descriptor].end()) { 1972d4d9a4dSopenharmony_ci return; 1982d4d9a4dSopenharmony_ci } 1992d4d9a4dSopenharmony_ci 2002d4d9a4dSopenharmony_ci keyDownStateMap_[event.descriptor].erase(evIter); 2012d4d9a4dSopenharmony_ci if (keyDownStateMap_[event.descriptor].empty()) { 2022d4d9a4dSopenharmony_ci keyDownStateMap_.erase(event.descriptor); 2032d4d9a4dSopenharmony_ci } 2042d4d9a4dSopenharmony_ci} 2052d4d9a4dSopenharmony_ci 2062d4d9a4dSopenharmony_civoid DInputSinkState::CheckAndSetLongPressedKeyOrder(struct RawEvent event) 2072d4d9a4dSopenharmony_ci{ 2082d4d9a4dSopenharmony_ci std::lock_guard<std::mutex> mapLock(keyDownStateMapMtx_); 2092d4d9a4dSopenharmony_ci auto iter = keyDownStateMap_.find(event.descriptor); 2102d4d9a4dSopenharmony_ci if (iter == keyDownStateMap_.end()) { 2112d4d9a4dSopenharmony_ci DHLOGI("Find new pressed key, save it, node id: %{public}s, type: %{public}d, key code: %{public}d, " 2122d4d9a4dSopenharmony_ci "value: %{public}d", GetAnonyString(event.descriptor).c_str(), event.type, event.code, event.value); 2132d4d9a4dSopenharmony_ci keyDownStateMap_[event.descriptor].push_back(event); 2142d4d9a4dSopenharmony_ci return; 2152d4d9a4dSopenharmony_ci } 2162d4d9a4dSopenharmony_ci 2172d4d9a4dSopenharmony_ci auto evIter = std::find(keyDownStateMap_[event.descriptor].begin(), 2182d4d9a4dSopenharmony_ci keyDownStateMap_[event.descriptor].end(), event); 2192d4d9a4dSopenharmony_ci // If not find the cache key on pressing, save it 2202d4d9a4dSopenharmony_ci if (evIter == keyDownStateMap_[event.descriptor].end()) { 2212d4d9a4dSopenharmony_ci DHLOGI("Find new pressed key, save it, node id: %{public}s, type: %{public}d, key code: %{public}d, " 2222d4d9a4dSopenharmony_ci "value: %{public}d", GetAnonyString(event.descriptor).c_str(), event.type, event.code, event.value); 2232d4d9a4dSopenharmony_ci keyDownStateMap_[event.descriptor].push_back(event); 2242d4d9a4dSopenharmony_ci return; 2252d4d9a4dSopenharmony_ci } 2262d4d9a4dSopenharmony_ci 2272d4d9a4dSopenharmony_ci // it is already the last one, just return 2282d4d9a4dSopenharmony_ci if (evIter == (keyDownStateMap_[event.descriptor].end() - 1)) { 2292d4d9a4dSopenharmony_ci DHLOGI("Pressed key already last one, node id: %{public}s, type: %{public}d, key code: %{public}d, " 2302d4d9a4dSopenharmony_ci "value: %{public}d", GetAnonyString(event.descriptor).c_str(), event.type, event.code, event.value); 2312d4d9a4dSopenharmony_ci return; 2322d4d9a4dSopenharmony_ci } 2332d4d9a4dSopenharmony_ci 2342d4d9a4dSopenharmony_ci // Ohterwhise, move the key to the last cached position. 2352d4d9a4dSopenharmony_ci RawEvent backEv = *evIter; 2362d4d9a4dSopenharmony_ci keyDownStateMap_[event.descriptor].erase(evIter); 2372d4d9a4dSopenharmony_ci keyDownStateMap_[event.descriptor].push_back(backEv); 2382d4d9a4dSopenharmony_ci DHLOGI("Find long pressed key: %{public}d, move the cached pressed key: %{public}d to the last position", 2392d4d9a4dSopenharmony_ci event.code, backEv.code); 2402d4d9a4dSopenharmony_ci} 2412d4d9a4dSopenharmony_ci 2422d4d9a4dSopenharmony_civoid DInputSinkState::ClearDeviceStates() 2432d4d9a4dSopenharmony_ci{ 2442d4d9a4dSopenharmony_ci std::lock_guard<std::mutex> mapLock(keyDownStateMapMtx_); 2452d4d9a4dSopenharmony_ci keyDownStateMap_.clear(); 2462d4d9a4dSopenharmony_ci} 2472d4d9a4dSopenharmony_ci} // namespace DistributedInput 2482d4d9a4dSopenharmony_ci} // namespace DistributedHardware 2492d4d9a4dSopenharmony_ci} // namespace OHOSs