• 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_collector.h"
17 
18 #include <cstring>
19 #include <dirent.h>
20 #include <fcntl.h>
21 #include <pthread.h>
22 #include <sys/stat.h>
23 #include <securec.h>
24 #include <unistd.h>
25 
26 #include <openssl/sha.h>
27 #include <sys/inotify.h>
28 #include <linux/input.h>
29 
30 #include "nlohmann/json.hpp"
31 
32 #include "dinput_errcode.h"
33 #include "dinput_log.h"
34 #include "dinput_utils_tool.h"
35 
36 namespace OHOS {
37 namespace DistributedHardware {
38 namespace DistributedInput {
DistributedInputCollector()39 DistributedInputCollector::DistributedInputCollector() : mEventBuffer{}, collectThreadID_(-1),
40     isCollectingEvents_(false), isStartGetDeviceHandlerThread(false), inputTypes_(0)
41 {
42     inputHub_ = std::make_unique<InputHub>(false);
43 }
44 
~DistributedInputCollector()45 DistributedInputCollector::~DistributedInputCollector()
46 {
47     StopCollectEventsThread();
48 }
49 
GetInstance()50 DistributedInputCollector &DistributedInputCollector::GetInstance()
51 {
52     static DistributedInputCollector instance;
53     return instance;
54 }
55 
PreInit()56 void DistributedInputCollector::PreInit()
57 {
58     DHLOGI("PreInit for record local device infos");
59     inputHub_->RecordDeviceStates();
60 }
61 
StartCollectionThread(std::shared_ptr<AppExecFwk::EventHandler> sinkHandler)62 int32_t DistributedInputCollector::StartCollectionThread(std::shared_ptr<AppExecFwk::EventHandler> sinkHandler)
63 {
64     sinkHandler_ = sinkHandler;
65     if (sinkHandler_ == nullptr || inputHub_ == nullptr) {
66         DHLOGE("DistributedInputCollector::Init sinkHandler_ or inputHub_ invalid \n");
67         return ERR_DH_INPUT_SERVER_SINK_COLLECTOR_INIT_FAIL;
68     }
69 
70     DHLOGI("Try start collect thread");
71     if (!isStartGetDeviceHandlerThread) {
72         InitCollectEventsThread();
73         isStartGetDeviceHandlerThread = true;
74     }
75     return DH_SUCCESS;
76 }
77 
InitCollectEventsThread()78 bool DistributedInputCollector::InitCollectEventsThread()
79 {
80     pthread_attr_t attr;
81     pthread_attr_init(&attr);
82     pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
83 
84     isCollectingEvents_ = true;
85     collectThreadID_ = -1;
86     int32_t ret = pthread_create(&collectThreadID_, &attr, CollectEventsThread, this);
87     if (ret != 0) {
88         DHLOGE("DistributedInputCollector::InitCollectEventsThread create  thread failed:%d \n", ret);
89         pthread_attr_destroy(&attr);
90         collectThreadID_ = -1;
91         isCollectingEvents_ = false;
92         return false;
93     }
94     return true;
95 }
96 
CollectEventsThread(void * param)97 void *DistributedInputCollector::CollectEventsThread(void *param)
98 {
99     int32_t ret = pthread_setname_np(pthread_self(), COLLECT_EVENT_THREAD_NAME);
100     if (ret != 0) {
101         DHLOGE("CollectEventsThread setname failed.");
102     }
103     DistributedInputCollector *pThis = reinterpret_cast<DistributedInputCollector *>(param);
104     pThis->StartCollectEventsThread();
105     DHLOGW("DistributedInputCollector::CollectEventsThread exist!");
106     return nullptr;
107 }
108 
StartCollectEventsThread()109 void DistributedInputCollector::StartCollectEventsThread()
110 {
111     DHLOGI("StartCollectEventsThread!");
112     while (isCollectingEvents_) {
113         memset_s(&mEventBuffer, sizeof(mEventBuffer), 0, sizeof(mEventBuffer));
114         if (inputHub_ == nullptr) {
115             DHLOGI("inputHub is nullptr!");
116             return;
117         }
118         size_t count = inputHub_->StartCollectInputEvents(mEventBuffer, INPUT_EVENT_BUFFER_SIZE);
119         if (count == 0) {
120             continue;
121         }
122 
123         // The RawEvent obtained by the controlled end calls transport and is
124         // sent to the main control end.
125         std::shared_ptr<nlohmann::json> jsonArrayMsg = std::make_shared<nlohmann::json>();
126         for (size_t ind = 0; ind < count; ind++) {
127             nlohmann::json tmpJson;
128             tmpJson[INPUT_KEY_WHEN] = mEventBuffer[ind].when;
129             tmpJson[INPUT_KEY_TYPE] = mEventBuffer[ind].type;
130             tmpJson[INPUT_KEY_CODE] = mEventBuffer[ind].code;
131             tmpJson[INPUT_KEY_VALUE] = mEventBuffer[ind].value;
132             tmpJson[INPUT_KEY_PATH] = mEventBuffer[ind].path;
133             tmpJson[INPUT_KEY_DESCRIPTOR] = mEventBuffer[ind].descriptor;
134             jsonArrayMsg->push_back(tmpJson);
135         }
136 
137         AppExecFwk::InnerEvent::Pointer msgEvent = AppExecFwk::InnerEvent::Get(
138             static_cast<uint32_t>(EHandlerMsgType::DINPUT_SINK_EVENT_HANDLER_MSG), jsonArrayMsg, 0);
139         if (sinkHandler_ != nullptr) {
140             sinkHandler_->SendEvent(msgEvent, 0, AppExecFwk::EventQueue::Priority::IMMEDIATE);
141         }
142     }
143     DHLOGW("DistributedInputCollector::StartCollectEventsThread exit!");
144 }
145 
StopCollectEventsThread()146 void DistributedInputCollector::StopCollectEventsThread()
147 {
148     isCollectingEvents_ = false;
149     isStartGetDeviceHandlerThread = false;
150     if (inputHub_ == nullptr) {
151         DHLOGI("inputHub is nullptr!");
152         return;
153     }
154     inputHub_->StopCollectInputEvents();
155     if (collectThreadID_ != (pthread_t)(-1)) {
156         DHLOGI("DistributedInputCollector::Wait collect thread exit");
157         pthread_join(collectThreadID_, NULL);
158         collectThreadID_ = (pthread_t)(-1);
159     }
160     inputHub_->ClearDeviceStates();
161     DHLOGW("DistributedInputCollector::StopCollectEventsThread exit!");
162 }
163 
SetSharingTypes(bool enabled,const uint32_t & inputType)164 AffectDhIds DistributedInputCollector::SetSharingTypes(bool enabled, const uint32_t &inputType)
165 {
166     inputTypes_ = 0;
167     if ((inputType & static_cast<uint32_t>(DInputDeviceType::MOUSE)) != 0 ||
168         (inputType & static_cast<uint32_t>(DInputDeviceType::TOUCHPAD)) != 0) {
169         inputTypes_ |= INPUT_DEVICE_CLASS_CURSOR;
170     }
171     if ((inputType & static_cast<uint32_t>(DInputDeviceType::KEYBOARD)) != 0) {
172         inputTypes_ |= INPUT_DEVICE_CLASS_KEYBOARD;
173     }
174     if ((inputType & static_cast<uint32_t>(DInputDeviceType::TOUCHSCREEN)) != 0) {
175         inputTypes_ |= INPUT_DEVICE_CLASS_TOUCH_MT | INPUT_DEVICE_CLASS_TOUCH;
176     }
177 
178     return inputHub_->SetSupportInputType(enabled, inputTypes_);
179 }
180 
ReportDhIdSharingState(const AffectDhIds & dhIds)181 void DistributedInputCollector::ReportDhIdSharingState(const AffectDhIds &dhIds)
182 {
183     std::lock_guard<std::mutex> lock(sharingDhIdListenerMtx_);
184     if (sharingDhIdListeners_.size() == 0) {
185         DHLOGE("sharingDhIdListeners is null, can not report sharing dhid");
186         return;
187     }
188 
189     for (auto const &id : dhIds.sharingDhIds) {
190         DHLOGI("Sharing DhId: %s", GetAnonyString(id).c_str());
191         for (auto iter : sharingDhIdListeners_) {
192             iter->OnSharing(id);
193         }
194     }
195 
196     for (auto const &id : dhIds.noSharingDhIds) {
197         DHLOGI("No Sharing DhId: %s", GetAnonyString(id).c_str());
198         for (auto iter : sharingDhIdListeners_) {
199             iter->OnNoSharing(id);
200         }
201     }
202 }
203 
StopCollectionThread()204 void DistributedInputCollector::StopCollectionThread()
205 {
206     StopCollectEventsThread();
207 }
208 
SetSharingDhIds(bool enabled,std::vector<std::string> dhIds)209 AffectDhIds DistributedInputCollector::SetSharingDhIds(bool enabled, std::vector<std::string> dhIds)
210 {
211     return inputHub_->SetSharingDevices(enabled, dhIds);
212 }
213 
GetSharingDhIds()214 std::vector<std::string> DistributedInputCollector::GetSharingDhIds()
215 {
216     return inputHub_->GetSharingDevices();
217 }
218 
GetMouseNodePath(const std::vector<std::string> & dhIds,std::string & mouseNodePath,std::string & dhId)219 void DistributedInputCollector::GetMouseNodePath(const std::vector<std::string> &dhIds,
220     std::string &mouseNodePath, std::string &dhId)
221 {
222     if (inputHub_ == nullptr) {
223         DHLOGE("inputHub is nullptr!");
224         return;
225     }
226     inputHub_->GetSharedMousePathByDhId(dhIds, mouseNodePath, dhId);
227 }
228 
GetSharedKeyboardPathsByDhIds(const std::vector<std::string> & dhIds,std::vector<std::string> & sharedKeyboardPaths,std::vector<std::string> & sharedKeyboardDhIds)229 void DistributedInputCollector::GetSharedKeyboardPathsByDhIds(const std::vector<std::string> &dhIds,
230     std::vector<std::string> &sharedKeyboardPaths, std::vector<std::string> &sharedKeyboardDhIds)
231 {
232     if (inputHub_ == nullptr) {
233         DHLOGE("inputHub is nullptr!");
234         return;
235     }
236     inputHub_->GetSharedKeyboardPathsByDhIds(dhIds, sharedKeyboardPaths, sharedKeyboardDhIds);
237 }
238 
IsAllDevicesStoped()239 bool DistributedInputCollector::IsAllDevicesStoped()
240 {
241     if (inputHub_ == nullptr) {
242         DHLOGE("inputHub is nullptr!");
243         return false;
244     }
245     return inputHub_->IsAllDevicesStoped();
246 }
247 
RegisterSharingDhIdListener(sptr<ISharingDhIdListener> sharingDhIdListener)248 int32_t DistributedInputCollector::RegisterSharingDhIdListener(sptr<ISharingDhIdListener> sharingDhIdListener)
249 {
250     DHLOGI("RegisterSharingDhIdListener");
251     std::lock_guard<std::mutex> lock(sharingDhIdListenerMtx_);
252     sharingDhIdListeners_.insert(sharingDhIdListener);
253     return DH_SUCCESS;
254 }
255 
GetDeviceInfoByType(const uint32_t inputTypes,std::map<int32_t,std::string> & deviceInfo)256 void DistributedInputCollector::GetDeviceInfoByType(const uint32_t inputTypes, std::map<int32_t,
257     std::string> &deviceInfo)
258 {
259     if (inputHub_ == nullptr) {
260         DHLOGE("inputHub is nullptr!");
261         return;
262     }
263     inputHub_->GetDevicesInfoByType(inputTypes, deviceInfo);
264 }
265 
ClearSkipDevicePaths()266 void DistributedInputCollector::ClearSkipDevicePaths()
267 {
268     if (inputHub_ == nullptr) {
269         DHLOGE("inputHub is nullptr!");
270         return;
271     }
272     inputHub_->ClearSkipDevicePaths();
273     inputHub_->ScanAndRecordInputDevices();
274 }
275 } // namespace DistributedInput
276 } // namespace DistributedHardware
277 } // namespace OHOS
278