1 /*
2 * Copyright (c) 2021-2022 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 "input_device_impl.h"
17
18 #include "mmi_log.h"
19 #include "multimodal_event_handler.h"
20 #include "multimodal_input_connect_manager.h"
21 #include "napi_constants.h"
22 #include "net_packet.h"
23
24 namespace OHOS {
25 namespace MMI {
26 namespace {
27 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, MMI_LOG_DOMAIN, "InputDeviceImpl"};
28 } // namespace
29
GetInstance()30 InputDeviceImpl& InputDeviceImpl::GetInstance()
31 {
32 static InputDeviceImpl instance;
33 return instance;
34 }
35
RegisterDevListener(const std::string & type,InputDevListenerPtr listener)36 int32_t InputDeviceImpl::RegisterDevListener(const std::string &type, InputDevListenerPtr listener)
37 {
38 CALL_DEBUG_ENTER;
39 CHKPR(listener, RET_ERR);
40 if (type != CHANGED_TYPE) {
41 MMI_HILOGE("Failed to register, listener event must be \"change\"");
42 return RET_ERR;
43 }
44 auto iter = devListener_.find(CHANGED_TYPE);
45 if (iter == devListener_.end()) {
46 MMI_HILOGE("Find change failed");
47 return RET_ERR;
48 }
49 for (const auto &item : iter->second) {
50 if (item == listener) {
51 MMI_HILOGW("The listener already exists");
52 return RET_ERR;
53 }
54 }
55 auto monitor = listener;
56 iter->second.push_back(monitor);
57 if (!isListeningProcess_) {
58 MMI_HILOGI("Start monitoring");
59 isListeningProcess_ = true;
60 return MultimodalInputConnMgr->RegisterDevListener();
61 }
62 return RET_OK;
63 }
64
UnregisterDevListener(const std::string & type,InputDevListenerPtr listener)65 int32_t InputDeviceImpl::UnregisterDevListener(const std::string &type, InputDevListenerPtr listener)
66 {
67 CALL_DEBUG_ENTER;
68 if (type != CHANGED_TYPE) {
69 MMI_HILOGE("Failed to cancel registration, listener event must be \"change\"");
70 return RET_ERR;
71 }
72 auto iter = devListener_.find(CHANGED_TYPE);
73 if (iter == devListener_.end()) {
74 MMI_HILOGE("Find change failed");
75 return RET_ERR;
76 }
77 if (listener == nullptr) {
78 iter->second.clear();
79 goto listenerLabel;
80 }
81 for (auto it = iter->second.begin(); it != iter->second.end(); ++it) {
82 if (*it == listener) {
83 iter->second.erase(it);
84 goto listenerLabel;
85 }
86 }
87
88 listenerLabel:
89 if (isListeningProcess_ && iter->second.empty()) {
90 isListeningProcess_ = false;
91 return MultimodalInputConnMgr->UnregisterDevListener();
92 }
93 return RET_OK;
94 }
95
OnDevListener(int32_t deviceId,const std::string & type)96 void InputDeviceImpl::OnDevListener(int32_t deviceId, const std::string &type)
97 {
98 CALL_DEBUG_ENTER;
99 std::lock_guard<std::mutex> guard(mtx_);
100 auto iter = devListener_.find("change");
101 if (iter == devListener_.end()) {
102 MMI_HILOGE("Find change failed");
103 return;
104 }
105 for (const auto &item : iter->second) {
106 MMI_HILOGI("Report device change task, event type:%{public}s", type.c_str());
107 if (type == "add") {
108 item->OnDeviceAdded(deviceId, type);
109 continue;
110 }
111 item->OnDeviceRemoved(deviceId, type);
112 }
113 }
114
GetInputDeviceIdsAsync(FunInputDevIds callback)115 int32_t InputDeviceImpl::GetInputDeviceIdsAsync(FunInputDevIds callback)
116 {
117 CALL_DEBUG_ENTER;
118 std::lock_guard<std::mutex> guard(mtx_);
119 InputDeviceData data;
120 data.ids = callback;
121 if (userData_ == INT32_MAX) {
122 MMI_HILOGE("userData exceeds the maximum");
123 return RET_ERR;
124 }
125 inputDevices_[userData_] = data;
126 return MultimodalInputConnMgr->GetDeviceIds(userData_++);
127 }
128
GetInputDeviceAsync(int32_t deviceId,FunInputDevInfo callback)129 int32_t InputDeviceImpl::GetInputDeviceAsync(int32_t deviceId, FunInputDevInfo callback)
130 {
131 CALL_DEBUG_ENTER;
132 std::lock_guard<std::mutex> guard(mtx_);
133 InputDeviceData data;
134 data.inputDevice = callback;
135 if (userData_ == INT32_MAX) {
136 MMI_HILOGE("UserData exceeds the maximum");
137 return RET_ERR;
138 }
139 inputDevices_[userData_] = data;
140 return MultimodalInputConnMgr->GetDevice(userData_++, deviceId);
141 }
142
SupportKeys(int32_t deviceId,std::vector<int32_t> keyCodes,FunInputDevKeys callback)143 int32_t InputDeviceImpl::SupportKeys(int32_t deviceId, std::vector<int32_t> keyCodes, FunInputDevKeys callback)
144 {
145 CALL_DEBUG_ENTER;
146 std::lock_guard<std::mutex> guard(mtx_);
147 if (keyCodes.size() > MAX_SUPPORT_KEY) {
148 MMI_HILOGE("Keys exceeds the max range");
149 return RET_ERR;
150 }
151 InputDeviceData data;
152 data.keys = callback;
153 if (userData_ == INT32_MAX) {
154 MMI_HILOGE("UserData exceeds the maximum");
155 return RET_ERR;
156 }
157 inputDevices_[userData_] = data;
158 return MultimodalInputConnMgr->SupportKeys(userData_++, deviceId, keyCodes);
159 }
160
GetKeyboardType(int32_t deviceId,FunKeyboardTypes callback)161 int32_t InputDeviceImpl::GetKeyboardType(int32_t deviceId, FunKeyboardTypes callback)
162 {
163 CALL_DEBUG_ENTER;
164 std::lock_guard<std::mutex> guard(mtx_);
165 InputDeviceData data;
166 data.kbTypes = callback;
167 if (userData_ == INT32_MAX) {
168 MMI_HILOGE("UserData exceeds the maximum");
169 return RET_ERR;
170 }
171 inputDevices_[userData_] = data;
172 return MultimodalInputConnMgr->GetKeyboardType(userData_++, deviceId);
173 }
174
OnInputDevice(int32_t userData,std::shared_ptr<InputDevice> devData)175 void InputDeviceImpl::OnInputDevice(int32_t userData, std::shared_ptr<InputDevice> devData)
176 {
177 CALL_DEBUG_ENTER;
178 CHK_PID_AND_TID();
179 std::lock_guard<std::mutex> guard(mtx_);
180 auto iter = inputDevices_.find(userData);
181 if (iter == inputDevices_.end()) {
182 MMI_HILOGI("Find userData failed");
183 return;
184 }
185 auto devInfo = GetDeviceInfo(userData);
186 CHKPV(devInfo);
187 CHKPV(devData);
188 (*devInfo)(devData);
189 MMI_HILOGD("Report device info, userData:%{public}d name:%{public}s type:%{public}d",
190 userData, devData->GetName().c_str(), devData->GetType());
191 }
192
OnInputDeviceIds(int32_t userData,std::vector<int32_t> & ids)193 void InputDeviceImpl::OnInputDeviceIds(int32_t userData, std::vector<int32_t> &ids)
194 {
195 CHK_PID_AND_TID();
196 std::lock_guard<std::mutex> guard(mtx_);
197 auto iter = inputDevices_.find(userData);
198 if (iter == inputDevices_.end()) {
199 MMI_HILOGI("Find userData failed");
200 return;
201 }
202 auto devIds = GetDeviceIds(userData);
203 CHKPV(devIds);
204 (*devIds)(ids);
205 MMI_HILOGD("Report all device, userData:%{public}d device:(%{public}s)",
206 userData, IdsListToString(ids).c_str());
207 }
208
OnSupportKeys(int32_t userData,std::vector<bool> & keystrokeAbility)209 void InputDeviceImpl::OnSupportKeys(int32_t userData, std::vector<bool> &keystrokeAbility)
210 {
211 CHK_PID_AND_TID();
212 std::lock_guard<std::mutex> guard(mtx_);
213 auto iter = inputDevices_.find(userData);
214 if (iter == inputDevices_.end()) {
215 MMI_HILOGI("Find userData failed");
216 return;
217 }
218 auto devKeys = GetDeviceKeys(userData);
219 CHKPV(devKeys);
220 (*devKeys)(keystrokeAbility);
221 }
222
OnKeyboardType(int32_t userData,int32_t keyboardType)223 void InputDeviceImpl::OnKeyboardType(int32_t userData, int32_t keyboardType)
224 {
225 CHK_PID_AND_TID();
226 std::lock_guard<std::mutex> guard(mtx_);
227 if (auto iter = inputDevices_.find(userData); iter == inputDevices_.end()) {
228 MMI_HILOGI("Find userData failed");
229 return;
230 }
231 auto devKbTypes = GetKeyboardTypes(userData);
232 CHKPV(devKbTypes);
233 (*devKbTypes)(keyboardType);
234 MMI_HILOGD("Keyboard type event userData:%{public}d keyboardType:%{public}d",
235 userData, keyboardType);
236 }
237
GetDeviceInfo(int32_t userData) const238 const InputDeviceImpl::FunInputDevInfo* InputDeviceImpl::GetDeviceInfo(int32_t userData) const
239 {
240 auto iter = inputDevices_.find(userData);
241 if (iter == inputDevices_.end()) {
242 return nullptr;
243 }
244 return &iter->second.inputDevice;
245 }
246
GetDeviceIds(int32_t userData) const247 const InputDeviceImpl::FunInputDevIds* InputDeviceImpl::GetDeviceIds(int32_t userData) const
248 {
249 auto iter = inputDevices_.find(userData);
250 if (iter == inputDevices_.end()) {
251 return nullptr;
252 }
253 return &iter->second.ids;
254 }
255
GetDeviceKeys(int32_t userData) const256 const InputDeviceImpl::FunInputDevKeys* InputDeviceImpl::GetDeviceKeys(int32_t userData) const
257 {
258 auto iter = inputDevices_.find(userData);
259 if (iter == inputDevices_.end()) {
260 return nullptr;
261 }
262 return &iter->second.keys;
263 }
264
GetKeyboardTypes(int32_t userData) const265 const InputDeviceImpl::FunKeyboardTypes* InputDeviceImpl::GetKeyboardTypes(int32_t userData) const
266 {
267 auto iter = inputDevices_.find(userData);
268 return iter == inputDevices_.end()? nullptr : &iter->second.kbTypes;
269 }
270
GetUserData()271 int32_t InputDeviceImpl::GetUserData()
272 {
273 return userData_;
274 }
275
DevDataUnmarshalling(NetPacket & pkt)276 std::shared_ptr<InputDevice> InputDeviceImpl::DevDataUnmarshalling(NetPacket &pkt)
277 {
278 auto devData = std::make_shared<InputDevice>();
279 int32_t deviceId;
280 pkt >> deviceId;
281 devData->SetId(deviceId);
282
283 std::string name;
284 pkt >> name;
285 devData->SetName(name);
286
287 int32_t deviceType;
288 pkt >> deviceType;
289 devData->SetType(deviceType);
290
291 int32_t bus;
292 pkt >> bus;
293 devData->SetBus(bus);
294
295 int32_t product;
296 pkt >> product;
297 devData->SetProduct(product);
298
299 int32_t vendor;
300 pkt >> vendor;
301 devData->SetVendor(vendor);
302
303 int32_t version;
304 pkt >> version;
305 devData->SetVersion(version);
306
307 std::string phys;
308 pkt >> phys;
309 devData->SetPhys(phys);
310
311 std::string uniq;
312 pkt >> uniq;
313 devData->SetUniq(uniq);
314
315 size_t size;
316 pkt >> size;
317 std::vector<InputDevice::AxisInfo> axisInfo;
318 for (size_t i = 0; i < size; ++i) {
319 InputDevice::AxisInfo axis;
320 int32_t type;
321 pkt >> type;
322 axis.SetAxisType(type);
323
324 int32_t min;
325 pkt >> min;
326 axis.SetMinimum(min);
327
328 int32_t max;
329 pkt >> max;
330 axis.SetMaximum(max);
331
332 int32_t fuzz;
333 pkt >> fuzz;
334 axis.SetFuzz(fuzz);
335
336 int32_t flat;
337 pkt >> flat;
338 axis.SetFlat(flat);
339
340 int32_t resolution;
341 pkt >> resolution;
342 axis.SetResolution(resolution);
343 devData->AddAxisInfo(axis);
344 }
345 return devData;
346 }
347 } // namespace MMI
348 } // namespace OHOS
349