• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_handler.h"
17 
18 #include <cstring>
19 #include <dirent.h>
20 #include <fcntl.h>
21 #include <pthread.h>
22 #include <sstream>
23 #include <sys/stat.h>
24 #include <unistd.h>
25 
26 #include <openssl/sha.h>
27 #include <sys/inotify.h>
28 #include <linux/input.h>
29 #include <linux/uinput.h>
30 
31 #include "nlohmann/json.hpp"
32 
33 #include "constants_dinput.h"
34 #include "dinput_errcode.h"
35 #include "dinput_log.h"
36 #include "dinput_softbus_define.h"
37 #include "dinput_utils_tool.h"
38 #include "softbus_bus_center.h"
39 
40 namespace OHOS {
41 namespace DistributedHardware {
42 namespace DistributedInput {
43 IMPLEMENT_SINGLE_INSTANCE(DistributedInputHandler);
DistributedInputHandler()44 DistributedInputHandler::DistributedInputHandler()
45     : collectThreadID_(-1), isCollectingEvents_(false), isStartCollectEventThread(false)
46 {
47     inputHub_ = std::make_unique<InputHub>();
48     this->m_listener = nullptr;
49 }
50 
~DistributedInputHandler()51 DistributedInputHandler::~DistributedInputHandler()
52 {
53     StopInputMonitorDeviceThread();
54 }
55 
StructTransJson(const InputDevice & pBuf,std::string & strDescriptor)56 void DistributedInputHandler::StructTransJson(const InputDevice &pBuf, std::string &strDescriptor)
57 {
58     DHLOGI("[%s] %d, %d, %d, %d, %s.\n", (pBuf.name).c_str(), pBuf.bus, pBuf.vendor, pBuf.product, pBuf.version,
59         GetAnonyString(pBuf.descriptor).c_str());
60     nlohmann::json tmpJson;
61     tmpJson[DEVICE_NAME] = pBuf.name;
62     tmpJson[PHYSICAL_PATH] = pBuf.physicalPath;
63     tmpJson[UNIQUE_ID] = pBuf.uniqueId;
64     tmpJson[BUS] = pBuf.bus;
65     tmpJson[VENDOR] = pBuf.vendor;
66     tmpJson[PRODUCT] = pBuf.product;
67     tmpJson[VERSION] = pBuf.version;
68     tmpJson[DESCRIPTOR] = pBuf.descriptor;
69     tmpJson[CLASSES] = pBuf.classes;
70     tmpJson[EVENT_TYPES] = pBuf.eventTypes;
71     tmpJson[EVENT_KEYS] = pBuf.eventKeys;
72     tmpJson[ABS_TYPES] = pBuf.absTypes;
73     tmpJson[ABS_INFOS] = pBuf.absInfos;
74     tmpJson[REL_TYPES] = pBuf.relTypes;
75     tmpJson[PROPERTIES] = pBuf.properties;
76 
77     std::ostringstream stream;
78     stream << tmpJson.dump();
79     strDescriptor = stream.str();
80     return;
81 }
82 
Initialize()83 int32_t DistributedInputHandler::Initialize()
84 {
85     if (!isStartCollectEventThread) {
86         InitCollectEventsThread();
87         isStartCollectEventThread = true;
88     }
89     return DH_SUCCESS;
90 }
91 
FindDevicesInfoByType(const uint32_t inputTypes,std::map<int32_t,std::string> & datas)92 void DistributedInputHandler::FindDevicesInfoByType(const uint32_t inputTypes, std::map<int32_t, std::string> &datas)
93 {
94     if (inputHub_ != nullptr) {
95         inputHub_->GetDevicesInfoByType(inputTypes, datas);
96     }
97 }
98 
FindDevicesInfoByDhId(std::vector<std::string> dhidsVec,std::map<int32_t,std::string> & datas)99 void DistributedInputHandler::FindDevicesInfoByDhId(
100     std::vector<std::string> dhidsVec, std::map<int32_t, std::string> &datas)
101 {
102     if (inputHub_ != nullptr) {
103         inputHub_->GetDevicesInfoByDhId(dhidsVec, datas);
104     }
105 }
106 
Query()107 std::vector<DHItem> DistributedInputHandler::Query()
108 {
109     std::vector<DHItem> retInfos;
110 
111     if (inputHub_ != nullptr) {
112         std::vector<InputDevice> vecInput = inputHub_->GetAllInputDevices();
113         for (auto iter : vecInput) {
114             DHItem item;
115             item.dhId = iter.descriptor;
116             StructTransJson(iter, item.attrs);
117             retInfos.push_back(item);
118         }
119     }
120 
121     return retInfos;
122 }
123 
QueryExtraInfo()124 std::map<std::string, std::string> DistributedInputHandler::QueryExtraInfo()
125 {
126     std::map<std::string, std::string> ret;
127     return ret;
128 }
129 
IsSupportPlugin()130 bool DistributedInputHandler::IsSupportPlugin()
131 {
132     return true;
133 }
134 
RegisterPluginListener(std::shared_ptr<PluginListener> listener)135 void DistributedInputHandler::RegisterPluginListener(std::shared_ptr<PluginListener> listener)
136 {
137     this->m_listener = listener;
138 }
139 
UnRegisterPluginListener()140 void DistributedInputHandler::UnRegisterPluginListener()
141 {
142     this->m_listener = nullptr;
143 }
144 
GetDeviceInfo(std::string & deviceId)145 int32_t DistributedInputHandler::GetDeviceInfo(std::string &deviceId)
146 {
147     std::unique_lock<std::mutex> my_lock(operationMutex_);
148     auto localNode = std::make_unique<NodeBasicInfo>();
149     int32_t retCode = GetLocalNodeDeviceInfo("ohos.dhardware", localNode.get());
150     if (retCode != 0) {
151         DHLOGE("Could not get device id.");
152         return ERR_DH_INPUT_HANDLER_GET_DEVICE_ID_FAIL;
153     }
154 
155     deviceId = localNode->networkId;
156     DHLOGI("device id is %s", GetAnonyString(deviceId).c_str());
157     return DH_SUCCESS;
158 }
159 
InitCollectEventsThread()160 bool DistributedInputHandler::InitCollectEventsThread()
161 {
162     pthread_attr_t attr;
163     pthread_attr_init(&attr);
164     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
165 
166     isCollectingEvents_ = true;
167     collectThreadID_ = -1;
168     int32_t ret = pthread_create(&collectThreadID_, &attr, CollectEventsThread, this);
169     if (ret != 0) {
170         DHLOGE("DistributedInputHandler::InitCollectEventsThread create thread failed:%d \n", ret);
171         pthread_attr_destroy(&attr);
172         collectThreadID_ = -1;
173         isCollectingEvents_ = false;
174         return false;
175     }
176     return true;
177 }
178 
CollectEventsThread(void * param)179 void *DistributedInputHandler::CollectEventsThread(void *param)
180 {
181     int32_t ret = pthread_setname_np(pthread_self(), COLLECT_EVENT_THREAD_NAME);
182     if (ret != 0) {
183         DHLOGE("CollectEventsThread setname failed.");
184     }
185     DistributedInputHandler *pThis = reinterpret_cast<DistributedInputHandler *>(param);
186 
187     std::string deviceId;
188     pThis->GetDeviceInfo(deviceId);
189     pThis->StartInputMonitorDeviceThread(deviceId);
190     DHLOGI("DistributedInputHandler::CollectEventsThread exist!");
191     return nullptr;
192 }
193 
StartInputMonitorDeviceThread(const std::string deviceId)194 void DistributedInputHandler::StartInputMonitorDeviceThread(const std::string deviceId)
195 {
196     if (inputHub_ == nullptr) {
197         DHLOGE("inputHub_ not initialized");
198         return;
199     }
200     while (isCollectingEvents_) {
201         size_t count = inputHub_->StartCollectInputHandler(mEventBuffer, inputDeviceBufferSize);
202         if (count > 0) {
203             DHLOGI("Count: %zu", count);
204             for (size_t iCnt = 0; iCnt < count; iCnt++) {
205                 NotifyHardWare(iCnt);
206             }
207         } else {
208             continue;
209         }
210     }
211     isCollectingEvents_ = false;
212     DHLOGI("DistributedInputHandler::StartCollectEventsThread exit!");
213 }
214 
NotifyHardWare(int iCnt)215 void DistributedInputHandler::NotifyHardWare(int iCnt)
216 {
217     switch (mEventBuffer[iCnt].type) {
218         case DeviceType::DEVICE_ADDED:
219             if (this->m_listener != nullptr) {
220                 std::string hdInfo;
221                 StructTransJson(mEventBuffer[iCnt].deviceInfo, hdInfo);
222                 this->m_listener->PluginHardware(mEventBuffer[iCnt].deviceInfo.descriptor, hdInfo);
223             }
224             break;
225         case DeviceType::DEVICE_REMOVED:
226             if (this->m_listener != nullptr) {
227                 this->m_listener->UnPluginHardware(mEventBuffer[iCnt].deviceInfo.descriptor);
228             }
229             break;
230         default:
231             break;
232     }
233 }
234 
StopInputMonitorDeviceThread()235 void DistributedInputHandler::StopInputMonitorDeviceThread()
236 {
237     isCollectingEvents_ = false;
238     isStartCollectEventThread = false;
239     inputHub_->StopCollectInputHandler();
240     if (collectThreadID_ != (pthread_t)(-1)) {
241         DHLOGI("DistributedInputHandler::Wait collect thread exit");
242         pthread_join(collectThreadID_, NULL);
243         collectThreadID_ = (pthread_t)(-1);
244     }
245     DHLOGI("DistributedInputHandler::StopInputMonitorDeviceThread exit!");
246 }
247 
GetHardwareHandler()248 IHardwareHandler* GetHardwareHandler()
249 {
250     return &DistributedInputHandler::GetInstance();
251 }
252 } // namespace DistributedInput
253 } // namespace DistributedHardware
254 } // namespace OHOS
255