1 /*
2 * Copyright (c) 2021-2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "distributed_input_node_manager.h"
17
18 #include <cinttypes>
19 #include <cstring>
20
21 #include <pthread.h>
22
23 #include "softbus_bus_center.h"
24
25 #include "dinput_context.h"
26 #include "dinput_errcode.h"
27 #include "dinput_log.h"
28 #include "dinput_softbus_define.h"
29 #include "dinput_utils_tool.h"
30
31 namespace OHOS {
32 namespace DistributedHardware {
33 namespace DistributedInput {
34 namespace {
35 constexpr int32_t RETRY_MAX_TIMES = 3;
36 constexpr uint32_t SLEEP_TIME_US = 10 * 1000;
37 }
DistributedInputNodeManager()38 DistributedInputNodeManager::DistributedInputNodeManager() : isInjectThreadCreated_(false),
39 isInjectThreadRunning_(false), virtualTouchScreenFd_(UN_INIT_FD_VALUE)
40 {
41 DHLOGI("DistributedInputNodeManager ctor");
42 std::shared_ptr<AppExecFwk::EventRunner> runner = AppExecFwk::EventRunner::Create(true);
43 callBackHandler_ = std::make_shared<DistributedInputNodeManager::DInputNodeManagerEventHandler>(runner, this);
44 }
45
~DistributedInputNodeManager()46 DistributedInputNodeManager::~DistributedInputNodeManager()
47 {
48 DHLOGI("DistributedInputNodeManager dtor");
49 isInjectThreadCreated_.store(false);
50 isInjectThreadRunning_.store(false);
51 if (eventInjectThread_.joinable()) {
52 eventInjectThread_.join();
53 }
54 {
55 std::lock_guard<std::mutex> lock(virtualDeviceMapMutex_);
56 virtualDeviceMap_.clear();
57 }
58 DHLOGI("destructor end");
59 }
60
OpenDevicesNode(const std::string & devId,const std::string & dhId,const std::string & parameters)61 int32_t DistributedInputNodeManager::OpenDevicesNode(const std::string &devId, const std::string &dhId,
62 const std::string ¶meters)
63 {
64 if (devId.size() > DEV_ID_LENGTH_MAX || devId.empty() || dhId.size() > DH_ID_LENGTH_MAX || dhId.empty() ||
65 parameters.size() > STRING_MAX_SIZE || parameters.empty()) {
66 DHLOGE("Params is invalid!");
67 return ERR_DH_INPUT_SERVER_SOURCE_OPEN_DEVICE_NODE_FAIL;
68 }
69 InputDevice event;
70 ParseInputDeviceJson(parameters, event);
71 if (CreateHandle(event, devId, dhId) < 0) {
72 DHLOGE("Can not create virtual node!");
73 return ERR_DH_INPUT_SERVER_SOURCE_OPEN_DEVICE_NODE_FAIL;
74 }
75 return DH_SUCCESS;
76 }
77
ParseInputDeviceJson(const std::string & str,InputDevice & pBuf)78 void DistributedInputNodeManager::ParseInputDeviceJson(const std::string &str, InputDevice &pBuf)
79 {
80 nlohmann::json inputDeviceJson = nlohmann::json::parse(str, nullptr, false);
81 if (inputDeviceJson.is_discarded()) {
82 DHLOGE("recMsg parse failed!");
83 return;
84 }
85 ParseInputDevice(inputDeviceJson, pBuf);
86 }
87
ParseInputDevice(const nlohmann::json & inputDeviceJson,InputDevice & pBuf)88 void DistributedInputNodeManager::ParseInputDevice(const nlohmann::json &inputDeviceJson, InputDevice &pBuf)
89 {
90 ParseInputDeviceBasicInfo(inputDeviceJson, pBuf);
91 ParseInputDeviceEvents(inputDeviceJson, pBuf);
92 }
93
ParseInputDeviceBasicInfo(const nlohmann::json & inputDeviceJson,InputDevice & pBuf)94 void DistributedInputNodeManager::ParseInputDeviceBasicInfo(const nlohmann::json &inputDeviceJson, InputDevice &pBuf)
95 {
96 if (IsString(inputDeviceJson, DEVICE_NAME)) {
97 pBuf.name = inputDeviceJson[DEVICE_NAME].get<std::string>();
98 }
99 if (IsString(inputDeviceJson, PHYSICAL_PATH)) {
100 pBuf.physicalPath = inputDeviceJson[PHYSICAL_PATH].get<std::string>();
101 }
102 if (IsString(inputDeviceJson, UNIQUE_ID)) {
103 pBuf.uniqueId = inputDeviceJson[UNIQUE_ID].get<std::string>();
104 }
105 if (IsUInt16(inputDeviceJson, BUS)) {
106 pBuf.bus = inputDeviceJson[BUS].get<uint16_t>();
107 }
108 if (IsUInt16(inputDeviceJson, VENDOR)) {
109 pBuf.vendor = inputDeviceJson[VENDOR].get<uint16_t>();
110 }
111 if (IsUInt16(inputDeviceJson, PRODUCT)) {
112 pBuf.product = inputDeviceJson[PRODUCT].get<uint16_t>();
113 }
114 if (IsUInt16(inputDeviceJson, VERSION)) {
115 pBuf.version = inputDeviceJson[VERSION].get<uint16_t>();
116 }
117 if (IsString(inputDeviceJson, DESCRIPTOR)) {
118 pBuf.descriptor = inputDeviceJson[DESCRIPTOR].get<std::string>();
119 }
120 if (IsUInt32(inputDeviceJson, CLASSES)) {
121 pBuf.classes = inputDeviceJson[CLASSES].get<uint32_t>();
122 }
123 }
124
ParseInputDeviceEvents(const nlohmann::json & inputDeviceJson,InputDevice & pBuf)125 void DistributedInputNodeManager::ParseInputDeviceEvents(const nlohmann::json &inputDeviceJson, InputDevice &pBuf)
126 {
127 if (IsArray(inputDeviceJson, EVENT_TYPES)) {
128 pBuf.eventTypes = inputDeviceJson[EVENT_TYPES].get<std::vector<uint32_t>>();
129 }
130 if (IsArray(inputDeviceJson, EVENT_KEYS)) {
131 pBuf.eventKeys = inputDeviceJson[EVENT_KEYS].get<std::vector<uint32_t>>();
132 }
133 if (IsArray(inputDeviceJson, ABS_TYPES)) {
134 pBuf.absTypes = inputDeviceJson[ABS_TYPES].get<std::vector<uint32_t>>();
135 }
136 if (IsArray(inputDeviceJson, ABS_INFOS)) {
137 pBuf.absInfos = inputDeviceJson[ABS_INFOS].get<std::map<uint32_t, std::vector<int32_t>>>();
138 }
139 if (IsArray(inputDeviceJson, REL_TYPES)) {
140 pBuf.relTypes = inputDeviceJson[REL_TYPES].get<std::vector<uint32_t>>();
141 }
142 if (IsArray(inputDeviceJson, PROPERTIES)) {
143 pBuf.properties = inputDeviceJson[PROPERTIES].get<std::vector<uint32_t>>();
144 }
145 if (IsArray(inputDeviceJson, MISCELLANEOUS)) {
146 pBuf.miscellaneous = inputDeviceJson[MISCELLANEOUS].get<std::vector<uint32_t>>();
147 }
148 if (IsArray(inputDeviceJson, LEDS)) {
149 pBuf.leds = inputDeviceJson[LEDS].get<std::vector<uint32_t>>();
150 }
151 if (IsArray(inputDeviceJson, REPEATS)) {
152 pBuf.repeats = inputDeviceJson[REPEATS].get<std::vector<uint32_t>>();
153 }
154 if (IsArray(inputDeviceJson, SWITCHS)) {
155 pBuf.switchs = inputDeviceJson[SWITCHS].get<std::vector<uint32_t>>();
156 }
157 }
158
ScanSinkInputDevices(const std::string & devId,const std::string & dhId)159 void DistributedInputNodeManager::ScanSinkInputDevices(const std::string &devId, const std::string &dhId)
160 {
161 DHLOGI("ScanSinkInputDevices enter, deviceId: %{public}s, dhId: %{public}s.",
162 GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str());
163 std::vector<std::string> vecInputDevPath;
164 ScanInputDevicesPath(DEVICE_PATH, vecInputDevPath);
165 for (auto &tempPath: vecInputDevPath) {
166 if (MatchAndSavePhysicalPath(tempPath, devId, dhId)) {
167 DHLOGI("Set physical path success");
168 break;
169 }
170 }
171 }
172
ProcessEvent(const AppExecFwk::InnerEvent::Pointer & event)173 void DistributedInputNodeManager::DInputNodeManagerEventHandler::ProcessEvent(
174 const AppExecFwk::InnerEvent::Pointer &event)
175 {
176 DHLOGI("ProcessEvent enter.");
177 auto iter = eventFuncMap_.find(event->GetInnerEventId());
178 if (iter == eventFuncMap_.end()) {
179 DHLOGE("Event Id %{public}d is undefined.", event->GetInnerEventId());
180 return;
181 }
182 nodeMgrFunc &func = iter->second;
183 (this->*func)(event);
184 }
185
DInputNodeManagerEventHandler(const std::shared_ptr<AppExecFwk::EventRunner> & runner,DistributedInputNodeManager * manager)186 DistributedInputNodeManager::DInputNodeManagerEventHandler::DInputNodeManagerEventHandler(
187 const std::shared_ptr<AppExecFwk::EventRunner> &runner, DistributedInputNodeManager *manager)
188 : AppExecFwk::EventHandler(runner)
189 {
190 eventFuncMap_[DINPUT_NODE_MANAGER_SCAN_ALL_NODE] = &DInputNodeManagerEventHandler::ScanAllNode;
191
192 nodeManagerObj_ = manager;
193 }
194
~DInputNodeManagerEventHandler()195 DistributedInputNodeManager::DInputNodeManagerEventHandler::~DInputNodeManagerEventHandler()
196 {
197 eventFuncMap_.clear();
198 nodeManagerObj_ = nullptr;
199 }
200
ScanAllNode(const AppExecFwk::InnerEvent::Pointer & event)201 void DistributedInputNodeManager::DInputNodeManagerEventHandler::ScanAllNode(
202 const AppExecFwk::InnerEvent::Pointer &event)
203 {
204 DHLOGI("ScanAllNode enter.");
205 if (event == nullptr) {
206 DHLOGE("event is null.");
207 return;
208 }
209 std::shared_ptr<nlohmann::json> dataMsg = event->GetSharedObject<nlohmann::json>();
210 if (dataMsg == nullptr) {
211 DHLOGE("dataMsg is null.");
212 return;
213 }
214 auto it = dataMsg->begin();
215 nlohmann::json innerMsg = *(it);
216 std::string devId = innerMsg[INPUT_NODE_DEVID];
217 std::string devicedhId = innerMsg[INPUT_NODE_DHID];
218 nodeManagerObj_->ScanSinkInputDevices(devId, devicedhId);
219 }
220
NotifyNodeMgrScanVirNode(const std::string & devId,const std::string & dhId)221 void DistributedInputNodeManager::NotifyNodeMgrScanVirNode(const std::string &devId, const std::string &dhId)
222 {
223 DHLOGI("NotifyNodeMgrScanVirNode enter.");
224 std::shared_ptr<nlohmann::json> jsonArrayMsg = std::make_shared<nlohmann::json>();
225 nlohmann::json tmpJson;
226 tmpJson[INPUT_NODE_DEVID] = devId;
227 tmpJson[INPUT_NODE_DHID] = dhId;
228 jsonArrayMsg->push_back(tmpJson);
229 AppExecFwk::InnerEvent::Pointer msgEvent = AppExecFwk::InnerEvent::Get(
230 DINPUT_NODE_MANAGER_SCAN_ALL_NODE, jsonArrayMsg, 0);
231 callBackHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
232 }
233
IsVirtualDev(int fd)234 bool DistributedInputNodeManager::IsVirtualDev(int fd)
235 {
236 char buffer[INPUT_EVENT_BUFFER_SIZE] = {0};
237 std::string deviceName;
238 if (ioctl(fd, EVIOCGNAME(sizeof(buffer) - 1), &buffer) < 1) {
239 DHLOGE("Could not get device name for %{public}s.", ConvertErrNo().c_str());
240 return false;
241 }
242 buffer[sizeof(buffer) - 1] = '\0';
243 deviceName = buffer;
244
245 DHLOGD("IsVirtualDev deviceName: %{public}s", buffer);
246 if (deviceName.find(VIRTUAL_DEVICE_NAME) == std::string::npos) {
247 DHLOGD("This is not a virtual device, fd %{public}d, deviceName: %{public}s.", fd, deviceName.c_str());
248 return false;
249 }
250 return true;
251 }
252
GetDevDhUniqueIdByFd(int fd,DhUniqueID & dhUnqueId,std::string & physicalPath)253 bool DistributedInputNodeManager::GetDevDhUniqueIdByFd(int fd, DhUniqueID &dhUnqueId, std::string &physicalPath)
254 {
255 char buffer[INPUT_EVENT_BUFFER_SIZE] = {0};
256 if (ioctl(fd, EVIOCGPHYS(sizeof(buffer) - 1), &buffer) < 1) {
257 DHLOGE("Could not get device physicalPath for %{public}s.", ConvertErrNo().c_str());
258 return false;
259 }
260 buffer[sizeof(buffer) - 1] = '\0';
261 physicalPath = buffer;
262
263 DHLOGD("GetDevDhUniqueIdByFd physicalPath %{public}s.", physicalPath.c_str());
264 std::vector<std::string> phyPathVec;
265 SplitStringToVector(physicalPath, VIR_NODE_SPLIT_CHAR, phyPathVec);
266 if (phyPathVec.size() != VIR_NODE_PHY_LEN) {
267 DHLOGE("The physical path is invalid");
268 return false;
269 }
270 std::string devId = phyPathVec[VIR_NODE_PHY_DEVID_IDX];
271 std::string dhId = phyPathVec[VIR_NODE_PHY_DHID_IDX];
272 if (devId.empty() || dhId.empty()) {
273 DHLOGE("Get dev deviceid and dhid failed.");
274 return false;
275 }
276 dhUnqueId.first = devId;
277 dhUnqueId.second = dhId;
278 DHLOGD("Device deviceid: %{public}s, dhId %{public}s.", GetAnonyString(devId).c_str(),
279 GetAnonyString(dhId).c_str());
280 return true;
281 }
282
SetPathForVirDev(const DhUniqueID & dhUniqueId,const std::string & devicePath)283 void DistributedInputNodeManager::SetPathForVirDev(const DhUniqueID &dhUniqueId, const std::string &devicePath)
284 {
285 std::lock_guard<std::mutex> lock(virtualDeviceMapMutex_);
286 auto iter = virtualDeviceMap_.begin();
287 while (iter != virtualDeviceMap_.end()) {
288 DHLOGD("Check Virtual device, deviceId %{public}s, dhid %{public}s.", GetAnonyString(iter->first.first).c_str(),
289 GetAnonyString(iter->first.second).c_str());
290 if (iter->first == dhUniqueId) {
291 DHLOGD("Found the virtual device, set path :%{public}s", devicePath.c_str());
292 iter->second->SetPath(devicePath);
293 break;
294 }
295 iter++;
296 }
297 }
298
MatchAndSavePhysicalPath(const std::string & devicePath,const std::string & devId,const std::string & dhId)299 bool DistributedInputNodeManager::MatchAndSavePhysicalPath(const std::string &devicePath,
300 const std::string &devId, const std::string &dhId)
301 {
302 DHLOGI("Opening input device path: %{public}s", devicePath.c_str());
303 DhUniqueID curDhUniqueId;
304 std::string physicalPath;
305 int fd = OpenInputDeviceFdByPath(devicePath);
306 if (fd == UN_INIT_FD_VALUE) {
307 DHLOGE("The fd open failed, devicePath %{public}s.", devicePath.c_str());
308 return false;
309 }
310 if (!IsVirtualDev(fd)) {
311 DHLOGE("The dev not virtual, devicePath %{public}s.", devicePath.c_str());
312 CloseFd(fd);
313 return false;
314 }
315 if (!GetDevDhUniqueIdByFd(fd, curDhUniqueId, physicalPath)) {
316 DHLOGE("Get unique id failed, device path %{public}s.", devicePath.c_str());
317 CloseFd(fd);
318 return false;
319 }
320
321 DHLOGD("This opening node deviceId: %{public}s, dhId: %{public}s, to match node deviceId: %{public}s, "
322 "dhId: %{public}s", GetAnonyString(curDhUniqueId.first).c_str(), GetAnonyString(curDhUniqueId.second).c_str(),
323 GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str());
324
325 if (curDhUniqueId.first != devId || curDhUniqueId.second != dhId) {
326 DHLOGW("It is not the target vir node, skip it.");
327 CloseFd(fd);
328 return false;
329 }
330
331 SetPathForVirDev(curDhUniqueId, devicePath);
332 CloseFd(fd);
333 return true;
334 }
335
GetVirtualKeyboardPaths(const std::vector<DhUniqueID> & dhUniqueIds,std::vector<std::string> & virKeyboardPaths)336 void DistributedInputNodeManager::GetVirtualKeyboardPaths(const std::vector<DhUniqueID> &dhUniqueIds,
337 std::vector<std::string> &virKeyboardPaths)
338 {
339 std::lock_guard<std::mutex> lock(virtualDeviceMapMutex_);
340 for (const auto &dhUniqueId : dhUniqueIds) {
341 auto iter = virtualDeviceMap_.begin();
342 while (iter != virtualDeviceMap_.end()) {
343 if (iter->second == nullptr) {
344 DHLOGE("device is nullptr");
345 continue;
346 }
347 if ((iter->first == dhUniqueId) &&
348 ((iter->second->GetClasses() & INPUT_DEVICE_CLASS_KEYBOARD) != 0)) {
349 DHLOGI("Found vir keyboard path %{public}s, deviceId %{public}s, dhid %{public}s",
350 iter->second->GetPath().c_str(), GetAnonyString(dhUniqueId.first).c_str(),
351 GetAnonyString(dhUniqueId.second).c_str());
352 virKeyboardPaths.push_back(iter->second->GetPath());
353 }
354 iter++;
355 }
356 }
357 }
358
CreateHandle(const InputDevice & inputDevice,const std::string & devId,const std::string & dhId)359 int32_t DistributedInputNodeManager::CreateHandle(const InputDevice &inputDevice, const std::string &devId,
360 const std::string &dhId)
361 {
362 std::unique_lock<std::mutex> my_lock(operationMutex_);
363 std::unique_ptr<VirtualDevice> virtualDevice = std::make_unique<VirtualDevice>(inputDevice);
364
365 virtualDevice->SetNetWorkId(devId);
366
367 if (!virtualDevice->SetUp(inputDevice, devId, dhId)) {
368 DHLOGE("could not create new virtual device\n");
369 for (int32_t i = 0; i < RETRY_MAX_TIMES; ++i) {
370 if (virtualDevice->SetUp(inputDevice, devId, dhId)) {
371 DHLOGI("Create new virtual success");
372 AddDeviceLocked(devId, inputDevice.descriptor, std::move(virtualDevice));
373 return DH_SUCCESS;
374 }
375 usleep(SLEEP_TIME_US);
376 }
377 return ERR_DH_INPUT_SERVER_SOURCE_CREATE_HANDLE_FAIL;
378 }
379 AddDeviceLocked(devId, inputDevice.descriptor, std::move(virtualDevice));
380 return DH_SUCCESS;
381 }
382
CreateVirtualTouchScreenNode(const std::string & devId,const std::string & dhId,const uint64_t srcWinId,const uint32_t sourcePhyWidth,const uint32_t sourcePhyHeight)383 int32_t DistributedInputNodeManager::CreateVirtualTouchScreenNode(const std::string &devId, const std::string &dhId,
384 const uint64_t srcWinId, const uint32_t sourcePhyWidth, const uint32_t sourcePhyHeight)
385 {
386 std::unique_lock<std::mutex> my_lock(operationMutex_);
387 std::unique_ptr<VirtualDevice> device;
388 LocalAbsInfo info = DInputContext::GetInstance().GetLocalTouchScreenInfo().localAbsInfo;
389 DHLOGI("CreateVirtualTouchScreenNode, dhId: %{public}s, sourcePhyWidth: %{public}d, sourcePhyHeight: %{public}d",
390 GetAnonyString(dhId).c_str(), sourcePhyWidth, sourcePhyHeight);
391 device = std::make_unique<VirtualDevice>(info.deviceInfo);
392 if (!device->SetUp(info.deviceInfo, devId, dhId)) {
393 DHLOGE("Virtual touch Screen setUp fail, devId: %{public}s, dhId: %{public}s", GetAnonyString(devId).c_str(),
394 GetAnonyString(dhId).c_str());
395 return ERR_DH_INPUT_SERVER_SOURCE_CREATE_HANDLE_FAIL;
396 }
397 virtualTouchScreenFd_ = device->GetDeviceFd();
398 AddDeviceLocked(devId, dhId, std::move(device));
399 DHLOGI("CreateVirtualTouchScreenNode end, dhId: %{public}s", GetAnonyString(dhId).c_str());
400 return DH_SUCCESS;
401 }
402
RemoveVirtualTouchScreenNode(const std::string & devId,const std::string & dhId)403 int32_t DistributedInputNodeManager::RemoveVirtualTouchScreenNode(const std::string &devId, const std::string &dhId)
404 {
405 return CloseDeviceLocked(devId, dhId);
406 }
407
GetVirtualTouchScreenFd()408 int32_t DistributedInputNodeManager::GetVirtualTouchScreenFd()
409 {
410 return virtualTouchScreenFd_;
411 }
412
AddDeviceLocked(const std::string & networkId,const std::string & dhId,std::unique_ptr<VirtualDevice> device)413 void DistributedInputNodeManager::AddDeviceLocked(const std::string &networkId, const std::string &dhId,
414 std::unique_ptr<VirtualDevice> device)
415 {
416 DHLOGI("AddDeviceLocked deviceId=%{public}s, dhId=%{public}s",
417 GetAnonyString(networkId).c_str(), GetAnonyString(dhId).c_str());
418 std::lock_guard<std::mutex> lock(virtualDeviceMapMutex_);
419 auto [dev_it, inserted] = virtualDeviceMap_.insert_or_assign(
420 {networkId, dhId}, std::move(device));
421 if (!inserted) {
422 DHLOGI("Device exists, deviceId=%{public}s, dhId=%{public}s, replaced. \n",
423 GetAnonyString(networkId).c_str(), GetAnonyString(dhId).c_str());
424 }
425 }
426
CloseDeviceLocked(const std::string & devId,const std::string & dhId)427 int32_t DistributedInputNodeManager::CloseDeviceLocked(const std::string &devId, const std::string &dhId)
428 {
429 DHLOGI("CloseDeviceLocked called, deviceId=%{public}s, dhId=%{public}s",
430 GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str());
431 std::lock_guard<std::mutex> lock(virtualDeviceMapMutex_);
432 DhUniqueID dhUniqueId = {devId, dhId};
433 std::map<DhUniqueID, std::unique_ptr<VirtualDevice>>::iterator iter = virtualDeviceMap_.find(dhUniqueId);
434 if (iter != virtualDeviceMap_.end()) {
435 DHLOGI("CloseDeviceLocked called success, deviceId=%{public}s, dhId=%{public}s",
436 GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str());
437 virtualDeviceMap_.erase(iter);
438 return DH_SUCCESS;
439 }
440 DHLOGE("CloseDeviceLocked called failure, deviceId=%{public}s, dhId=%{public}s",
441 GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str());
442 return ERR_DH_INPUT_SERVER_SOURCE_CLOSE_DEVICE_FAIL;
443 }
444
GetDevice(const std::string & devId,const std::string & dhId,VirtualDevice * & device)445 int32_t DistributedInputNodeManager::GetDevice(const std::string &devId, const std::string &dhId,
446 VirtualDevice *&device)
447 {
448 std::lock_guard<std::mutex> lock(virtualDeviceMapMutex_);
449 auto iter = virtualDeviceMap_.find({devId, dhId});
450 if (iter != virtualDeviceMap_.end()) {
451 device = iter->second.get();
452 return DH_SUCCESS;
453 }
454 return ERR_DH_INPUT_SERVER_SOURCE_GET_DEVICE_FAIL;
455 }
456
StartInjectThread()457 void DistributedInputNodeManager::StartInjectThread()
458 {
459 if (isInjectThreadCreated_.load()) {
460 DHLOGI("InjectThread has been created.");
461 return;
462 }
463 DHLOGI("InjectThread does not created");
464 isInjectThreadCreated_.store(true);
465 isInjectThreadRunning_.store(true);
466 eventInjectThread_ = std::thread([this]() { this->InjectEvent(); });
467 }
468
StopInjectThread()469 void DistributedInputNodeManager::StopInjectThread()
470 {
471 if (!isInjectThreadCreated_.load()) {
472 DHLOGI("InjectThread does not created, and not need to stop.");
473 }
474 DHLOGI("InjectThread has been created, and soon will be stopped.");
475 isInjectThreadRunning_.store(false);
476 isInjectThreadCreated_.store(false);
477 conditionVariable_.notify_all();
478 if (eventInjectThread_.joinable()) {
479 eventInjectThread_.join();
480 }
481 }
482
ReportEvent(const std::string & devId,const std::vector<RawEvent> & events)483 void DistributedInputNodeManager::ReportEvent(const std::string &devId, const std::vector<RawEvent> &events)
484 {
485 std::lock_guard<std::mutex> lockGuard(injectThreadMutex_);
486 injectQueue_.push({devId, events});
487 conditionVariable_.notify_all();
488 }
489
InjectEvent()490 void DistributedInputNodeManager::InjectEvent()
491 {
492 int32_t ret = pthread_setname_np(pthread_self(), EVENT_INJECT_THREAD_NAME);
493 if (ret != 0) {
494 DHLOGE("InjectEvent setname failed.");
495 }
496 DHLOGD("start");
497 while (isInjectThreadRunning_.load()) {
498 EventBatch events;
499 {
500 std::unique_lock<std::mutex> waitEventLock(injectThreadMutex_);
501 conditionVariable_.wait(waitEventLock,
502 [this]() { return !isInjectThreadRunning_.load() || !injectQueue_.empty(); });
503 if (injectQueue_.empty()) {
504 continue;
505 }
506 events = injectQueue_.front();
507 injectQueue_.pop();
508 }
509
510 ProcessInjectEvent(events);
511 }
512 }
513
RegisterInjectEventCb(sptr<ISessionStateCallback> callback)514 void DistributedInputNodeManager::RegisterInjectEventCb(sptr<ISessionStateCallback> callback)
515 {
516 DHLOGI("RegisterInjectEventCb");
517 SessionStateCallback_ = callback;
518 }
519
UnregisterInjectEventCb()520 void DistributedInputNodeManager::UnregisterInjectEventCb()
521 {
522 DHLOGI("UnregisterInjectEventCb");
523 SessionStateCallback_ = nullptr;
524 }
525
RunInjectEventCallback(const std::string & dhId,const uint32_t injectEvent)526 void DistributedInputNodeManager::RunInjectEventCallback(const std::string &dhId, const uint32_t injectEvent)
527 {
528 DHLOGI("RunInjectEventCallback start.");
529 if (SessionStateCallback_ == nullptr) {
530 DHLOGE("RunSessionStateCallback SessionStateCallback_ is null.");
531 return;
532 }
533 SessionStateCallback_->OnResult(dhId, DINPUT_INJECT_EVENT_FAIL);
534 }
535
ProcessInjectEvent(const EventBatch & events)536 void DistributedInputNodeManager::ProcessInjectEvent(const EventBatch &events)
537 {
538 std::string deviceId = events.first;
539 for (const auto &rawEvent : events.second) {
540 std::string dhId = rawEvent.descriptor;
541 struct input_event event = {
542 .type = rawEvent.type,
543 .code = rawEvent.code,
544 .value = rawEvent.value
545 };
546 DHLOGI("InjectEvent deviceId: %{public}s, dhId: %{public}s, eventType: %{public}d, eventCode: %{public}d, "
547 "eventValue: %{public}d, when: %{public}" PRId64"", GetAnonyString(deviceId).c_str(),
548 GetAnonyString(dhId).c_str(), event.type, event.code, event.value, rawEvent.when);
549 VirtualDevice* device = nullptr;
550 if (GetDevice(deviceId, dhId, device) < 0) {
551 DHLOGE("could not find the device");
552 return;
553 }
554 if (device != nullptr) {
555 device->InjectInputEvent(event);
556 }
557 }
558 }
559 } // namespace DistributedInput
560 } // namespace DistributedHardware
561 } // namespace OHOS
562