1 /*
2 * Copyright (c) 2021-2023 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_inject.h"
17
18 #include <sstream>
19
20 #include "nlohmann/json.hpp"
21
22 #include "dinput_errcode.h"
23 #include "dinput_log.h"
24 #include "dinput_utils_tool.h"
25
26 namespace OHOS {
27 namespace DistributedHardware {
28 namespace DistributedInput {
DistributedInputInject()29 DistributedInputInject::DistributedInputInject()
30 {
31 std::lock_guard<std::mutex> lock(inputNodeManagerMutex_);
32 inputNodeManager_ = std::make_unique<DistributedInputNodeManager>();
33 }
34
~DistributedInputInject()35 DistributedInputInject::~DistributedInputInject()
36 {
37 DHLOGI("~DistributedInputInject");
38 std::lock_guard<std::mutex> lock(inputNodeManagerMutex_);
39 inputNodeManager_.reset();
40 inputNodeManager_ = nullptr;
41 }
42
GetInstance()43 DistributedInputInject &DistributedInputInject::GetInstance()
44 {
45 static DistributedInputInject instance;
46 return instance;
47 }
48
RegisterDistributedHardware(const std::string & devId,const std::string & dhId,const std::string & parameters)49 int32_t DistributedInputInject::RegisterDistributedHardware(const std::string &devId, const std::string &dhId,
50 const std::string ¶meters)
51 {
52 DHLOGI("RegisterDistributedHardware called, deviceId: %s, dhId: %s, parameters: %s",
53 GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str(), SetAnonyId(parameters).c_str());
54 std::lock_guard<std::mutex> lock(inputNodeManagerMutex_);
55 if (inputNodeManager_ == nullptr) {
56 DHLOGE("the DistributedInputNodeManager is null\n");
57 return ERR_DH_INPUT_SERVER_SOURCE_INJECT_NODE_MANAGER_IS_NULL;
58 }
59 if (inputNodeManager_->OpenDevicesNode(devId, dhId, parameters) < 0) {
60 DHLOGE("create virtual device error\n");
61 return ERR_DH_INPUT_SERVER_SOURCE_INJECT_REGISTER_FAIL;
62 }
63
64 std::string srcDevId;
65 inputNodeManager_->GetDeviceInfo(srcDevId);
66 DHLOGI("RegisterDistributedHardware called, device type = source, source networkId = %s, sink networkId = %s",
67 GetAnonyString(srcDevId).c_str(), GetAnonyString(devId).c_str());
68
69 SyncNodeOnlineInfo(srcDevId, devId, dhId, GetNodeDesc(parameters));
70 return DH_SUCCESS;
71 }
72
UnregisterDistributedHardware(const std::string & devId,const std::string & dhId)73 int32_t DistributedInputInject::UnregisterDistributedHardware(const std::string &devId, const std::string &dhId)
74 {
75 DHLOGI("UnregisterDistributedHardware called, deviceId: %s, dhId: %s",
76 GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str());
77 std::lock_guard<std::mutex> lock(inputNodeManagerMutex_);
78 if (inputNodeManager_ == nullptr) {
79 DHLOGE("the DistributedInputNodeManager is null\n");
80 return ERR_DH_INPUT_SERVER_SOURCE_INJECT_NODE_MANAGER_IS_NULL;
81 }
82 if (inputNodeManager_->CloseDeviceLocked(dhId) < 0) {
83 DHLOGE("delete virtual device error\n");
84 return ERR_DH_INPUT_SERVER_SOURCE_INJECT_UNREGISTER_FAIL;
85 }
86
87 std::string srcDevId;
88 inputNodeManager_->GetDeviceInfo(srcDevId);
89
90 DHLOGI("UnregisterDistributedHardware called, device = %s, dhId = %s, OnNodeOffLine",
91 GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str());
92 SyncNodeOfflineInfo(srcDevId, devId, dhId);
93
94 return DH_SUCCESS;
95 }
96
RegisterInputNodeListener(sptr<InputNodeListener> listener)97 int32_t DistributedInputInject::RegisterInputNodeListener(sptr<InputNodeListener> listener)
98 {
99 std::lock_guard<std::mutex> lock(inputNodeListenersMutex_);
100 this->inputNodeListeners_.insert(listener);
101 return DH_SUCCESS;
102 }
103
UnregisterInputNodeListener(sptr<InputNodeListener> listener)104 int32_t DistributedInputInject::UnregisterInputNodeListener(sptr<InputNodeListener> listener)
105 {
106 std::lock_guard<std::mutex> lock(inputNodeListenersMutex_);
107 this->inputNodeListeners_.erase(listener);
108 return DH_SUCCESS;
109 }
110
GetDhIdsByInputType(const std::string & devId,const uint32_t & inputTypes,std::vector<std::string> & dhIds)111 int32_t DistributedInputInject::GetDhIdsByInputType(const std::string &devId, const uint32_t &inputTypes,
112 std::vector<std::string> &dhIds)
113 {
114 std::lock_guard<std::mutex> lock(inputNodeManagerMutex_);
115 if (inputNodeManager_ == nullptr) {
116 DHLOGE("the inputNodeListener is nullptr");
117 return ERR_DH_INPUT_SERVER_SOURCE_INJECT_NODE_MANAGER_IS_NULL;
118 }
119 std::map<int32_t, std::string> datas;
120 inputNodeManager_->GetDevicesInfoByType(devId, inputTypes, datas);
121 for (const auto &data_ : datas) {
122 dhIds.push_back(data_.second);
123 }
124 return DH_SUCCESS;
125 }
126
StructTransJson(const InputDevice & pBuf,std::string & strDescriptor)127 int32_t DistributedInputInject::StructTransJson(const InputDevice &pBuf, std::string &strDescriptor)
128 {
129 DHLOGI("[%s] %d, %d, %d, %d, %s.\n", (pBuf.name).c_str(), pBuf.bus, pBuf.vendor, pBuf.product, pBuf.version,
130 GetAnonyString(pBuf.descriptor).c_str());
131 nlohmann::json tmpJson;
132 tmpJson[DEVICE_NAME] = pBuf.name;
133 tmpJson[PHYSICAL_PATH] = pBuf.physicalPath;
134 tmpJson[UNIQUE_ID] = pBuf.uniqueId;
135 tmpJson[BUS] = pBuf.bus;
136 tmpJson[VENDOR] = pBuf.vendor;
137 tmpJson[PRODUCT] = pBuf.product;
138 tmpJson[VERSION] = pBuf.version;
139 tmpJson[DESCRIPTOR] = pBuf.descriptor;
140 tmpJson[CLASSES] = pBuf.classes;
141 tmpJson[EVENT_TYPES] = pBuf.eventTypes;
142 tmpJson[EVENT_KEYS] = pBuf.eventKeys;
143 tmpJson[ABS_TYPES] = pBuf.absTypes;
144 tmpJson[ABS_INFOS] = pBuf.absInfos;
145 tmpJson[REL_TYPES] = pBuf.relTypes;
146 tmpJson[PROPERTIES] = pBuf.properties;
147
148 std::ostringstream stream;
149 stream << tmpJson.dump();
150 strDescriptor = stream.str();
151 return DH_SUCCESS;
152 }
153
InputDeviceEventInject(const std::shared_ptr<RawEvent> & rawEvent)154 void DistributedInputInject::InputDeviceEventInject(const std::shared_ptr<RawEvent> &rawEvent)
155 {
156 std::lock_guard<std::mutex> lock(inputNodeManagerMutex_);
157 if (inputNodeManager_ == nullptr) {
158 DHLOGE("the inputNodeListener is nullptr");
159 return;
160 }
161 if (rawEvent == nullptr) {
162 DHLOGE("the rawEvent is nullptr");
163 return;
164 }
165 inputNodeManager_->ProcessInjectEvent(rawEvent);
166 }
167
SyncNodeOnlineInfo(const std::string & srcDevId,const std::string & sinkDevId,const std::string & sinkNodeId,const std::string & sinkNodeDesc)168 void DistributedInputInject::SyncNodeOnlineInfo(const std::string &srcDevId,
169 const std::string &sinkDevId, const std::string &sinkNodeId, const std::string &sinkNodeDesc)
170 {
171 std::lock_guard<std::mutex> lock(inputNodeListenersMutex_);
172 DHLOGI("SyncVirNodeOnlineInfo, srcId: %s, sinkId: %s, dhId: %s", GetAnonyString(srcDevId).c_str(),
173 GetAnonyString(sinkDevId).c_str(), GetAnonyString(sinkNodeId).c_str());
174 for (const auto &listener : inputNodeListeners_) {
175 listener->OnNodeOnLine(srcDevId, sinkDevId, sinkNodeId, sinkNodeDesc);
176 }
177 }
178
SyncNodeOfflineInfo(const std::string & srcDevId,const std::string & sinkDevId,const std::string & sinkNodeId)179 void DistributedInputInject::SyncNodeOfflineInfo(const std::string &srcDevId,
180 const std::string &sinkDevId, const std::string &sinkNodeId)
181 {
182 std::lock_guard<std::mutex> lock(inputNodeListenersMutex_);
183 DHLOGI("SyncVirNodeOfflineInfo, srcId: %s, sinkId: %s, dhId: %s", GetAnonyString(srcDevId).c_str(),
184 GetAnonyString(sinkDevId).c_str(), GetAnonyString(sinkNodeId).c_str());
185 for (const auto &listener : inputNodeListeners_) {
186 listener->OnNodeOffLine(srcDevId, sinkDevId, sinkNodeId);
187 }
188 }
189
RegisterDistributedEvent(RawEvent * buffer,size_t bufferSize)190 int32_t DistributedInputInject::RegisterDistributedEvent(RawEvent *buffer, size_t bufferSize)
191 {
192 std::lock_guard<std::mutex> lock(inputNodeManagerMutex_);
193 if (inputNodeManager_ == nullptr) {
194 DHLOGE("the DistributedInputNodeManager is null");
195 return ERR_DH_INPUT_SERVER_SOURCE_INJECT_NODE_MANAGER_IS_NULL;
196 }
197 DHLOGI("RegisterDistributedEvent start %zu\n", bufferSize);
198 for (size_t i = 0; i < bufferSize; i++) {
199 inputNodeManager_->ReportEvent(buffer[i]);
200 }
201 return DH_SUCCESS;
202 }
203
StartInjectThread()204 void DistributedInputInject::StartInjectThread()
205 {
206 std::lock_guard<std::mutex> lock(inputNodeManagerMutex_);
207 if (inputNodeManager_ != nullptr) {
208 inputNodeManager_->StartInjectThread();
209 }
210 }
211
StopInjectThread()212 void DistributedInputInject::StopInjectThread()
213 {
214 std::lock_guard<std::mutex> lock(inputNodeManagerMutex_);
215 if (inputNodeManager_ != nullptr) {
216 inputNodeManager_->StopInjectThread();
217 }
218 }
219
GenerateVirtualTouchScreenDHId(const uint64_t sourceWinId,const uint32_t sourceWinWidth,const uint32_t sourceWinHeight)220 std::string DistributedInputInject::GenerateVirtualTouchScreenDHId(const uint64_t sourceWinId,
221 const uint32_t sourceWinWidth, const uint32_t sourceWinHeight)
222 {
223 std::string uniqueInfo = GetLocalNetworkId() + std::to_string(sourceWinId) +
224 std::to_string(sourceWinWidth) + std::to_string(sourceWinHeight);
225 return DH_ID_PREFIX + Sha256(uniqueInfo);
226 }
227
CreateVirtualTouchScreenNode(const std::string & devId,const std::string & dhId,const uint64_t srcWinId,const uint32_t sourcePhyWidth,const uint32_t sourcePhyHeight)228 int32_t DistributedInputInject::CreateVirtualTouchScreenNode(const std::string &devId, const std::string &dhId,
229 const uint64_t srcWinId, const uint32_t sourcePhyWidth, const uint32_t sourcePhyHeight)
230 {
231 std::lock_guard<std::mutex> lock(inputNodeManagerMutex_);
232 if (inputNodeManager_ == nullptr) {
233 DHLOGE("inputNodeManager is nullptr");
234 return ERR_DH_INPUT_SERVER_SOURCE_INJECT_NODE_MANAGER_IS_NULL;
235 }
236 return inputNodeManager_->CreateVirtualTouchScreenNode(devId, dhId, srcWinId, sourcePhyWidth, sourcePhyHeight);
237 }
238
RemoveVirtualTouchScreenNode(const std::string & dhId)239 int32_t DistributedInputInject::RemoveVirtualTouchScreenNode(const std::string &dhId)
240 {
241 std::lock_guard<std::mutex> lock(inputNodeManagerMutex_);
242 if (inputNodeManager_ == nullptr) {
243 DHLOGE("inputNodeManager is nullptr");
244 return ERR_DH_INPUT_SERVER_SOURCE_INJECT_NODE_MANAGER_IS_NULL;
245 }
246 return inputNodeManager_->RemoveVirtualTouchScreenNode(dhId);
247 }
248
GetVirtualTouchScreenFd()249 int32_t DistributedInputInject::GetVirtualTouchScreenFd()
250 {
251 std::lock_guard<std::mutex> lock(inputNodeManagerMutex_);
252 if (inputNodeManager_ == nullptr) {
253 DHLOGE("inputNodeManager is nullptr");
254 return UN_INIT_FD_VALUE;
255 }
256 return inputNodeManager_->GetVirtualTouchScreenFd();
257 }
258
GetVirtualKeyboardPathsByDhIds(const std::vector<std::string> & dhIds,std::vector<std::string> & shareDhidsPaths,std::vector<std::string> & shareDhIds)259 void DistributedInputInject::GetVirtualKeyboardPathsByDhIds(const std::vector<std::string> &dhIds,
260 std::vector<std::string> &shareDhidsPaths, std::vector<std::string> &shareDhIds)
261 {
262 std::lock_guard<std::mutex> lock(inputNodeManagerMutex_);
263 if (inputNodeManager_ == nullptr) {
264 DHLOGE("inputNodeManager is nullptr");
265 return;
266 }
267 inputNodeManager_->GetVirtualKeyboardPathsByDhIds(dhIds, shareDhidsPaths, shareDhIds);
268 }
269
NotifyNodeMgrScanVirNode(const std::string & dhId)270 void DistributedInputInject::NotifyNodeMgrScanVirNode(const std::string &dhId)
271 {
272 std::lock_guard<std::mutex> lock(inputNodeManagerMutex_);
273 if (inputNodeManager_ == nullptr) {
274 DHLOGE("inputNodeManager is nullptr");
275 return;
276 }
277 inputNodeManager_->NotifyNodeMgrScanVirNode(dhId);
278 }
279 } // namespace DistributedInput
280 } // namespace DistributedHardware
281 } // namespace OHOS