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_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 &parameters)
51 {
52     DHLOGI("RegisterDistributedHardware called, deviceId: %{public}s,  dhId: %{public}s,  parameters: %{public}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     DHLOGI("RegisterDistributedHardware success");
65     return DH_SUCCESS;
66 }
67 
UnregisterDistributedHardware(const std::string & devId,const std::string & dhId)68 int32_t DistributedInputInject::UnregisterDistributedHardware(const std::string &devId, const std::string &dhId)
69 {
70     DHLOGI("UnregisterDistributedHardware called, deviceId: %{public}s,  dhId: %{public}s",
71         GetAnonyString(devId).c_str(), GetAnonyString(dhId).c_str());
72     std::lock_guard<std::mutex> lock(inputNodeManagerMutex_);
73     if (inputNodeManager_ == nullptr) {
74         DHLOGE("the DistributedInputNodeManager is null\n");
75         return ERR_DH_INPUT_SERVER_SOURCE_INJECT_NODE_MANAGER_IS_NULL;
76     }
77     if (inputNodeManager_->CloseDeviceLocked(devId, dhId) < 0) {
78         DHLOGE("delete virtual device error\n");
79         return ERR_DH_INPUT_SERVER_SOURCE_INJECT_UNREGISTER_FAIL;
80     }
81 
82     DHLOGI("UnregisterDistributedHardware success");
83     return DH_SUCCESS;
84 }
85 
StructTransJson(const InputDevice & pBuf,std::string & strDescriptor)86 int32_t DistributedInputInject::StructTransJson(const InputDevice &pBuf, std::string &strDescriptor)
87 {
88     DHLOGI("[%{public}s] %{public}d, %{public}d, %{public}d, %{public}d, %{public}s.\n", (pBuf.name).c_str(),
89         pBuf.bus, pBuf.vendor, pBuf.product, pBuf.version, GetAnonyString(pBuf.descriptor).c_str());
90     nlohmann::json tmpJson;
91     tmpJson[DEVICE_NAME] = pBuf.name;
92     tmpJson[PHYSICAL_PATH] = pBuf.physicalPath;
93     tmpJson[UNIQUE_ID] = pBuf.uniqueId;
94     tmpJson[BUS] = pBuf.bus;
95     tmpJson[VENDOR] = pBuf.vendor;
96     tmpJson[PRODUCT] = pBuf.product;
97     tmpJson[VERSION] = pBuf.version;
98     tmpJson[DESCRIPTOR] = pBuf.descriptor;
99     tmpJson[CLASSES] = pBuf.classes;
100     tmpJson[EVENT_TYPES] = pBuf.eventTypes;
101     tmpJson[EVENT_KEYS] = pBuf.eventKeys;
102     tmpJson[ABS_TYPES] = pBuf.absTypes;
103     tmpJson[ABS_INFOS] = pBuf.absInfos;
104     tmpJson[REL_TYPES] = pBuf.relTypes;
105     tmpJson[PROPERTIES] = pBuf.properties;
106 
107     std::ostringstream stream;
108     stream << tmpJson.dump();
109     strDescriptor = stream.str();
110     return DH_SUCCESS;
111 }
112 
RegisterDistributedEvent(const std::string & devId,const std::vector<RawEvent> & events)113 int32_t DistributedInputInject::RegisterDistributedEvent(const std::string &devId,
114     const std::vector<RawEvent> &events)
115 {
116     std::lock_guard<std::mutex> lock(inputNodeManagerMutex_);
117     if (inputNodeManager_ == nullptr) {
118         DHLOGE("the DistributedInputNodeManager is null");
119         return ERR_DH_INPUT_SERVER_SOURCE_INJECT_NODE_MANAGER_IS_NULL;
120     }
121 
122     inputNodeManager_->ReportEvent(devId, events);
123     return DH_SUCCESS;
124 }
125 
StartInjectThread()126 void DistributedInputInject::StartInjectThread()
127 {
128     std::lock_guard<std::mutex> lock(inputNodeManagerMutex_);
129     if (inputNodeManager_ != nullptr) {
130         inputNodeManager_->StartInjectThread();
131     }
132 }
133 
StopInjectThread()134 void DistributedInputInject::StopInjectThread()
135 {
136     std::lock_guard<std::mutex> lock(inputNodeManagerMutex_);
137     if (inputNodeManager_ != nullptr) {
138         inputNodeManager_->StopInjectThread();
139     }
140 }
141 
GenerateVirtualTouchScreenDHId(const uint64_t sourceWinId,const uint32_t sourceWinWidth,const uint32_t sourceWinHeight)142 std::string DistributedInputInject::GenerateVirtualTouchScreenDHId(const uint64_t sourceWinId,
143     const uint32_t sourceWinWidth, const uint32_t sourceWinHeight)
144 {
145     std::string uniqueInfo = GetLocalNetworkId() + std::to_string(sourceWinId) +
146         std::to_string(sourceWinWidth) + std::to_string(sourceWinHeight);
147     return DH_ID_PREFIX + Sha256(uniqueInfo);
148 }
149 
CreateVirtualTouchScreenNode(const std::string & devId,const std::string & dhId,const uint64_t srcWinId,const uint32_t sourcePhyWidth,const uint32_t sourcePhyHeight)150 int32_t DistributedInputInject::CreateVirtualTouchScreenNode(const std::string &devId, const std::string &dhId,
151     const uint64_t srcWinId, const uint32_t sourcePhyWidth, const uint32_t sourcePhyHeight)
152 {
153     std::lock_guard<std::mutex> lock(inputNodeManagerMutex_);
154     if (inputNodeManager_ == nullptr) {
155         DHLOGE("inputNodeManager is nullptr");
156         return ERR_DH_INPUT_SERVER_SOURCE_INJECT_NODE_MANAGER_IS_NULL;
157     }
158     return inputNodeManager_->CreateVirtualTouchScreenNode(devId, dhId, srcWinId, sourcePhyWidth, sourcePhyHeight);
159 }
160 
RemoveVirtualTouchScreenNode(const std::string & devId,const std::string & dhId)161 int32_t DistributedInputInject::RemoveVirtualTouchScreenNode(const std::string &devId, const std::string &dhId)
162 {
163     std::lock_guard<std::mutex> lock(inputNodeManagerMutex_);
164     if (inputNodeManager_ == nullptr) {
165         DHLOGE("inputNodeManager is nullptr");
166         return ERR_DH_INPUT_SERVER_SOURCE_INJECT_NODE_MANAGER_IS_NULL;
167     }
168     return inputNodeManager_->RemoveVirtualTouchScreenNode(devId, dhId);
169 }
170 
GetVirtualTouchScreenFd()171 int32_t DistributedInputInject::GetVirtualTouchScreenFd()
172 {
173     std::lock_guard<std::mutex> lock(inputNodeManagerMutex_);
174     if (inputNodeManager_ == nullptr) {
175         DHLOGE("inputNodeManager is nullptr");
176         return UN_INIT_FD_VALUE;
177     }
178     return inputNodeManager_->GetVirtualTouchScreenFd();
179 }
180 
RegisterInjectEventCb(sptr<ISessionStateCallback> callback)181 int32_t DistributedInputInject::RegisterInjectEventCb(sptr<ISessionStateCallback> callback)
182 {
183     if (callback == nullptr) {
184         DHLOGE("RegisterInjectEventCb callback is null.");
185         return ERR_DH_INPUT_SERVER_SOURCE_MANAGER_INJECT_EVENT_CB_IS_NULL;
186     }
187     inputNodeManager_->RegisterInjectEventCb(callback);
188     return DH_SUCCESS;
189 }
190 
UnregisterInjectEventCb()191 int32_t DistributedInputInject::UnregisterInjectEventCb()
192 {
193     inputNodeManager_->UnregisterInjectEventCb();
194     return DH_SUCCESS;
195 }
196 
GetVirtualKeyboardPaths(const std::string & devId,const std::vector<std::string> & dhIds,std::vector<std::string> & virKeyboardPaths)197 void DistributedInputInject::GetVirtualKeyboardPaths(const std::string &devId,
198     const std::vector<std::string> &dhIds, std::vector<std::string> &virKeyboardPaths)
199 {
200     std::lock_guard<std::mutex> lock(inputNodeManagerMutex_);
201     if (inputNodeManager_ == nullptr) {
202         DHLOGE("inputNodeManager is nullptr");
203         return;
204     }
205     std::vector<DhUniqueID> dhUniqIds;
206     std::for_each(dhIds.begin(), dhIds.end(),
207         [&devId, &dhUniqIds](std::string dhId) {
208             DhUniqueID id = {devId, dhId};
209             dhUniqIds.push_back(id);
210         });
211     inputNodeManager_->GetVirtualKeyboardPaths(dhUniqIds, virKeyboardPaths);
212 }
213 
NotifyNodeMgrScanVirNode(const std::string & devId,const std::string & dhId)214 void DistributedInputInject::NotifyNodeMgrScanVirNode(const std::string &devId, const std::string &dhId)
215 {
216     std::lock_guard<std::mutex> lock(inputNodeManagerMutex_);
217     if (inputNodeManager_ == nullptr) {
218         DHLOGE("inputNodeManager is nullptr");
219         return;
220     }
221     inputNodeManager_->NotifyNodeMgrScanVirNode(devId, dhId);
222 }
223 } // namespace DistributedInput
224 } // namespace DistributedHardware
225 } // namespace OHOS