diff --git a/bundle.json b/bundle.json index 993070c1da88aeddd8644815edfcd261f883b874..5e3419c4931a76136daf8d135c6622c35f6db502 100755 --- a/bundle.json +++ b/bundle.json @@ -62,6 +62,7 @@ "//foundation/distributedhardware/distributed_input/services/sink/transport:libdinput_sink_trans", "//foundation/distributedhardware/distributed_input/services/sink/inputcollector:libdinput_collector", "//foundation/distributedhardware/distributed_input/services/transportbase:libdinput_trans_base", + "//foundation/distributedhardware/distributed_input/services/state:libdinput_state", "//foundation/distributedhardware/distributed_input/sourcehandler:libdinput_source_handler", "//foundation/distributedhardware/distributed_input/sinkhandler:libdinput_sink_handler", "//foundation/distributedhardware/distributed_input/inputdevicehandler:libdinput_handler", diff --git a/common/include/constants_dinput.h b/common/include/constants_dinput.h index fd19bf79491ca159a933be43841d6717f64b50a7..04fbb9c437685789859b3a072b10a063793605d4 100644 --- a/common/include/constants_dinput.h +++ b/common/include/constants_dinput.h @@ -38,6 +38,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 READ_SLEEP_TIME_MS = 50; const uint32_t READ_RETRY_MAX = 5; const uint32_t DH_ID_LENGTH_MAX = 256; diff --git a/common/include/input_hub.cpp b/common/include/input_hub.cpp index 410e4f47575a7fb5b538b51d3123adeb2559cd70..41bbac7f5ef58ee386b633c80a213c52b3c0abef 100644 --- a/common/include/input_hub.cpp +++ b/common/include/input_hub.cpp @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include @@ -40,8 +39,6 @@ namespace DistributedHardware { namespace DistributedInput { namespace { const uint32_t SLEEP_TIME_US = 100 * 1000; -const uint32_t ERROR_MSG_MAX_LEN = 256; -constexpr int32_t MAX_RETRY_COUNT = 10; } InputHub::InputHub() : epollFd_(0), iNotifyFd_(0), inputWd_(0), needToScanDevices_(true), nextDeviceId_(1), @@ -56,14 +53,6 @@ InputHub::~InputHub() Release(); } -static std::string ConvertErrNo() -{ - char errMsg[ERROR_MSG_MAX_LEN] = {0}; - strerror_r(errno, errMsg, ERROR_MSG_MAX_LEN); - std::string errNoMsg(errMsg); - return errNoMsg; -} - int32_t InputHub::Initialize() { epollFd_ = epoll_create1(EPOLL_CLOEXEC); @@ -430,41 +419,14 @@ std::vector InputHub::GetAllInputDevices() return vecDevice; } -void InputHub::ScanInputDevices(const std::string& dirname) +void InputHub::ScanInputDevices(const std::string& dirName) { - DIR *dir; - struct dirent *de; - dir = opendir(dirname.c_str()); - if (dir == nullptr) { - DHLOGE("error opendir /dev/input :%{public}s\n", ConvertErrNo().c_str()); - return; - } - size_t dirNameFirstPos = 0; - size_t dirNameSecondPos = 1; - size_t dirNameThirdPos = 2; - while ((de = readdir(dir))) { - /* - * The maximum value of d_name defined in the linux kernel is 260. Therefore, - * The d_name length does not need to be verified. - */ - if (de->d_name[dirNameFirstPos] == '.' && (de->d_name[dirNameSecondPos] == '\0' || - (de->d_name[dirNameSecondPos] == '.' && de->d_name[dirNameThirdPos] == '\0'))) { - continue; - } - std::string devName = dirname + "/" + std::string(de->d_name); - OpenInputDeviceLocked(devName); + DHLOGI("ScanInputDevices enter, dirName %s.", dirName.c_str()); + std::vector vecInputDevPath; + ScanInputDevicesPath(dirName, vecInputDevPath); + for (auto &tempPath: vecInputDevPath) { + OpenInputDeviceLocked(tempPath); } - closedir(dir); -} - -void InputHub::CloseFd(int& fd) -{ - if (fd < 0) { - DHLOGE("No fd need to be closed."); - return; - } - close(fd); - fd = -1; } bool InputHub::IsDeviceRegistered(const std::string& devicePath) @@ -486,30 +448,9 @@ int32_t InputHub::OpenInputDeviceLocked(const std::string& devicePath) std::unique_lock my_lock(operationMutex_); DHLOGI("Opening device: %s", devicePath.c_str()); - chmod(devicePath.c_str(), S_IWRITE | S_IREAD); - char canonicalDevicePath[PATH_MAX + 1] = {0x00}; - if (devicePath.length() == 0 || devicePath.length() > PATH_MAX || - realpath(devicePath.c_str(), canonicalDevicePath) == nullptr) { - DHLOGE("path check fail, error path: %s", devicePath.c_str()); - return ERR_DH_INPUT_HUB_OPEN_DEVICEPATH_FAIL; - } - struct stat s; - if ((stat(canonicalDevicePath, &s) == 0) && (s.st_mode & S_IFDIR)) { - DHLOGI("path: %s is a dir.", devicePath.c_str()); - return DH_SUCCESS; - } - - int fd = open(canonicalDevicePath, O_RDWR | O_CLOEXEC | O_NONBLOCK); - int32_t count = 0; - while ((fd < 0) && (count < MAX_RETRY_COUNT)) { - ++count; - usleep(SLEEP_TIME_US); - fd = open(canonicalDevicePath, O_RDWR | O_CLOEXEC | O_NONBLOCK); - DHLOGE("could not open %s, %s; retry %d\n", devicePath.c_str(), ConvertErrNo().c_str(), count); - } - if (count >= MAX_RETRY_COUNT) { - DHLOGE("could not open %s, %s\n", devicePath.c_str(), ConvertErrNo().c_str()); - CloseFd(fd); + int fd = OpenInputDeviceFdByPath(devicePath); + if (fd == -1) { + DHLOGE("The fd open failed, devicePath %s.", devicePath.c_str()); return ERR_DH_INPUT_HUB_OPEN_DEVICEPATH_FAIL; } @@ -1140,6 +1081,28 @@ void InputHub::GetShareMousePathByDhId(std::vector dhIds, std::stri } } +void InputHub::GetShareKeyboardPathsByDhIds(std::vector dhIds, std::vector &shareDhidsPaths, + std::vector &shareDhIds) +{ + DHLOGI("GetShareKeyboardPathsByDhIds: devices_.size:%d,", devices_.size()); + std::unique_lock deviceLock(devicesMutex_); + for (auto dhId_ : dhIds) { + for (const auto &[id, device] : devices_) { + if (device == nullptr) { + DHLOGE("device is nullptr"); + continue; + } + DHLOGI("descriptor:%s, isShare[%d], type[%d]", GetAnonyString(device->identifier.descriptor).c_str(), + device->isShare, device->classes); + if ((device->identifier.descriptor == dhId_) && + ((device->classes & INPUT_DEVICE_CLASS_KEYBOARD) != 0)) { + shareDhIds.push_back(dhId_); + shareDhidsPaths.push_back(device->path); + } + } + } +} + void InputHub::GetDevicesInfoByType(const uint32_t inputTypes, std::map &datas) { uint32_t dhType = 0; diff --git a/common/include/input_hub.h b/common/include/input_hub.h index 71ab4a799cdb401e68187ee06c841834b40ca1e2..a8f7aa39b3fb626b948498f67a6033742d181a73 100644 --- a/common/include/input_hub.h +++ b/common/include/input_hub.h @@ -53,8 +53,10 @@ public: void GetDevicesInfoByType(const uint32_t inputTypes, std::map &datas); void GetDevicesInfoByDhId(std::vector dhidsVec, std::map &datas); void GetShareMousePathByDhId(std::vector dhIds, std::string &path, std::string &dhId); + void GetShareKeyboardPathsByDhIds(std::vector dhIds, std::vector &shareDhidsPaths, + std::vector &shareDhIds); bool IsAllDevicesStoped(); - void ScanInputDevices(const std::string& dirname); + void ScanInputDevices(const std::string& dirName); private: struct Device { @@ -121,7 +123,6 @@ private: Device* GetDeviceByPathLocked(const std::string& devicePath); Device* GetDeviceByFdLocked(int fd); Device* GetSupportDeviceByFd(int fd); - void CloseFd(int& fd); bool IsDeviceRegistered(const std::string& devicePath); bool ContainsNonZeroByte(const uint8_t* array, uint32_t startIndex, uint32_t endIndex); diff --git a/interfaces/ipc/test/clientunittest/BUILD.gn b/interfaces/ipc/test/clientunittest/BUILD.gn index a9254db6c485848bb16ee9a2b0890f9f914d187b..a1a38e9f5c825836fab5b6cba7277008877286aa 100644 --- a/interfaces/ipc/test/clientunittest/BUILD.gn +++ b/interfaces/ipc/test/clientunittest/BUILD.gn @@ -49,6 +49,7 @@ ohos_unittest("distributed_input_client_test") { "${services_sink_path}/inputcollector/include", "${services_sink_path}/sinkmanager/include", "${distributedinput_path}/inputdevicehandler/include", + "${distributedinput_path}/services/state/include", ] sources = [ diff --git a/services/sink/inputcollector/include/distributed_input_collector.h b/services/sink/inputcollector/include/distributed_input_collector.h index 6cad8f668fa3a21131bfce9ed94b8fd31e5eade5..847704abc794aa47e2892fa57f09a5cb2fd7ef4a 100644 --- a/services/sink/inputcollector/include/distributed_input_collector.h +++ b/services/sink/inputcollector/include/distributed_input_collector.h @@ -43,6 +43,8 @@ public: AffectDhIds SetSharingTypes(bool enabled, const uint32_t &inputType); AffectDhIds SetSharingDhIds(bool enabled, std::vector dhIds); void GetMouseNodePath(std::vector dhIds, std::string &mouseNodePath, std::string &dhid); + void GetShareKeyboardPathsByDhIds(std::vector dhIds, std::vector &shareDhidsPaths, + std::vector &shareDhIds); // false for sharing device exist, true for all devices stop sharing bool IsAllDevicesStoped(); int32_t RegisterSharingDhIdListener(sptr sharingDhIdListener); diff --git a/services/sink/inputcollector/src/distributed_input_collector.cpp b/services/sink/inputcollector/src/distributed_input_collector.cpp index 0f664f4d9b6d1ae3b95205c99a89b4c44627c858..8b91e99f82a356dc8ada36da6b4cfe0b2e6180bf 100644 --- a/services/sink/inputcollector/src/distributed_input_collector.cpp +++ b/services/sink/inputcollector/src/distributed_input_collector.cpp @@ -175,7 +175,7 @@ void DistributedInputCollector::ReportDhIdSharingState(const AffectDhIds &dhIds) { std::lock_guard lock(sharingDhIdListenerMtx_); if (sharingDhIdListeners_.size() == 0) { - DHLOGI("sharingDhIdListeners_ is null, can not report sharing dhid"); + DHLOGE("sharingDhIdListeners is null, can not report sharing dhid"); return; } @@ -208,16 +208,26 @@ void DistributedInputCollector::GetMouseNodePath( std::vector dhIds, std::string &mouseNodePath, std::string &dhid) { if (inputHub_ == nullptr) { - DHLOGI("inputHub is nullptr!"); + DHLOGE("inputHub is nullptr!"); return; } inputHub_->GetShareMousePathByDhId(dhIds, mouseNodePath, dhid); } +void DistributedInputCollector::GetShareKeyboardPathsByDhIds(std::vector dhIds, + std::vector &shareDhidsPaths, std::vector &shareDhIds) +{ + if (inputHub_ == nullptr) { + DHLOGE("inputHub is nullptr!"); + return; + } + inputHub_->GetShareKeyboardPathsByDhIds(dhIds, shareDhidsPaths, shareDhIds); +} + bool DistributedInputCollector::IsAllDevicesStoped() { if (inputHub_ == nullptr) { - DHLOGI("inputHub is nullptr!"); + DHLOGE("inputHub is nullptr!"); return false; } return inputHub_->IsAllDevicesStoped(); @@ -235,7 +245,7 @@ void DistributedInputCollector::GetDeviceInfoByType(const uint32_t inputTypes, s std::string>& deviceInfo) { if (inputHub_ == nullptr) { - DHLOGI("inputHub is nullptr!"); + DHLOGE("inputHub is nullptr!"); return; } inputHub_->GetDevicesInfoByType(inputTypes, deviceInfo); diff --git a/services/sink/sinkmanager/BUILD.gn b/services/sink/sinkmanager/BUILD.gn index 49a96bad075fe1fb5d21844110e01c9d8a0b8b5a..7ba1f32659d6b29051313bb109c0438c630532b9 100644 --- a/services/sink/sinkmanager/BUILD.gn +++ b/services/sink/sinkmanager/BUILD.gn @@ -35,6 +35,7 @@ ohos_shared_library("libdinput_sink") { "${utils_path}/include", "${fwk_interfaces_path}/include", "${fwk_interfaces_path}/include/ipc", + "${distributedinput_path}/services/state/include", ] sources = [ @@ -52,6 +53,7 @@ ohos_shared_library("libdinput_sink") { deps = [ "${dfx_utils_path}:libdinput_dfx_utils", + "${distributedinput_path}/services/state:libdinput_state", "${innerkits_path}:libdinput_sdk", "${services_sink_path}/inputcollector:libdinput_collector", "${services_sink_path}/transport:libdinput_sink_trans", diff --git a/services/sink/sinkmanager/include/distributed_input_sink_manager.h b/services/sink/sinkmanager/include/distributed_input_sink_manager.h index 1fd3bda6c169562bb4cbcef57844918f31128cbe..aca13781a4e2e58bb155e0d61737170162882d4e 100644 --- a/services/sink/sinkmanager/include/distributed_input_sink_manager.h +++ b/services/sink/sinkmanager/include/distributed_input_sink_manager.h @@ -37,6 +37,7 @@ #include "dinput_sink_trans_callback.h" #include "distributed_input_sink_stub.h" #include "distributed_input_sink_event_handler.h" +#include "dinput_state.h" namespace OHOS { namespace DistributedHardware { @@ -78,14 +79,6 @@ public: private: DistributedInputSinkManager *sinkManagerObj_; - static inline int BitIsSet(const unsigned long *array, int bit) - { - return !!(array[bit / LONG_BITS] & (1LL << (bit % LONG_BITS))); - } - void SleepTimeMs(); - void StringSplit(const std::string &str, const char split, std::vector &vecStr); - void CreateCheckThread(const int32_t &sessionId, const std::string &strDhids); - void CheckKeyState(const int32_t &sessionId, const std::string &strDhids); }; class ProjectWindowListener : public PublisherListenerStub { diff --git a/services/sink/sinkmanager/src/distributed_input_sink_manager.cpp b/services/sink/sinkmanager/src/distributed_input_sink_manager.cpp index a986d3d068bab886e43f05336624f86e4e2ff575..1dee49f6ac0be3509a89914674d58bbcc595d819 100644 --- a/services/sink/sinkmanager/src/distributed_input_sink_manager.cpp +++ b/services/sink/sinkmanager/src/distributed_input_sink_manager.cpp @@ -210,7 +210,9 @@ void DistributedInputSinkManager::DInputSinkListener::OnStartRemoteInput( deviceInfos); for (auto deviceInfo : deviceInfos) { DHLOGI("deviceInfo dhId, %s", GetAnonyString(deviceInfo.second).c_str()); - CreateCheckThread(sessionId, deviceInfo.second); + std::vector vecStr; + StringSplitToVector(deviceInfo.second, INPUT_STRING_SPLIT_POINT, vecStr); + DInputState::GetInstance().RecordDhids(vecStr, DhidState::THROUGH_OUT, sessionId); } } } @@ -268,15 +270,12 @@ void DistributedInputSinkManager::DInputSinkListener::OnStartRemoteInputDhid(con return; } - CreateCheckThread(sessionId, strDhids); - // add the dhids - if (startRes == DH_SUCCESS) { - std::vector vecStr; - StringSplit(strDhids, INPUT_STRING_SPLIT_POINT, vecStr); - AffectDhIds affDhIds = DistributedInputCollector::GetInstance().SetSharingDhIds(true, vecStr); - sinkManagerObj_->StoreStartDhids(sessionId, affDhIds.sharingDhIds); - DistributedInputCollector::GetInstance().ReportDhIdSharingState(affDhIds); - } + std::vector vecStr; + StringSplitToVector(strDhids, INPUT_STRING_SPLIT_POINT, vecStr); + DInputState::GetInstance().RecordDhids(vecStr, DhidState::THROUGH_OUT, sessionId); + AffectDhIds affDhIds = DistributedInputCollector::GetInstance().SetSharingDhIds(true, vecStr); + sinkManagerObj_->StoreStartDhids(sessionId, affDhIds.sharingDhIds); + DistributedInputCollector::GetInstance().ReportDhIdSharingState(affDhIds); } void DistributedInputSinkManager::DInputSinkListener::OnStopRemoteInputDhid(const int32_t &sessionId, @@ -285,13 +284,15 @@ void DistributedInputSinkManager::DInputSinkListener::OnStopRemoteInputDhid(cons DHLOGI("OnStopRemoteInputDhid called, sessionId: %d", sessionId); std::vector stopIndeedDhIds; std::vector stopOnCmdDhIds; - StringSplit(strDhids, INPUT_STRING_SPLIT_POINT, stopOnCmdDhIds); + StringSplitToVector(strDhids, INPUT_STRING_SPLIT_POINT, stopOnCmdDhIds); sinkManagerObj_->DeleteStopDhids(sessionId, stopOnCmdDhIds, stopIndeedDhIds); (void)DistributedInputCollector::GetInstance().SetSharingDhIds(false, stopIndeedDhIds); AffectDhIds stopIndeedOnes; stopIndeedOnes.noSharingDhIds = stopIndeedDhIds; DistributedInputCollector::GetInstance().ReportDhIdSharingState(stopIndeedOnes); + DInputState::GetInstance().RecordDhids(stopOnCmdDhIds, DhidState::THROUGH_IN, -1); + if (DistributedInputCollector::GetInstance().IsAllDevicesStoped()) { DHLOGE("All dhid stop sharing, sessionId: %d is closed.", sessionId); DistributedInputSinkSwitch::GetInstance().StopSwitch(sessionId); @@ -336,16 +337,12 @@ void DistributedInputSinkManager::DInputSinkListener::OnRelayStartDhidRemoteInpu return; } - CreateCheckThread(toSinkSessionId, strDhids); - - // add the dhids - if (startRes == DH_SUCCESS) { - std::vector vecStr; - StringSplit(strDhids, INPUT_STRING_SPLIT_POINT, vecStr); - AffectDhIds affDhIds = DistributedInputCollector::GetInstance().SetSharingDhIds(true, vecStr); - sinkManagerObj_->StoreStartDhids(toSinkSessionId, affDhIds.sharingDhIds); - DistributedInputCollector::GetInstance().ReportDhIdSharingState(affDhIds); - } + std::vector vecStr; + StringSplitToVector(strDhids, INPUT_STRING_SPLIT_POINT, vecStr); + DInputState::GetInstance().RecordDhids(vecStr, DhidState::THROUGH_OUT, toSinkSessionId); + AffectDhIds affDhIds = DistributedInputCollector::GetInstance().SetSharingDhIds(true, vecStr); + sinkManagerObj_->StoreStartDhids(toSinkSessionId, affDhIds.sharingDhIds); + DistributedInputCollector::GetInstance().ReportDhIdSharingState(affDhIds); } void DistributedInputSinkManager::DInputSinkListener::OnRelayStopDhidRemoteInput(const int32_t &toSrcSessionId, @@ -354,13 +351,15 @@ void DistributedInputSinkManager::DInputSinkListener::OnRelayStopDhidRemoteInput DHLOGI("onRelayStopDhidRemoteInput called, toSinkSessionId: %d", toSinkSessionId); std::vector stopIndeedDhIds; std::vector stopOnCmdDhIds; - StringSplit(strDhids, INPUT_STRING_SPLIT_POINT, stopOnCmdDhIds); + StringSplitToVector(strDhids, INPUT_STRING_SPLIT_POINT, stopOnCmdDhIds); sinkManagerObj_->DeleteStopDhids(toSinkSessionId, stopOnCmdDhIds, stopIndeedDhIds); AffectDhIds affDhIds = DistributedInputCollector::GetInstance().SetSharingDhIds(false, stopIndeedDhIds); AffectDhIds stopIndeedOnes; stopIndeedOnes.noSharingDhIds = stopIndeedDhIds; DistributedInputCollector::GetInstance().ReportDhIdSharingState(stopIndeedOnes); + DInputState::GetInstance().RecordDhids(stopOnCmdDhIds, DhidState::THROUGH_IN, -1); + if (DistributedInputCollector::GetInstance().IsAllDevicesStoped()) { DHLOGE("All dhid stop sharing, sessionId: %d is closed.", toSinkSessionId); DistributedInputSinkSwitch::GetInstance().StopSwitch(toSinkSessionId); @@ -432,7 +431,9 @@ void DistributedInputSinkManager::DInputSinkListener::OnRelayStartTypeRemoteInpu deviceInfos); for (auto deviceInfo : deviceInfos) { DHLOGI("deviceInfo dhId, %s", GetAnonyString(deviceInfo.second).c_str()); - CreateCheckThread(toSinkSessionId, deviceInfo.second); + std::vector vecStr; + StringSplitToVector(deviceInfo.second, INPUT_STRING_SPLIT_POINT, vecStr); + DInputState::GetInstance().RecordDhids(vecStr, DhidState::THROUGH_OUT, toSinkSessionId); } } @@ -472,99 +473,6 @@ void DistributedInputSinkManager::DInputSinkListener::OnRelayStopTypeRemoteInput } } -void DistributedInputSinkManager::DInputSinkListener::StringSplit(const std::string &str, const char split, - std::vector &vecStr) -{ - if (str.empty()) { - DHLOGE("param str is error."); - return; - } - std::string strTmp = str + split; - size_t pos = strTmp.find(split); - while (pos != strTmp.npos) { - std::string matchTmp = strTmp.substr(0, pos); - vecStr.push_back(matchTmp); - strTmp = strTmp.substr(pos + 1, strTmp.size()); - pos = strTmp.find(split); - } -} - -void DistributedInputSinkManager::DInputSinkListener::SleepTimeMs() -{ - std::this_thread::sleep_for(std::chrono::milliseconds(READ_SLEEP_TIME_MS)); -} - -void DistributedInputSinkManager::DInputSinkListener::CreateCheckThread(const int32_t &sessionId, - const std::string &strDhids) -{ - std::thread checkKeyStateThread = - std::thread(&DistributedInputSinkManager::DInputSinkListener::CheckKeyState, this, sessionId, strDhids); - int32_t ret = pthread_setname_np(checkKeyStateThread.native_handle(), CHECK_KEY_STATUS_THREAD_NAME); - if (ret != 0) { - DHLOGE("CreateCheckThread setname failed."); - } - checkKeyStateThread.detach(); -} - -void DistributedInputSinkManager::DInputSinkListener::CheckKeyState(const int32_t &sessionId, - const std::string &strDhids) -{ - std::vector vecStr; - StringSplit(strDhids, INPUT_STRING_SPLIT_POINT, vecStr); - std::string mouseNodePath; - std::string dhid; - DistributedInputCollector::GetInstance().GetMouseNodePath(vecStr, mouseNodePath, dhid); - - char canonicalPath[PATH_MAX + 1] = {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()); - return; - } - - int fd = open(canonicalPath, O_RDONLY | O_NONBLOCK); - if (fd < 0) { - DHLOGE("open mouse Node Path error:", errno); - 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; - SleepTimeMs(); - continue; - } - leftKeyVal = BitIsSet(keystate, BTN_LEFT); - if (leftKeyVal != 0) { - DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhid, BTN_LEFT); - } - rightKeyVal = BitIsSet(keystate, BTN_RIGHT); - if (rightKeyVal != 0) { - DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhid, BTN_RIGHT); - } - midKeyVal = BitIsSet(keystate, BTN_MIDDLE); - if (midKeyVal != 0) { - DistributedInputSinkTransport::GetInstance().SendKeyStateNodeMsg(sessionId, dhid, BTN_MIDDLE); - } - break; - } - if (fd >= 0) { - close(fd); - fd = -1; - } -} - bool DistributedInputSinkManager::IsStopDhidOnCmdStillNeed(int32_t sessionId, const std::string &stopDhId) { for (auto sessionDhid : sharingDhIdsMap_) { @@ -695,6 +603,12 @@ int32_t DistributedInputSinkManager::Init() return ERR_DH_INPUT_SERVER_SINK_MANAGER_INIT_FAIL; } + ret = DInputState::GetInstance().Init(); + if (ret != DH_SUCCESS) { + DHLOGE("DInputState init fail!"); + return ERR_DH_INPUT_SERVER_SINK_MANAGER_INIT_FAIL; + } + statuslistener_ = std::make_shared(this); DistributedInputSinkTransport::GetInstance().RegistSinkRespCallback(statuslistener_); diff --git a/services/sink/sinkmanager/test/sinkmanagerunittest/BUILD.gn b/services/sink/sinkmanager/test/sinkmanagerunittest/BUILD.gn index a5bc23d14aadf5d04636975530cdc29489d05cfd..2ab18a6c2e178d55d78970df319553622d43bf13 100755 --- a/services/sink/sinkmanager/test/sinkmanagerunittest/BUILD.gn +++ b/services/sink/sinkmanager/test/sinkmanagerunittest/BUILD.gn @@ -49,6 +49,7 @@ ohos_unittest("distributed_input_sinkmanager_test") { "${fwk_interfaces_path}/include/ipc", "${common_path}/test/mock", "${services_sink_path}/sinkmanager/test/sinkmanagerunittest/mock/", + "${distributedinput_path}/services/state/include", ] sources = [ @@ -84,6 +85,7 @@ ohos_unittest("distributed_input_sinkmanager_test") { deps = [ "${dfx_utils_path}:libdinput_dfx_utils", + "${distributedinput_path}/services/state:libdinput_state", "${distributedinput_path}/services/transportbase:libdinput_trans_base", "${services_sink_path}/transport:libdinput_sink_trans", "${utils_path}:libdinput_utils", diff --git a/services/sink/sinkmanager/test/sinkmanagerunittest/distributed_input_sinkmanager_test.cpp b/services/sink/sinkmanager/test/sinkmanagerunittest/distributed_input_sinkmanager_test.cpp index 8820003640176a2b4e29112a1de57856ee2091af..c92dcb715781ac9c8756aa88eb02b4cdefdd3e27 100644 --- a/services/sink/sinkmanager/test/sinkmanagerunittest/distributed_input_sinkmanager_test.cpp +++ b/services/sink/sinkmanager/test/sinkmanagerunittest/distributed_input_sinkmanager_test.cpp @@ -186,18 +186,6 @@ HWTEST_F(DistributedInputSinkManagerTest, RegisterGetSinkScreenInfosCallback_02, EXPECT_EQ(DH_SUCCESS, ret); } -HWTEST_F(DistributedInputSinkManagerTest, StringSplit_01, testing::ext::TestSize.Level1) -{ - char splitPoint = '.'; - std::string str = ""; - std::vector vecStr; - sinkManager_->statuslistener_->StringSplit(str, splitPoint, vecStr); - - str = "123,123,123,123"; - sinkManager_->statuslistener_->StringSplit(str, splitPoint, vecStr); - EXPECT_NE(0, vecStr.size()); -} - HWTEST_F(DistributedInputSinkManagerTest, OnMessage_01, testing::ext::TestSize.Level1) { int32_t ret = sinkManager_->Init(); diff --git a/services/sink/transport/test/sinktransunittest/BUILD.gn b/services/sink/transport/test/sinktransunittest/BUILD.gn index 48415d92755b62c9fd6db819a8a0469ea8713769..e817dc58ae140bbd0216e662278761c52b4b29fd 100755 --- a/services/sink/transport/test/sinktransunittest/BUILD.gn +++ b/services/sink/transport/test/sinktransunittest/BUILD.gn @@ -50,6 +50,7 @@ ohos_unittest("distributed_input_sinktrans_test") { "${services_sink_path}/inputcollector/include", "${services_source_path}/inputinject/include", "${distributedinput_path}/inputdevicehandler/include", + "${distributedinput_path}/services/state/include", ] sources = [ @@ -79,6 +80,7 @@ ohos_unittest("distributed_input_sinktrans_test") { deps = [ "${dfx_utils_path}:libdinput_dfx_utils", + "${distributedinput_path}/services/state:libdinput_state", "${services_sink_path}/inputcollector:libdinput_collector", "${services_sink_path}/sinkmanager:libdinput_sink", "${utils_path}:libdinput_utils", diff --git a/services/source/inputinject/BUILD.gn b/services/source/inputinject/BUILD.gn index 34e49ddd06ea06cb6dbfca83b8b9cf1b1f9eb8b5..0c697350a1caebe14f689c17be98e5928ef34cd8 100644 --- a/services/source/inputinject/BUILD.gn +++ b/services/source/inputinject/BUILD.gn @@ -30,6 +30,7 @@ ohos_shared_library("libdinput_inject") { "${fwk_interfaces_path}/include", "${fwk_interfaces_path}/include/ipc", "${distributedinput_path}/inputdevicehandler/include", + "${distributedinput_path}/services/state/include", ] sources = [ @@ -55,6 +56,7 @@ ohos_shared_library("libdinput_inject") { external_deps = [ "c_utils:utils", "dsoftbus:softbus_client", + "eventhandler:libeventhandler", "ipc:ipc_core", "safwk:system_ability_fwk", "samgr:samgr_proxy", diff --git a/services/source/inputinject/include/distributed_input_inject.h b/services/source/inputinject/include/distributed_input_inject.h index 0da45f7336cbb7817637bc41674c6c37310b55ff..68d556e5f8d20d200d02b575737eb47c15d180c0 100644 --- a/services/source/inputinject/include/distributed_input_inject.h +++ b/services/source/inputinject/include/distributed_input_inject.h @@ -56,6 +56,11 @@ public: const std::string &sinkNodeDesc); void SyncNodeOfflineInfo(const std::string &srcDevId, const std::string &sinkDevId, const std::string &sinkNodeId); + void GetVirtualKeyboardPathsByDhIds(const std::vector &dhIds, + std::vector &shareDhidsPaths, std::vector &shareDhIds); + + void NotifyNodeMgrScanVirNode(const std::string &dhId); + 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 9c3d0373e3c12efca02c7728a5bcbeec30017548..c9003229f64b1ccd64a165e188d7c489edb3a25e 100644 --- a/services/source/inputinject/include/distributed_input_node_manager.h +++ b/services/source/inputinject/include/distributed_input_node_manager.h @@ -24,6 +24,7 @@ #include #include +#include "event_handler.h" #include "nlohmann/json.hpp" #include "constants_dinput.h" @@ -33,15 +34,16 @@ namespace OHOS { namespace DistributedHardware { namespace DistributedInput { +const uint32_t DINPUT_NODE_MANAGER_SCAN_ALL_NODE = 1; +const std::string INPUT_NODE_DHID = "dhId"; class DistributedInputNodeManager { public: DistributedInputNodeManager(); ~DistributedInputNodeManager(); - int32_t openDevicesNode(const std::string& devId, const std::string& dhId, - const std::string& parameters); + int32_t OpenDevicesNode(const std::string& devId, const std::string& dhId, const std::string& parameters); - int32_t getDevice(const std::string& dhId, VirtualDevice*& device); + int32_t GetDevice(const std::string& dhId, VirtualDevice*& device); void ReportEvent(const RawEvent rawEvent); int32_t CloseDeviceLocked(const std::string& dhId); void StartInjectThread(); @@ -56,6 +58,26 @@ public: void GetDevicesInfoByDhId(std::vector dhidsVec, std::map &datas); void ProcessInjectEvent(const std::shared_ptr &rawEvent); + void GetVirtualKeyboardPathsByDhIds(const std::vector &dhIds, + std::vector &shareDhidsPaths, std::vector &shareDhIds); + void NotifyNodeMgrScanVirNode(const std::string &dhId); + + class DInputNodeManagerEventHandler : public AppExecFwk::EventHandler { + public: + DInputNodeManagerEventHandler(const std::shared_ptr &runner, + DistributedInputNodeManager *manager); + ~DInputNodeManagerEventHandler() override; + + void ProcessEvent(const AppExecFwk::InnerEvent::Pointer &event) override; + private: + void ScanAllNode(const AppExecFwk::InnerEvent::Pointer &event); + + using nodeMgrFunc = void (DInputNodeManagerEventHandler::*)( + const AppExecFwk::InnerEvent::Pointer &event); + std::map eventFuncMap_; + DistributedInputNodeManager *nodeManagerObj_; + }; + private: void AddDeviceLocked(const std::string& dhId, std::unique_ptr device); int32_t CreateHandle(const InputDevice& inputDevice, const std::string& devId, const std::string& dhId); @@ -63,6 +85,12 @@ private: void VerifyInputDevice(const nlohmann::json& inputDeviceJson, InputDevice& pBuf); void InjectEvent(); + void ScanSinkInputDevices(const std::string& dhId); + void OpenInputDevice(const std::string& devicePath, const std::string& dhId); + bool IsVirtualDev(int fd); + bool GetDevDhIdByFd(int fd, std::string& dhId, std::string& physicalPath); + void SetPathForDevMap(std::string& dhId, const std::string& devicePath); + /* the key is dhId, and the value is virtualDevice */ std::map> virtualDeviceMap_; std::mutex virtualDeviceMapMutex_; @@ -76,6 +104,7 @@ private: std::unique_ptr inputHub_; int32_t virtualTouchScreenFd_; std::once_flag callOnceFlag_; + std::shared_ptr callBackHandler_; }; } // namespace DistributedInput } // namespace DistributedHardware diff --git a/services/source/inputinject/include/virtual_device.h b/services/source/inputinject/include/virtual_device.h index 6bbe88331f96262bee07b36279ecc533272266a6..9dc0b36b9fc5fb419b41dc30538e2e4efdd3ce38 100644 --- a/services/source/inputinject/include/virtual_device.h +++ b/services/source/inputinject/include/virtual_device.h @@ -43,7 +43,10 @@ public: bool SetUp(const InputDevice& inputDevice, const std::string &devId, const std::string &dhId); bool InjectInputEvent(const input_event &event); void SetNetWorkId(const std::string netWorkId); + void SetPath(const std::string path); std::string GetNetWorkId(); + std::string GetPath(); + uint16_t GetClasses(); int32_t GetDeviceFd(); uint16_t GetDeviceType(); @@ -52,6 +55,7 @@ private: int32_t fd_ = -1; std::string deviceName_; std::string netWorkId_; + std::string path_ {""}; const uint16_t busType_; const uint16_t vendorId_; const uint16_t productId_; diff --git a/services/source/inputinject/src/distributed_input_inject.cpp b/services/source/inputinject/src/distributed_input_inject.cpp index b3511b244bee48326809abf233df73709fcb9524..010d6d6c0c7ed8b733f52ebe1d4af4d77b69856b 100644 --- a/services/source/inputinject/src/distributed_input_inject.cpp +++ b/services/source/inputinject/src/distributed_input_inject.cpp @@ -56,7 +56,7 @@ int32_t DistributedInputInject::RegisterDistributedHardware(const std::string& d DHLOGE("the DistributedInputNodeManager is null\n"); return ERR_DH_INPUT_SERVER_SOURCE_INJECT_NODE_MANAGER_IS_NULL; } - if (inputNodeManager_->openDevicesNode(devId, dhId, parameters) < 0) { + if (inputNodeManager_->OpenDevicesNode(devId, dhId, parameters) < 0) { DHLOGE("create virtual device error\n"); return ERR_DH_INPUT_SERVER_SOURCE_INJECT_REGISTER_FAIL; } @@ -255,6 +255,27 @@ int32_t DistributedInputInject::GetVirtualTouchScreenFd() } return inputNodeManager_->GetVirtualTouchScreenFd(); } + +void DistributedInputInject::GetVirtualKeyboardPathsByDhIds(const std::vector &dhIds, + std::vector &shareDhidsPaths, std::vector &shareDhIds) +{ + std::lock_guard lock(inputNodeManagerMutex_); + if (inputNodeManager_ == nullptr) { + DHLOGE("inputNodeManager is nullptr"); + return; + } + inputNodeManager_->GetVirtualKeyboardPathsByDhIds(dhIds, shareDhidsPaths, shareDhIds); +} + +void DistributedInputInject::NotifyNodeMgrScanVirNode(const std::string &dhId) +{ + std::lock_guard lock(inputNodeManagerMutex_); + if (inputNodeManager_ == nullptr) { + DHLOGE("inputNodeManager is nullptr"); + return; + } + inputNodeManager_->NotifyNodeMgrScanVirNode(dhId); +} } // 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 6c4838bc01bd14c09c4fee7c1c3f4ce0e21f3be7..041d4de69505fa3a45ae9be7251675796d3609c3 100644 --- a/services/source/inputinject/src/distributed_input_node_manager.cpp +++ b/services/source/inputinject/src/distributed_input_node_manager.cpp @@ -18,9 +18,7 @@ #include #include -#include #include -#include #include "softbus_bus_center.h" @@ -36,11 +34,14 @@ namespace DistributedInput { DistributedInputNodeManager::DistributedInputNodeManager() : isInjectThreadCreated_(false), isInjectThreadRunning_(false), inputHub_(std::make_unique()), virtualTouchScreenFd_(UN_INIT_FD_VALUE) { + DHLOGI("DistributedInputNodeManager ctor"); + std::shared_ptr runner = AppExecFwk::EventRunner::Create(true); + callBackHandler_ = std::make_shared(runner, this); } DistributedInputNodeManager::~DistributedInputNodeManager() { - DHLOGI("destructor start"); + DHLOGI("DistributedInputNodeManager dtor"); isInjectThreadCreated_.store(false); isInjectThreadRunning_.store(false); if (eventInjectThread_.joinable()) { @@ -53,7 +54,7 @@ DistributedInputNodeManager::~DistributedInputNodeManager() DHLOGI("destructor end"); } -int32_t DistributedInputNodeManager::openDevicesNode(const std::string& devId, const std::string& dhId, +int32_t DistributedInputNodeManager::OpenDevicesNode(const std::string& devId, const std::string& dhId, const std::string& parameters) { if (devId.size() > DEV_ID_LENGTH_MAX || devId.empty() || dhId.size() > DH_ID_LENGTH_MAX || dhId.empty() || @@ -67,7 +68,6 @@ int32_t DistributedInputNodeManager::openDevicesNode(const std::string& devId, c DHLOGE("Can not create virtual node!"); return ERR_DH_INPUT_SERVER_SOURCE_OPEN_DEVICE_NODE_FAIL; } - return DH_SUCCESS; } @@ -130,6 +130,166 @@ void DistributedInputNodeManager::VerifyInputDevice(const nlohmann::json& inputD } } +void DistributedInputNodeManager::ScanSinkInputDevices(const std::string& dhId) +{ + DHLOGI("ScanSinkInputDevices enter, dhId %s.", dhId.c_str()); + std::vector vecInputDevPath; + ScanInputDevicesPath(DEVICE_PATH, vecInputDevPath); + for (auto &tempPath: vecInputDevPath) { + OpenInputDevice(tempPath, dhId); + } +} + +void DistributedInputNodeManager::DInputNodeManagerEventHandler::ProcessEvent( + const AppExecFwk::InnerEvent::Pointer &event) +{ + DHLOGI("ProcessEvent enter."); + auto iter = eventFuncMap_.find(event->GetInnerEventId()); + if (iter == eventFuncMap_.end()) { + DHLOGE("Event Id %d is undefined.", event->GetInnerEventId()); + return; + } + nodeMgrFunc &func = iter->second; + (this->*func)(event); +} + +DistributedInputNodeManager::DInputNodeManagerEventHandler::DInputNodeManagerEventHandler( + const std::shared_ptr &runner, DistributedInputNodeManager *manager) + : AppExecFwk::EventHandler(runner) +{ + eventFuncMap_[DINPUT_NODE_MANAGER_SCAN_ALL_NODE] = &DInputNodeManagerEventHandler::ScanAllNode; + + nodeManagerObj_ = manager; +} + +DistributedInputNodeManager::DInputNodeManagerEventHandler::~DInputNodeManagerEventHandler() +{ + eventFuncMap_.clear(); + nodeManagerObj_ = nullptr; +} + +void DistributedInputNodeManager::DInputNodeManagerEventHandler::ScanAllNode( + const AppExecFwk::InnerEvent::Pointer &event) +{ + DHLOGI("ScanAllNode enter."); + std::shared_ptr dataMsg = event->GetSharedObject(); + auto it = dataMsg->begin(); + nlohmann::json innerMsg = *(it); + std::string devicedhId = innerMsg[INPUT_NODE_DHID]; + nodeManagerObj_->ScanSinkInputDevices(devicedhId); +} + +void DistributedInputNodeManager::NotifyNodeMgrScanVirNode(const std::string &dhId) +{ + DHLOGI("NotifyNodeMgrScanVirNode enter."); + std::shared_ptr jsonArrayMsg = std::make_shared(); + nlohmann::json tmpJson; + tmpJson[INPUT_NODE_DHID] = dhId; + jsonArrayMsg->push_back(tmpJson); + AppExecFwk::InnerEvent::Pointer msgEvent = AppExecFwk::InnerEvent::Get( + DINPUT_NODE_MANAGER_SCAN_ALL_NODE, jsonArrayMsg, 0); + callBackHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE); +} + +bool DistributedInputNodeManager::IsVirtualDev(int fd) +{ + char buffer[256] = {0}; + std::string deviceName; + if (ioctl(fd, EVIOCGNAME(sizeof(buffer) - 1), &buffer) < 1) { + DHLOGE("Could not get device name for %s.", ConvertErrNo().c_str()); + return false; + } + buffer[sizeof(buffer) - 1] = '\0'; + deviceName = buffer; + + DHLOGD("IsVirtualDev deviceName: %s", buffer); + if (deviceName.find(VIRTUAL_DEVICE_NAME) == std::string::npos) { + DHLOGD("This is not a virtual device, fd %d, deviceName: %s.", fd, deviceName.c_str()); + return false; + } + return true; +} + +bool DistributedInputNodeManager::GetDevDhIdByFd(int fd, std::string& dhId, std::string& physicalPath) +{ + char buffer[256] = {0}; + if (ioctl(fd, EVIOCGPHYS(sizeof(buffer) - 1), &buffer) < 1) { + DHLOGE("Could not get device physicalPath for %s.", ConvertErrNo().c_str()); + return false; + } + buffer[sizeof(buffer) - 1] = '\0'; + physicalPath = buffer; + + DHLOGD("GetDevDhIdByFd physicalPath %s.", physicalPath.c_str()); + dhId = physicalPath.substr(physicalPath.find(DH_ID_PREFIX)); + if (dhId.size() == 0) { + DHLOGE("Get dev dhid failed."); + return false; + } + DHLOGD("Device dhId %s.", GetAnonyString(dhId).c_str()); + return true; +} + +void DistributedInputNodeManager::SetPathForDevMap(std::string& dhId, const std::string& devicePath) +{ + std::lock_guard lock(virtualDeviceMapMutex_); + auto iter = virtualDeviceMap_.begin(); + while (iter != virtualDeviceMap_.end()) { + DHLOGD("Virtual device map dhid %s.", iter->first.c_str()); + if (dhId.compare(iter->first) == 0) { + DHLOGD("Found the virtual device, set path :%s", devicePath.c_str()); + iter->second->SetPath(devicePath); + break; + } + iter++; + } +} + +void DistributedInputNodeManager::OpenInputDevice(const std::string& devicePath, const std::string& dhId) +{ + DHLOGI("Opening input device path: %s", devicePath.c_str()); + std::string curDhId; + std::string physicalPath; + int fd = OpenInputDeviceFdByPath(devicePath); + if (fd == -1) { + DHLOGE("The fd open failed, devicePath %s.", devicePath.c_str()); + return; + } + if (!IsVirtualDev(fd)) { + DHLOGE("The dev not virtual, devicePath %s.", devicePath.c_str()); + return; + } + if (!GetDevDhIdByFd(fd, curDhId, physicalPath) || dhId != curDhId) { + DHLOGE("This is not same dev, curDhId %s.", devicePath.c_str()); + return; + } + DHLOGD("curDhId %s.", GetAnonyString(curDhId).c_str()); + SetPathForDevMap(curDhId, devicePath); +} + +void DistributedInputNodeManager::GetVirtualKeyboardPathsByDhIds(const std::vector &dhIds, + std::vector &shareDhidsPaths, std::vector &shareDhIds) +{ + std::lock_guard lock(virtualDeviceMapMutex_); + for (auto dhId_ : dhIds) { + auto iter = virtualDeviceMap_.begin(); + while (iter != virtualDeviceMap_.end()) { + if (iter->second == nullptr) { + DHLOGE("device is nullptr"); + continue; + } + if ((iter->first.compare(dhId_) == 0) && + ((iter->second->GetClasses() & INPUT_DEVICE_CLASS_KEYBOARD) != 0)) { + DHLOGI("Found vir keyboard path %s, dhid %s", iter->second->GetPath().c_str(), + GetAnonyString(dhId_).c_str()); + shareDhidsPaths.push_back(iter->second->GetPath()); + shareDhIds.push_back(dhId_); + } + iter++; + } + } +} + int32_t DistributedInputNodeManager::CreateHandle(const InputDevice& inputDevice, const std::string& devId, const std::string& dhId) { @@ -201,7 +361,7 @@ int32_t DistributedInputNodeManager::CloseDeviceLocked(const std::string &dhId) return ERR_DH_INPUT_SERVER_SOURCE_CLOSE_DEVICE_FAIL; } -int32_t DistributedInputNodeManager::getDevice(const std::string& dhId, VirtualDevice*& device) +int32_t DistributedInputNodeManager::GetDevice(const std::string& dhId, VirtualDevice*& device) { std::lock_guard lock(virtualDeviceMapMutex_); auto iter = virtualDeviceMap_.find(dhId); @@ -286,7 +446,7 @@ void DistributedInputNodeManager::ProcessInjectEvent(const std::shared_ptrwhen); VirtualDevice* device = nullptr; - if (getDevice(dhId, device) < 0) { + if (GetDevice(dhId, device) < 0) { DHLOGE("could not find the device"); return; } diff --git a/services/source/inputinject/src/virtual_device.cpp b/services/source/inputinject/src/virtual_device.cpp index feef9e229a24f42f6d2a1e66ac71ccad4e91fc3f..bd114d42823da793fd9d3b067b294d346750a065 100644 --- a/services/source/inputinject/src/virtual_device.cpp +++ b/services/source/inputinject/src/virtual_device.cpp @@ -185,11 +185,26 @@ void VirtualDevice::SetNetWorkId(const std::string netWorkId) netWorkId_ = netWorkId; } +void VirtualDevice::SetPath(const std::string path) +{ + path_ = path; +} + std::string VirtualDevice::GetNetWorkId() { return netWorkId_; } +std::string VirtualDevice::GetPath() +{ + return path_; +} + +uint16_t VirtualDevice::GetClasses() +{ + return classes_; +} + void VirtualDevice::RecordEventLog(const input_event& event) { std::string eventType = ""; diff --git a/services/source/inputinject/test/sourceinjectunittest/distributed_input_sourceinject_test.cpp b/services/source/inputinject/test/sourceinjectunittest/distributed_input_sourceinject_test.cpp index 3d2827ec129d1830bcd5d55ef5cdcaead74e056b..0c929bbde6780935046ac5edcf5d3a6627ee2432 100644 --- a/services/source/inputinject/test/sourceinjectunittest/distributed_input_sourceinject_test.cpp +++ b/services/source/inputinject/test/sourceinjectunittest/distributed_input_sourceinject_test.cpp @@ -413,49 +413,49 @@ HWTEST_F(DistributedInputSourceInjectTest, GetVirtualTouchScreenFd_003, testing: EXPECT_NE(-1, ret); } -HWTEST_F(DistributedInputSourceInjectTest, getDevice_001, testing::ext::TestSize.Level1) +HWTEST_F(DistributedInputSourceInjectTest, GetDevice_001, testing::ext::TestSize.Level1) { std::string dhId = "1ds56v18e1v21v8v1erv15r1v8r1j1ty8"; VirtualDevice* device = nullptr; - int32_t ret = DistributedInputInject::GetInstance().inputNodeManager_->getDevice(dhId, device); + int32_t ret = DistributedInputInject::GetInstance().inputNodeManager_->GetDevice(dhId, device); EXPECT_EQ(ERR_DH_INPUT_SERVER_SOURCE_GET_DEVICE_FAIL, ret); } -HWTEST_F(DistributedInputSourceInjectTest, openDevicesNode_001, testing::ext::TestSize.Level1) +HWTEST_F(DistributedInputSourceInjectTest, OpenDevicesNode_001, testing::ext::TestSize.Level1) { std::string devId = "umkyu1b165e1be98151891erbe8r91ev"; std::string dhId = "1ds56v18e1v21v8v1erv15r1v8r1j1ty8"; std::string parameters = ""; - int32_t ret = DistributedInputInject::GetInstance().inputNodeManager_->openDevicesNode(devId, dhId, parameters); + int32_t ret = DistributedInputInject::GetInstance().inputNodeManager_->OpenDevicesNode(devId, dhId, parameters); EXPECT_EQ(ERR_DH_INPUT_SERVER_SOURCE_OPEN_DEVICE_NODE_FAIL, ret); devId = ""; parameters = "parameters_test"; - ret = DistributedInputInject::GetInstance().inputNodeManager_->openDevicesNode(devId, dhId, parameters); + ret = DistributedInputInject::GetInstance().inputNodeManager_->OpenDevicesNode(devId, dhId, parameters); EXPECT_EQ(ERR_DH_INPUT_SERVER_SOURCE_OPEN_DEVICE_NODE_FAIL, ret); devId = "umkyu1b165e1be98151891erbe8r91ev"; dhId = ""; - ret = DistributedInputInject::GetInstance().inputNodeManager_->openDevicesNode(devId, dhId, parameters); + ret = DistributedInputInject::GetInstance().inputNodeManager_->OpenDevicesNode(devId, dhId, parameters); EXPECT_EQ(ERR_DH_INPUT_SERVER_SOURCE_OPEN_DEVICE_NODE_FAIL, ret); } -HWTEST_F(DistributedInputSourceInjectTest, openDevicesNode_002, testing::ext::TestSize.Level1) +HWTEST_F(DistributedInputSourceInjectTest, OpenDevicesNode_002, testing::ext::TestSize.Level1) { std::string devId(DEV_ID_LENGTH_MAX + 1, 'a'); std::string dhId = "1ds56v18e1v21v8v1erv15r1v8r1j1ty8"; std::string parameters = "parameters_test"; - int32_t ret = DistributedInputInject::GetInstance().inputNodeManager_->openDevicesNode(devId, dhId, parameters); + int32_t ret = DistributedInputInject::GetInstance().inputNodeManager_->OpenDevicesNode(devId, dhId, parameters); EXPECT_EQ(ERR_DH_INPUT_SERVER_SOURCE_OPEN_DEVICE_NODE_FAIL, ret); devId = "umkyu1b165e1be98151891erbe8r91ev"; std::string dhIds(DH_ID_LENGTH_MAX + 1, 'a'); - ret = DistributedInputInject::GetInstance().inputNodeManager_->openDevicesNode(devId, dhIds, parameters); + ret = DistributedInputInject::GetInstance().inputNodeManager_->OpenDevicesNode(devId, dhIds, parameters); EXPECT_EQ(ERR_DH_INPUT_SERVER_SOURCE_OPEN_DEVICE_NODE_FAIL, ret); std::string dhIdtest = "1ds56v18e1v21v8v1erv15r1v8r1j1ty8"; std::string param(STRING_MAX_SIZE + 1, 'a'); - ret = DistributedInputInject::GetInstance().inputNodeManager_->openDevicesNode(devId, dhIdtest, param); + ret = DistributedInputInject::GetInstance().inputNodeManager_->OpenDevicesNode(devId, dhIdtest, param); EXPECT_EQ(ERR_DH_INPUT_SERVER_SOURCE_OPEN_DEVICE_NODE_FAIL, ret); } diff --git a/services/source/sourcemanager/BUILD.gn b/services/source/sourcemanager/BUILD.gn index 08e3a551698ab622aa9cb00839c09cb17a85eed4..1ef442860401210d8ca0a616ab582e2aa8cbc886 100644 --- a/services/source/sourcemanager/BUILD.gn +++ b/services/source/sourcemanager/BUILD.gn @@ -37,6 +37,7 @@ ohos_shared_library("libdinput_source") { "${fwk_interfaces_path}/include", "${fwk_interfaces_path}/include/ipc", "${distributedinput_path}/inputdevicehandler/include", + "${distributedinput_path}/services/state/include", ] sources = [ @@ -87,6 +88,7 @@ ohos_shared_library("libdinput_source") { deps = [ "${dfx_utils_path}:libdinput_dfx_utils", + "${distributedinput_path}/services/state:libdinput_state", "${innerkits_path}:libdinput_sdk", "${services_source_path}/inputinject:libdinput_inject", "${services_source_path}/transport:libdinput_source_trans", diff --git a/services/source/sourcemanager/include/distributed_input_source_manager.h b/services/source/sourcemanager/include/distributed_input_source_manager.h index 412c2a4f4fc556bd88d63859c945d3e08cc28918..961192977ee6efebf0705968efeb8d97cddc1e08 100644 --- a/services/source/sourcemanager/include/distributed_input_source_manager.h +++ b/services/source/sourcemanager/include/distributed_input_source_manager.h @@ -37,6 +37,7 @@ #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" namespace OHOS { namespace DistributedHardware { @@ -490,7 +491,6 @@ private: int32_t RelayStopRemoteInputByDhid(const std::string &srcId, const std::string &sinkId, const std::vector &dhIds, sptr callback); bool IsStringDataSame(const std::vector &oldDhIds, std::vector newDhIds); - void StringSplitToVector(const std::string &str, const char split, std::vector &vecStr); void DeleteNodeInfoAndNotify(const std::string& offlineDevId); void SendExistVirNodeInfos(sptr listener); std::set GetSyncNodeInfo(const std::string& devId); diff --git a/services/source/sourcemanager/src/distributed_input_source_manager.cpp b/services/source/sourcemanager/src/distributed_input_source_manager.cpp index 39a78ef6d2ecf36550b166cf868d5700c6817319..4070002c523557f30e185081315bbe92103ac32d 100644 --- a/services/source/sourcemanager/src/distributed_input_source_manager.cpp +++ b/services/source/sourcemanager/src/distributed_input_source_manager.cpp @@ -34,6 +34,7 @@ #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" @@ -282,6 +283,10 @@ void DistributedInputSourceManager::DInputSourceListener::OnResponseStartRemoteI sourceManagerObj_->SetDeviceMapValue(deviceId, DINPUT_SOURCE_SWITCH_ON); } + std::vector vecStr; + StringSplitToVector(dhids, INPUT_STRING_SPLIT_POINT, vecStr); + DInputState::GetInstance().RecordDhids(vecStr, DhidState::THROUGH_IN, -1); + std::shared_ptr jsonArrayMsg = std::make_shared(); nlohmann::json tmpJson; tmpJson[INPUT_SOURCEMANAGER_KEY_DEVID] = deviceId; @@ -971,6 +976,12 @@ 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; } @@ -1121,6 +1132,9 @@ int32_t DistributedInputSourceManager::RegisterDistributedHardware(const std::st } cli->SyncNodeInfoRemoteInput(GetLocalNetworkId(), dhId, GetNodeDesc(parameters)); + + // 6. Notify node mgr to scan vir dev node info + DistributedInputInject::GetInstance().NotifyNodeMgrScanVirNode(dhId); return DH_SUCCESS; } @@ -2447,24 +2461,6 @@ void DistributedInputSourceManager::RunKeyStateCallback(const std::string &sinkI return; } -void DistributedInputSourceManager::StringSplitToVector(const std::string &str, const char split, - std::vector &vecStr) -{ - if (str.empty()) { - DHLOGE("StringSplitToVector param str is error."); - return; - } - std::string strTmp = str + split; - size_t pos = strTmp.find(split); - while (pos != strTmp.npos) { - std::string matchTmp = strTmp.substr(0, pos); - vecStr.push_back(matchTmp); - - strTmp = strTmp.substr(pos + 1, strTmp.size()); - pos = strTmp.find(split); - } -} - DInputServerType DistributedInputSourceManager::GetStartTransFlag() { return isStartTrans_; diff --git a/services/source/sourcemanager/test/sourcemanagerunittest/BUILD.gn b/services/source/sourcemanager/test/sourcemanagerunittest/BUILD.gn index 9b3bc45c9b985ed19019c63f38fa7d86101d3eba..9ec9226c5752121a9da93f72a5376129b95ddb5c 100755 --- a/services/source/sourcemanager/test/sourcemanagerunittest/BUILD.gn +++ b/services/source/sourcemanager/test/sourcemanagerunittest/BUILD.gn @@ -51,6 +51,7 @@ ohos_unittest("distributed_input_sourcemanager_test") { "${common_path}/test/mock", "${distributedinput_path}/services/transportbase/include", "${distributedinput_path}/utils/include", + "${distributedinput_path}/services/state/include", ] sources = [ @@ -109,6 +110,7 @@ ohos_unittest("distributed_input_sourcemanager_test") { deps = [ "${dfx_utils_path}:libdinput_dfx_utils", + "${distributedinput_path}/services/state:libdinput_state", "${innerkits_path}:libdinput_sdk", "${services_source_path}/transport:libdinput_source_trans", "//third_party/libevdev:libevdev", diff --git a/services/source/sourcemanager/test/sourcemanagerunittest/distributed_input_sourcemanager_test.cpp b/services/source/sourcemanager/test/sourcemanagerunittest/distributed_input_sourcemanager_test.cpp index db31c2a1c9752cd79887359f4f4abf3a52eb5e7e..8211fa301d58b296f70d98fd39dfd151f3ecd4a0 100644 --- a/services/source/sourcemanager/test/sourcemanagerunittest/distributed_input_sourcemanager_test.cpp +++ b/services/source/sourcemanager/test/sourcemanagerunittest/distributed_input_sourcemanager_test.cpp @@ -1588,14 +1588,6 @@ HWTEST_F(DistributedInputSourceManagerTest, RunRelayStopTypeCallback_01, testing EXPECT_EQ(1, sourceManager_->relayStpTypeCallbacks_.size()); } -HWTEST_F(DistributedInputSourceManagerTest, StringSplitToVector_01, testing::ext::TestSize.Level1) -{ - std::string str = ""; - std::vector vecStr; - sourceManager_->StringSplitToVector(str, ',', vecStr); - EXPECT_EQ(true, str.empty()); -} - HWTEST_F(DistributedInputSourceManagerTest, RemoveInputDeviceId_01, testing::ext::TestSize.Level1) { std::string deviceId = "umkyu1b165e1be98151891erbe8r91ev"; diff --git a/services/source/transport/BUILD.gn b/services/source/transport/BUILD.gn index 5796bcb72635b77315b35ae7f0478290ad908033..2c752ccd6d9682378f06ef009a58df5050182f0a 100755 --- a/services/source/transport/BUILD.gn +++ b/services/source/transport/BUILD.gn @@ -31,6 +31,7 @@ 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" ] @@ -43,6 +44,7 @@ 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 08d40df39306df42095e94be293f019211377dc1..6979d94e882563f681f935c6c42d10599bf60bbc 100644 --- a/services/source/transport/include/distributed_input_source_transport.h +++ b/services/source/transport/include/distributed_input_source_transport.h @@ -29,6 +29,7 @@ #include "nlohmann/json.hpp" #include "securec.h" +#include "dinput_state.h" #include "dinput_source_trans_callback.h" #include "dinput_transbase_source_callback.h" diff --git a/services/source/transport/src/distributed_input_source_transport.cpp b/services/source/transport/src/distributed_input_source_transport.cpp index e8676da751ed75805c69aadd3bdfb08d22526257..91d616dde46e4f6121381a1f8e6b45a3ef6c10b7 100644 --- a/services/source/transport/src/distributed_input_source_transport.cpp +++ b/services/source/transport/src/distributed_input_source_transport.cpp @@ -296,6 +296,10 @@ int32_t DistributedInputSourceTransport::StartRemoteInputDhids(int32_t srcTsrcSe } DHLOGI("StartRemoteInputDhids srcTsrcSeId:%d, sinkSessionId:%d.", srcTsrcSeId, sinkSessionId); + std::vector vecStr; + StringSplitToVector(dhids, INPUT_STRING_SPLIT_POINT, vecStr); + DInputState::GetInstance().RecordDhids(vecStr, 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; @@ -759,6 +763,8 @@ int32_t DistributedInputSourceTransport::StopRemoteInput(const std::string &devi } DHLOGI("StopRemoteInput sessionId:%d.", sessionId); + DInputState::GetInstance().RecordDhids(dhids, DhidState::THROUGH_OUT, -1); + nlohmann::json jsonStr; jsonStr[DINPUT_SOFTBUS_KEY_CMD_TYPE] = TRANS_SOURCE_MSG_STOP_DHID; jsonStr[DINPUT_SOFTBUS_KEY_DEVICE_ID] = deviceId; diff --git a/services/source/transport/test/sourcetransunittest/BUILD.gn b/services/source/transport/test/sourcetransunittest/BUILD.gn index b6b84bcc9ca22f5e84a0119f1eb380606ce0b7d2..6242cfe61cd75c77cc51f38f3991b45ff032bf08 100755 --- a/services/source/transport/test/sourcetransunittest/BUILD.gn +++ b/services/source/transport/test/sourcetransunittest/BUILD.gn @@ -46,6 +46,7 @@ ohos_unittest("distributed_input_sourcetrans_test") { "${utils_path}/include", "${ipc_path}/include", "${frameworks_path}/include", + "${distributedinput_path}/services/state/include", "${distributedinput_path}/inputdevicehandler/include", "${common_path}/test/mock", ] @@ -75,6 +76,7 @@ ohos_unittest("distributed_input_sourcetrans_test") { deps = [ "${dfx_utils_path}:libdinput_dfx_utils", + "${distributedinput_path}/services/state:libdinput_state", "${services_source_path}/inputinject:libdinput_inject", "${services_source_path}/sourcemanager:libdinput_source", "${utils_path}:libdinput_utils", diff --git a/services/state/BUILD.gn b/services/state/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..5ca8aafe437bee7d4bfef17ec5e4aac31796f37f --- /dev/null +++ b/services/state/BUILD.gn @@ -0,0 +1,65 @@ +# Copyright (c) 2023 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/ohos.gni") +import( + "//foundation/distributedhardware/distributed_input/distributedinput.gni") + +ohos_shared_library("libdinput_state") { + include_dirs = [ + "include", + "${common_path}/include", + "${utils_path}/include", + "${service_common}/include", + "${services_sink_path}/inputcollector/include", + "${distributedinput_path}/inputdevicehandler/include", + "${services_source_path}/inputinject/include", + "${services_sink_path}/transport/include", + "${frameworks_path}/include", + "${fwk_common_path}/utils/include", + ] + + sources = [ "src/dinput_state.cpp" ] + + defines = [ + "HI_LOG_ENABLE", + "DH_LOG_TAG=\"distributedinputstate\"", + "LOG_DOMAIN=0xD004100", + ] + + 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", + ] + + external_deps = [ + "c_utils:utils", + "distributed_hardware_fwk:libdhfwk_sdk", + "dsoftbus:softbus_client", + "eventhandler:libeventhandler", + "hitrace:hitrace_meter", + "ipc:ipc_core", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + ] + + cflags_cc = [ "-DHILOG_ENABLE" ] + + subsystem_name = "distributedhardware" + + part_name = "distributed_input" +} diff --git a/services/state/include/dinput_state.h b/services/state/include/dinput_state.h new file mode 100644 index 0000000000000000000000000000000000000000..8dd9b490e591a3370cc24326497f6db5199b3659 --- /dev/null +++ b/services/state/include/dinput_state.h @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef DISTRIBUTED_INPUT_STATE_BASE_H +#define DISTRIBUTED_INPUT_STATE_BASE_H + +#include +#include +#include +#include + +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 { +public: + static DInputState &GetInstance() + { + static DInputState instance; + return instance; + }; + + int32_t Init(); + int32_t Release(); + int32_t RecordDhids(const std::vector &dhids, DhidState state, const int32_t &sessionId); + int32_t RemoveDhids(const std::vector &dhids); + DhidState GetStateByDhid(std::string &dhid); + +private: + ~DInputState(); + + void CreateSpecialEventInjectThread(const int32_t &sessionId, const std::vector &dhids); + void CheckKeyboardState(std::string &dhid, std::string &keyboardNodePath, + std::vector &keyboardPressedKeys, int &fd); + void SpecEventInject(const int32_t &sessionId, std::vector dhids); + void RecordEventLog(const input_event &event); + void WriteEventToDev(int &fd, const input_event &event); + void CheckMouseKeyState(const int32_t &sessionId, const std::string &mouseNodePath, + const std::string &mouseNodeDhId); + +private: + std::mutex operationMutex_; + std::map dhidStateMap_; +}; +} // namespace DistributedInput +} // namespace DistributedHardware +} // namespace OHOS +#endif // DISTRIBUTED_INPUT_STATE_BASE_H \ No newline at end of file diff --git a/services/state/src/dinput_state.cpp b/services/state/src/dinput_state.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1ecdbfac4e03cccd5fdd1a60de7feb28b82dbd67 --- /dev/null +++ b/services/state/src/dinput_state.cpp @@ -0,0 +1,258 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "dinput_state.h" + +#include +#include +#include +#include +#include +#include + +#include "dinput_errcode.h" +#include "dinput_log.h" +#include "dinput_utils_tool.h" +#include "constants_dinput.h" +#include "distributed_input_collector.h" +#include "distributed_input_inject.h" +#include "distributed_input_sink_transport.h" + +namespace OHOS { +namespace DistributedHardware { +namespace DistributedInput { +DInputState::~DInputState() +{ + Release(); +} + +int32_t DInputState::Init() +{ + DHLOGI("DInputState Init."); + return DH_SUCCESS; +} + +int32_t DInputState::Release() +{ + DHLOGI("DInputState Release."); + std::unique_lock mapLock(operationMutex_); + dhidStateMap_.clear(); + return DH_SUCCESS; +} + +int32_t DInputState::RecordDhids(const std::vector &dhids, DhidState state, const int32_t &sessionId) +{ + DHLOGI("RecordDhids dhids size = %zu", dhids.size()); + std::unique_lock mapLock(operationMutex_); + for (auto &dhid : dhids) { + DHLOGD("add dhid : %s, state : %d.", GetAnonyString(dhid).c_str(), state); + dhidStateMap_[dhid] = state; + } + + if (state == DhidState::THROUGH_OUT) { + CreateSpecialEventInjectThread(sessionId, dhids); + } + return DH_SUCCESS; +} + +int32_t DInputState::RemoveDhids(const std::vector &dhids) +{ + DHLOGI("RemoveDhids dhids size = %zu", dhids.size()); + std::unique_lock mapLock(operationMutex_); + for (auto &dhid : dhids) { + DHLOGD("delete dhid : %s", GetAnonyString(dhid).c_str()); + dhidStateMap_.erase(dhid); + } + return DH_SUCCESS; +} + +DhidState DInputState::GetStateByDhid(std::string &dhid) +{ + std::unique_lock mapLock(operationMutex_); + if (dhidStateMap_.find(dhid) == dhidStateMap_.end()) { + DHLOGE("dhid : %s not exist.", GetAnonyString(dhid).c_str()); + return DhidState::THROUGH_IN; + } + return dhidStateMap_[dhid]; +} + +void DInputState::CreateSpecialEventInjectThread(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."); + } + 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"; + 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 DInputState::WriteEventToDev(int &fd, const input_event &event) +{ + if (write(fd, &event, sizeof(event)) < static_cast(sizeof(event))) { + DHLOGE("could not inject event, removed? (fd: %d)", fd); + return; + } + RecordEventLog(event); +} + +void DInputState::SpecEventInject(const int32_t &sessionId, std::vector dhids) +{ + DHLOGI("SpecEveInject enter"); + // mouse event send to remote device + if (sessionId != -1) { + std::string mouseNodePath; + std::string mouseNodeDhId; + DistributedInputCollector::GetInstance().GetMouseNodePath(dhids, mouseNodePath, mouseNodeDhId); + CheckMouseKeyState(sessionId, mouseNodePath, mouseNodeDhId); + } + + // keyboard up event inject local device + std::vector keyboardNodePaths; + std::vector keyboardNodeDhIds; + DistributedInputCollector::GetInstance().GetShareKeyboardPathsByDhIds(dhids, keyboardNodePaths, keyboardNodeDhIds); + DistributedInputInject::GetInstance().GetVirtualKeyboardPathsByDhIds(dhids, keyboardNodePaths, keyboardNodeDhIds); + ssize_t len = keyboardNodePaths.size(); + for (ssize_t i = 0; i < len; ++i) { + std::vector keyboardPressedKeys; + int fd = -1; + CheckKeyboardState(keyboardNodeDhIds[i], keyboardNodePaths[i], keyboardPressedKeys, fd); + for (auto &code : keyboardPressedKeys) { + struct input_event event = { + .type = EV_KEY, + .code = code, + .value = KEY_UP_STATE + }; + WriteEventToDev(fd, event); + event.type = EV_SYN; + event.code = 0; + WriteEventToDev(fd, event); + } + CloseFd(fd); + } +} + +void DInputState::CheckKeyboardState(std::string &dhid, std::string &keyboardNodePath, + std::vector &keyboardPressedKeys, int &fd) +{ + 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()); + return; + } + fd = open(canonicalPath, O_WRONLY | O_NONBLOCK); + if (fd < 0) { + DHLOGE("open keyboard Node Path error:", errno); + 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 yalv = 0; yalv < KEY_MAX; yalv++) { + if (BitIsSet(keystate, yalv)) { + DHLOGD("yalv = %d, not up.", yalv); + keyboardPressedKeys.push_back(yalv); + } + } + break; + } +} + +void DInputState::CheckMouseKeyState(const int32_t &sessionId, const std::string &mouseNodePath, + const std::string &mouseNodeDhId) +{ + DHLOGI("CheckMouseKeyState 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()); + return; + } + int fd = open(canonicalPath, O_RDONLY | O_NONBLOCK); + if (fd < 0) { + DHLOGE("open mouse Node Path error:", errno); + 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); +} +} // namespace DistributedInput +} // namespace DistributedHardware +} // namespace OHOSs \ No newline at end of file diff --git a/services/transportbase/test/transbaseunittest/BUILD.gn b/services/transportbase/test/transbaseunittest/BUILD.gn index 7b090229b2df01d80ea8729035d148effc1a3f9f..60d4bf97ad71472e675c8f5676d0f52474ae62a7 100644 --- a/services/transportbase/test/transbaseunittest/BUILD.gn +++ b/services/transportbase/test/transbaseunittest/BUILD.gn @@ -43,6 +43,7 @@ ohos_unittest("distributed_input_transbase_test") { "${frameworks_path}/include", "//third_party/json/include", "${distributedinput_path}/inputdevicehandler/include", + "${distributedinput_path}/services/state/include", "${common_path}/test/mock", ] diff --git a/sourcehandler/BUILD.gn b/sourcehandler/BUILD.gn index 2c927d1f58d312e1f0f410d4aede1535ceb77cb8..2cf11d72401710187c546c93beb88694e50ebb88 100644 --- a/sourcehandler/BUILD.gn +++ b/sourcehandler/BUILD.gn @@ -33,6 +33,7 @@ ohos_shared_library("libdinput_source_handler") { "${fwk_interfaces_path}/include/ipc", "${utils_path}/include", "${services_source_path}/inputinject/include", + "${distributedinput_path}/services/state/include", ] sources = [ diff --git a/sourcehandler/test/unittest/BUILD.gn b/sourcehandler/test/unittest/BUILD.gn index 7c43860e504454c76c998e1e770502c5967e69d8..a1fee4138a2c7ddcb8ee4192b1f80db163c7c87a 100755 --- a/sourcehandler/test/unittest/BUILD.gn +++ b/sourcehandler/test/unittest/BUILD.gn @@ -44,6 +44,7 @@ ohos_unittest("distributed_input_source_handler_test") { "${fwk_interfaces_path}/include", "${fwk_interfaces_path}/include/ipc", "${services_source_path}/inputinject/include", + "${distributedinput_path}/services/state/include", "${utils_path}/include", ] diff --git a/test/fuzztest/dinputconfigdh_fuzzer/BUILD.gn b/test/fuzztest/dinputconfigdh_fuzzer/BUILD.gn index c6d933a142f8fdb0a4b53d72e6c43deb13162370..58863e47b2ac866abb7916e003a92b7ebaeef445 100644 --- a/test/fuzztest/dinputconfigdh_fuzzer/BUILD.gn +++ b/test/fuzztest/dinputconfigdh_fuzzer/BUILD.gn @@ -33,6 +33,7 @@ ohos_fuzztest("DinputConfigDhFuzzTest") { "${distributedinput_path}/frameworks/include", "${distributedinput_path}/sourcehandler/include", "${distributedinput_path}/inputdevicehandler/include", + "${distributedinput_path}/services/state/include", "${service_common}/include", "${common_path}/include", "${fwk_common_path}/log/include", diff --git a/test/fuzztest/dinputinitsource_fuzzer/BUILD.gn b/test/fuzztest/dinputinitsource_fuzzer/BUILD.gn index e0218b838b74748f4ca0c2f18c0004dddfa40455..b5b2bd52dd8740a4b74ccb1cbf17cb4ef6dc8dbd 100644 --- a/test/fuzztest/dinputinitsource_fuzzer/BUILD.gn +++ b/test/fuzztest/dinputinitsource_fuzzer/BUILD.gn @@ -30,6 +30,7 @@ ohos_fuzztest("DinputInitSourceFuzzTest") { "${distributedinput_path}/interfaces/ipc/include", "${distributedinput_path}/services/source/sourcemanager/include", "${distributedinput_path}/services/sink/sinkmanager/include", + "${distributedinput_path}/services/state/include", "${distributedinput_path}/frameworks/include", "${distributedinput_path}/sourcehandler/include", "${distributedinput_path}/inputdevicehandler/include", diff --git a/test/fuzztest/dinputreleasesource_fuzzer/BUILD.gn b/test/fuzztest/dinputreleasesource_fuzzer/BUILD.gn index 48852523d5cf565fb162c079bfce6f85f9b9e188..af05d70fe7502be94d5790858a2b42477975639f 100644 --- a/test/fuzztest/dinputreleasesource_fuzzer/BUILD.gn +++ b/test/fuzztest/dinputreleasesource_fuzzer/BUILD.gn @@ -33,6 +33,7 @@ ohos_fuzztest("DinputReleaseSourceFuzzTest") { "${distributedinput_path}/frameworks/include", "${distributedinput_path}/sourcehandler/include", "${distributedinput_path}/inputdevicehandler/include", + "${distributedinput_path}/services/state/include", "${service_common}/include", "${common_path}/include", "${fwk_common_path}/log/include", diff --git a/test/fuzztest/distributedinputclient_fuzzer/BUILD.gn b/test/fuzztest/distributedinputclient_fuzzer/BUILD.gn index a902db65db239b2e2e96c28e8414c55f2191afe1..4c6ecaa5efb4e145733933c9e3ddf1c7921be8de 100755 --- a/test/fuzztest/distributedinputclient_fuzzer/BUILD.gn +++ b/test/fuzztest/distributedinputclient_fuzzer/BUILD.gn @@ -35,6 +35,7 @@ ohos_fuzztest("DistributedInputClientFuzzTest") { "${distributedinput_path}/sourcehandler/include", "${distributedinput_path}/sinkhandler/include", "${distributedinput_path}/inputdevicehandler/include", + "${distributedinput_path}/services/state/include", "${service_common}/include", "${common_path}/include", "${fwk_common_path}/log/include", diff --git a/test/fuzztest/distributedinputkit_fuzzer/BUILD.gn b/test/fuzztest/distributedinputkit_fuzzer/BUILD.gn index 9e1a052dce2ae056db47e98621bb01ad19fb72a5..280c9a995e8d640e09af797911a991b848c74fde 100755 --- a/test/fuzztest/distributedinputkit_fuzzer/BUILD.gn +++ b/test/fuzztest/distributedinputkit_fuzzer/BUILD.gn @@ -43,6 +43,7 @@ ohos_fuzztest("DistributedInputKitFuzzTest") { "${fwk_interfaces_path}/include", "${fwk_interfaces_path}/include/ipc", "${services_source_path}/inputinject/include", + "${distributedinput_path}/services/state/include", ] cflags = [ diff --git a/test/fuzztest/distributedinputsourcetransport_fuzzer/BUILD.gn b/test/fuzztest/distributedinputsourcetransport_fuzzer/BUILD.gn index dd1c5ba2d3aa337ae0b3a9fb644e308d4aba7a32..976f06500fbbed37410d9696fdb094a6dbba89b6 100755 --- a/test/fuzztest/distributedinputsourcetransport_fuzzer/BUILD.gn +++ b/test/fuzztest/distributedinputsourcetransport_fuzzer/BUILD.gn @@ -39,6 +39,7 @@ ohos_fuzztest("DistributedInputSourceTransportFuzzTest") { "${utils_path}/include", "${frameworks_path}/include", "${distributedinput_path}/inputdevicehandler/include", + "${distributedinput_path}/services/state/include", ] cflags = [ diff --git a/utils/include/dinput_utils_tool.h b/utils/include/dinput_utils_tool.h index dba9054c0e6fe5963acef26975f9b950399fc5fd..8092ce2bc07b5360ec0763a8692aa0c2af53fb81 100644 --- a/utils/include/dinput_utils_tool.h +++ b/utils/include/dinput_utils_tool.h @@ -50,8 +50,13 @@ std::string GetNodeDesc(std::string parameters); std::string GetAnonyString(const std::string &value); std::string GetAnonyInt32(const int32_t value); std::string Sha256(const std::string& string); +void CloseFd(int& fd); +int BitIsSet(const unsigned long *array, int bit); +void StringSplitToVector(const std::string& str, const char split, std::vector& vecStr); +int OpenInputDeviceFdByPath(std::string devicePath); +std::string ConvertErrNo(); +void ScanInputDevicesPath(std::string dirName, std::vector& vecInputDevPath); } // namespace DistributedInput } // namespace DistributedHardware } // namespace OHOS - #endif // OHOS_DISTRIBUTED_INPUT_UTILS_TOOL_H \ No newline at end of file diff --git a/utils/src/dinput_utils_tool.cpp b/utils/src/dinput_utils_tool.cpp index 0cda783c3d8c0137cb0ba7f5aad1b02168809f37..bb6db414a52ffa45caaf4127e85e92767a3dcc7f 100644 --- a/utils/src/dinput_utils_tool.cpp +++ b/utils/src/dinput_utils_tool.cpp @@ -17,8 +17,12 @@ #include #include +#include +#include #include - +#include +#include +#include #include #include "nlohmann/json.hpp" @@ -46,6 +50,9 @@ namespace { constexpr unsigned char MASK = 0x0F; constexpr int32_t DOUBLE_TIMES = 2; constexpr int32_t INT32_STRING_LENGTH = 40; + constexpr int32_t MAX_RETRY_COUNT = 10; + constexpr uint32_t SLEEP_TIME_US = 100 * 1000; + constexpr uint32_t ERROR_MSG_MAX_LEN = 256; } DevInfo GetLocalDeviceInfo() { @@ -285,6 +292,98 @@ std::string Sha256(const std::string& in) out[SHA256_DIGEST_LENGTH * DOUBLE_TIMES] = 0; return reinterpret_cast(out); } + +void CloseFd(int& fd) +{ + if (fd < 0) { + DHLOGE("No fd need to beclosed."); + return; + } + close(fd); + fd = -1; +} + +int BitIsSet(const unsigned long *array, int bit) +{ + return !!(array[bit / LONG_BITS] & (1LL << (bit % LONG_BITS))); +} + +void StringSplitToVector(const std::string& str, const char split, std::vector& vecStr) +{ + if (str.empty()) { + DHLOGE("StringSplitToVector param str is error."); + return; + } + std::string strTmp = str + split; + size_t pos = strTmp.find(split); + while (pos != strTmp.npos) { + std::string matchTmp = strTmp.substr(0, pos); + vecStr.push_back(matchTmp); + strTmp = strTmp.substr(pos + 1, strTmp.size()); + pos = strTmp.find(split); + } +} + +int OpenInputDeviceFdByPath(std::string devicePath) +{ + chmod(devicePath.c_str(), S_IWRITE | S_IREAD); + char canonicalDevicePath[PATH_MAX] = {0x00}; + if (devicePath.length() == 0 || devicePath.length() >= PATH_MAX || + realpath(devicePath.c_str(), canonicalDevicePath) == nullptr) { + DHLOGE("path check fail, error path: %s", devicePath.c_str()); + return -1; + } + struct stat s; + if ((stat(canonicalDevicePath, &s) == 0) && (s.st_mode & S_IFDIR)) { + DHLOGI("path: %s is a dir.", devicePath.c_str()); + return -1; + } + int fd = open(canonicalDevicePath, O_RDWR | O_CLOEXEC | O_NONBLOCK); + int32_t count = 0; + while ((fd < 0) && (count < MAX_RETRY_COUNT)) { + ++count; + usleep(SLEEP_TIME_US); + fd = open(canonicalDevicePath, O_RDWR | O_CLOEXEC | O_NONBLOCK); + DHLOGE("could not open %s, %s; retry %d\n", devicePath.c_str(), ConvertErrNo().c_str(), count); + } + if (count >= MAX_RETRY_COUNT) { + DHLOGE("could not open %s, %s\n", devicePath.c_str(), ConvertErrNo().c_str()); + CloseFd(fd); + return -1; + } + return fd; +} + +std::string ConvertErrNo() +{ + char errMsg[ERROR_MSG_MAX_LEN] = {0}; + strerror_r(errno, errMsg, ERROR_MSG_MAX_LEN); + std::string errNoMsg(errMsg); + return errNoMsg; +} + +void ScanInputDevicesPath(std::string dirName, std::vector& vecInputDevPath) +{ + DIR *dir; + struct dirent *de; + dir = opendir(dirName.c_str()); + if (dir == nullptr) { + DHLOGE("error opendir /dev/input :%{public}s\n", ConvertErrNo().c_str()); + return; + } + size_t dirNameFirstPos = 0; + size_t dirNameSecondPos = 1; + size_t dirNameThirdPos = 2; + while ((de = readdir(dir))) { + if (de->d_name[dirNameFirstPos] == '.' && (de->d_name[dirNameSecondPos] == '\0' || + (de->d_name[dirNameSecondPos] == '.' && de->d_name[dirNameThirdPos] == '\0'))) { + continue; + } + std::string tmpDevName = dirName + "/" + std::string(de->d_name); + vecInputDevPath.push_back(tmpDevName); + } + closedir(dir); +} } // namespace DistributedInput } // namespace DistributedHardware } // namespace OHOS \ No newline at end of file