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_manager.h"
17
18 #include <linux/input.h>
19 #include <parameters.h>
20 #ifdef OHOS_BUILD_ENABLE_COOPERATE
21 #include <openssl/sha.h>
22 #endif // OHOS_BUILD_ENABLE_COOPERATE
23 #include <regex>
24 #include <unordered_map>
25
26 #include "dfx_hisysevent.h"
27 #ifdef OHOS_BUILD_ENABLE_COOPERATE
28 #include "input_device_cooperate_sm.h"
29 #include "input_device_cooperate_util.h"
30 #endif // OHOS_BUILD_ENABLE_COOPERATE
31 #include "input_windows_manager.h"
32 #include "key_event_value_transformation.h"
33 #ifdef OHOS_BUILD_ENABLE_COOPERATE
34 #include "util.h"
35 #endif // OHOS_BUILD_ENABLE_COOPERATE
36 #include "util_ex.h"
37 #include "util_napi_error.h"
38
39 namespace OHOS {
40 namespace MMI {
41 namespace {
42 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, MMI_LOG_DOMAIN, "InputDeviceManager"};
43 constexpr int32_t INVALID_DEVICE_ID = -1;
44 constexpr int32_t SUPPORT_KEY = 1;
45
46 const std::string UNKNOWN_SCREEN_ID = "";
47 #ifdef OHOS_BUILD_ENABLE_COOPERATE
48 const char *SPLIT_SYMBOL = "|";
49 const std::string DH_ID_PREFIX = "Input_";
50 #endif // OHOS_BUILD_ENABLE_COOPERATE
51 const std::string INPUT_VIRTUAL_DEVICE_NAME = "Hos Distributed Virtual Device ";
52 std::unordered_map<int32_t, std::string> axisType = {
53 {ABS_MT_TOUCH_MAJOR, "TOUCH_MAJOR"},
54 {ABS_MT_TOUCH_MINOR, "TOUCH_MINOR"},
55 {ABS_MT_ORIENTATION, "ORIENTATION"},
56 {ABS_MT_POSITION_X, "POSITION_X"},
57 {ABS_MT_POSITION_Y, "POSITION_Y"},
58 {ABS_MT_PRESSURE, "PRESSURE"},
59 {ABS_MT_WIDTH_MAJOR, "WIDTH_MAJOR"},
60 {ABS_MT_WIDTH_MINOR, "WIDTH_MINOR"}
61 };
62
63 constexpr size_t EXPECTED_N_SUBMATCHES { 2 };
64 constexpr size_t EXPECTED_SUBMATCH { 1 };
65 } // namespace
66
InputDeviceManager()67 InputDeviceManager::InputDeviceManager() {}
~InputDeviceManager()68 InputDeviceManager::~InputDeviceManager() {}
69
GetInputDevice(int32_t id) const70 std::shared_ptr<InputDevice> InputDeviceManager::GetInputDevice(int32_t id) const
71 {
72 CALL_DEBUG_ENTER;
73 auto iter = inputDevice_.find(id);
74 if (iter == inputDevice_.end()) {
75 MMI_HILOGE("Failed to search for the device");
76 return nullptr;
77 }
78
79 std::shared_ptr<InputDevice> inputDevice = std::make_shared<InputDevice>();
80 CHKPP(inputDevice);
81 inputDevice->SetId(iter->first);
82 struct libinput_device *inputDeviceOrigin = iter->second.inputDeviceOrigin;
83 inputDevice->SetType(static_cast<int32_t>(libinput_device_get_tags(inputDeviceOrigin)));
84 const char* name = libinput_device_get_name(inputDeviceOrigin);
85 inputDevice->SetName((name == nullptr) ? ("null") : (name));
86 inputDevice->SetBus(libinput_device_get_id_bustype(inputDeviceOrigin));
87 inputDevice->SetVersion(libinput_device_get_id_version(inputDeviceOrigin));
88 inputDevice->SetProduct(libinput_device_get_id_product(inputDeviceOrigin));
89 inputDevice->SetVendor(libinput_device_get_id_vendor(inputDeviceOrigin));
90 const char* phys = libinput_device_get_phys(inputDeviceOrigin);
91 inputDevice->SetPhys((phys == nullptr) ? ("null") : (phys));
92 const char* uniq = libinput_device_get_uniq(inputDeviceOrigin);
93 inputDevice->SetUniq((uniq == nullptr) ? ("null") : (uniq));
94
95 InputDevice::AxisInfo axis;
96 for (const auto &item : axisType) {
97 int32_t min = libinput_device_get_axis_min(inputDeviceOrigin, item.first);
98 if (min == -1) {
99 MMI_HILOGD("The device does not support this axis");
100 continue;
101 }
102 if (item.first == ABS_MT_PRESSURE) {
103 axis.SetMinimum(0);
104 axis.SetMaximum(1);
105 } else {
106 axis.SetMinimum(min);
107 axis.SetMaximum(libinput_device_get_axis_max(inputDeviceOrigin, item.first));
108 }
109 axis.SetAxisType(item.first);
110 axis.SetFuzz(libinput_device_get_axis_fuzz(inputDeviceOrigin, item.first));
111 axis.SetFlat(libinput_device_get_axis_flat(inputDeviceOrigin, item.first));
112 axis.SetResolution(libinput_device_get_axis_resolution(inputDeviceOrigin, item.first));
113 inputDevice->AddAxisInfo(axis);
114 }
115 return inputDevice;
116 }
117
GetInputDeviceIds() const118 std::vector<int32_t> InputDeviceManager::GetInputDeviceIds() const
119 {
120 CALL_DEBUG_ENTER;
121 std::vector<int32_t> ids;
122 for (const auto &item : inputDevice_) {
123 #ifdef OHOS_BUILD_ENABLE_COOPERATE
124 if (IsRemote(item.second.inputDeviceOrigin) &&
125 InputDevCooSM->GetCurrentCooperateState() == CooperateState::STATE_FREE) {
126 MMI_HILOGW("Current device is remote and in STATUS_STATE");
127 continue;
128 }
129 #endif // OHOS_BUILD_ENABLE_COOPERATE
130 ids.push_back(item.first);
131 }
132 return ids;
133 }
134
SupportKeys(int32_t deviceId,std::vector<int32_t> & keyCodes,std::vector<bool> & keystroke)135 int32_t InputDeviceManager::SupportKeys(int32_t deviceId, std::vector<int32_t> &keyCodes, std::vector<bool> &keystroke)
136 {
137 CALL_DEBUG_ENTER;
138 auto iter = inputDevice_.find(deviceId);
139 if (iter == inputDevice_.end()) {
140 return COMMON_PARAMETER_ERROR;
141 }
142 for (const auto &item : keyCodes) {
143 bool ret = false;
144 for (const auto &it : KeyMapMgr->InputTransferKeyValue(deviceId, item)) {
145 ret |= libinput_device_has_key(iter->second.inputDeviceOrigin, it) == SUPPORT_KEY;
146 }
147 keystroke.push_back(ret);
148 }
149 return RET_OK;
150 }
151
IsMatchKeys(struct libinput_device * device,const std::vector<int32_t> & keyCodes) const152 bool InputDeviceManager::IsMatchKeys(struct libinput_device* device, const std::vector<int32_t> &keyCodes) const
153 {
154 CHKPF(device);
155 for (const auto &key : keyCodes) {
156 int32_t value = InputTransformationKeyValue(key);
157 if (libinput_device_keyboard_has_key(device, value) == SUPPORT_KEY) {
158 return true;
159 }
160 }
161 return false;
162 }
163
GetDeviceConfig(int32_t deviceId,int32_t & keyboardType)164 bool InputDeviceManager::GetDeviceConfig(int32_t deviceId, int32_t &keyboardType)
165 {
166 CALL_DEBUG_ENTER;
167 if (auto iter = inputDevice_.find(deviceId); iter == inputDevice_.end()) {
168 MMI_HILOGE("Failed to search for the deviceID");
169 return false;
170 }
171 auto deviceConfig = KeyRepeat->GetDeviceConfig();
172 auto it = deviceConfig.find(deviceId);
173 if (it == deviceConfig.end()) {
174 MMI_HILOGE("Failed to obtain the keyboard type of the configuration file");
175 return false;
176 }
177 keyboardType = it->second.keyboardType;
178 MMI_HILOGD("Get keyboard type results from the configuration file:%{public}d", keyboardType);
179 return true;
180 }
181
GetKeyboardBusMode(int32_t deviceId)182 int32_t InputDeviceManager::GetKeyboardBusMode(int32_t deviceId)
183 {
184 CALL_DEBUG_ENTER;
185 std::shared_ptr dev = GetInputDevice(deviceId);
186 CHKPR(dev, ERROR_NULL_POINTER);
187 return dev->GetBus();
188 }
189
GetDeviceSupportKey(int32_t deviceId,int32_t & keyboardType)190 int32_t InputDeviceManager::GetDeviceSupportKey(int32_t deviceId, int32_t &keyboardType)
191 {
192 CALL_DEBUG_ENTER;
193 std::vector <int32_t> keyCodes;
194 keyCodes.push_back(KeyEvent::KEYCODE_Q);
195 keyCodes.push_back(KeyEvent::KEYCODE_NUMPAD_1);
196 keyCodes.push_back(KeyEvent::KEYCODE_HOME);
197 keyCodes.push_back(KeyEvent::KEYCODE_CTRL_LEFT);
198 keyCodes.push_back(KeyEvent::KEYCODE_SHIFT_RIGHT);
199 keyCodes.push_back(KeyEvent::KEYCODE_F20);
200 std::vector<bool> supportKey;
201 int32_t ret = SupportKeys(deviceId, keyCodes, supportKey);
202 if (ret != RET_OK) {
203 MMI_HILOGE("SupportKey call failed");
204 return ret;
205 }
206 std::map<int32_t, bool> determineKbType;
207 for (size_t i = 0; i < keyCodes.size(); i++) {
208 determineKbType[keyCodes[i]] = supportKey[i];
209 }
210 if (determineKbType[KeyEvent::KEYCODE_HOME] && GetKeyboardBusMode(deviceId) == BUS_BLUETOOTH) {
211 keyboardType = KEYBOARD_TYPE_REMOTECONTROL;
212 MMI_HILOGD("The keyboard type is remote control:%{public}d", keyboardType);
213 } else if (determineKbType[KeyEvent::KEYCODE_NUMPAD_1] && !determineKbType[KeyEvent::KEYCODE_Q]) {
214 keyboardType = KEYBOARD_TYPE_DIGITALKEYBOARD;
215 MMI_HILOGD("The keyboard type is digital keyboard:%{public}d", keyboardType);
216 } else if (determineKbType[KeyEvent::KEYCODE_Q]) {
217 keyboardType = KEYBOARD_TYPE_ALPHABETICKEYBOARD;
218 MMI_HILOGD("The keyboard type is standard:%{public}d", keyboardType);
219 } else if (determineKbType[KeyEvent::KEYCODE_CTRL_LEFT] && determineKbType[KeyEvent::KEYCODE_SHIFT_RIGHT]
220 && determineKbType[KeyEvent::KEYCODE_F20]) {
221 keyboardType = KEYBOARD_TYPE_HANDWRITINGPEN;
222 MMI_HILOGD("The keyboard type is handwriting pen:%{public}d", keyboardType);
223 } else {
224 keyboardType = KEYBOARD_TYPE_UNKNOWN;
225 MMI_HILOGW("Undefined keyboard type");
226 }
227 MMI_HILOGD("Get keyboard type results by supporting keys:%{public}d", keyboardType);
228 return RET_OK;
229 }
230
GetKeyboardType(int32_t deviceId,int32_t & keyboardType)231 int32_t InputDeviceManager::GetKeyboardType(int32_t deviceId, int32_t &keyboardType)
232 {
233 CALL_DEBUG_ENTER;
234 int32_t tempKeyboardType = KEYBOARD_TYPE_NONE;
235 if (auto iter = inputDevice_.find(deviceId); iter == inputDevice_.end()) {
236 MMI_HILOGE("Failed to search for the deviceID");
237 return COMMON_PARAMETER_ERROR;
238 }
239 if (GetDeviceConfig(deviceId, tempKeyboardType)) {
240 keyboardType = tempKeyboardType;
241 return RET_OK;
242 }
243 return GetDeviceSupportKey(deviceId, keyboardType);
244 }
245
AddDevListener(SessionPtr sess,std::function<void (int32_t,const std::string &)> callback)246 void InputDeviceManager::AddDevListener(SessionPtr sess, std::function<void(int32_t, const std::string&)> callback)
247 {
248 CALL_DEBUG_ENTER;
249 auto ret = devListener_.insert({ sess, callback });
250 if (!ret.second) {
251 MMI_HILOGE("Session is duplicated");
252 return;
253 }
254 }
255
RemoveDevListener(SessionPtr sess)256 void InputDeviceManager::RemoveDevListener(SessionPtr sess)
257 {
258 CALL_DEBUG_ENTER;
259 auto iter = devListener_.find(sess);
260 if (iter == devListener_.end()) {
261 MMI_HILOGE("Session does not exist");
262 return;
263 }
264 devListener_.erase(iter);
265 }
266
267 #ifdef OHOS_BUILD_ENABLE_POINTER_DRAWING
HasPointerDevice()268 bool InputDeviceManager::HasPointerDevice()
269 {
270 for (auto it = inputDevice_.begin(); it != inputDevice_.end(); ++it) {
271 if (it->second.isPointerDevice) {
272 return true;
273 }
274 }
275 return false;
276 }
277 #endif // OHOS_BUILD_ENABLE_POINTER_DRAWING
278
HasTouchDevice()279 bool InputDeviceManager::HasTouchDevice()
280 {
281 CALL_DEBUG_ENTER;
282 for (auto it = inputDevice_.begin(); it != inputDevice_.end(); ++it) {
283 if (it->second.isTouchableDevice) {
284 return true;
285 }
286 }
287 return false;
288 }
289
ParseDeviceId(const std::string & sysName)290 int32_t InputDeviceManager::ParseDeviceId(const std::string &sysName)
291 {
292 CALL_DEBUG_ENTER;
293 std::regex pattern("^event(\\d+)$");
294 std::smatch mr;
295
296 if (std::regex_match(sysName, mr, pattern)) {
297 if (mr.ready() && mr.size() == EXPECTED_N_SUBMATCHES) {
298 return std::stoi(mr[EXPECTED_SUBMATCH].str());
299 }
300 }
301 return -1;
302 }
303
OnInputDeviceAdded(struct libinput_device * inputDevice)304 void InputDeviceManager::OnInputDeviceAdded(struct libinput_device *inputDevice)
305 {
306 CALL_DEBUG_ENTER;
307 CHKPV(inputDevice);
308 bool hasLocalPointer = false;
309 bool hasPointer = false;
310 for (const auto &item : inputDevice_) {
311 if (item.second.inputDeviceOrigin == inputDevice) {
312 MMI_HILOGI("The device is already existent");
313 DfxHisysevent::OnDeviceConnect(item.first, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT);
314 return;
315 }
316 if (item.second.isPointerDevice) {
317 hasPointer = true;
318 if (!item.second.isRemote) {
319 hasLocalPointer = true;
320 }
321 }
322 }
323
324 const char *sysName = libinput_device_get_sysname(inputDevice);
325 CHKPV(sysName);
326 int32_t deviceId = ParseDeviceId(std::string(sysName));
327 if (deviceId < 0) {
328 MMI_HILOGE("Parsing sysname failed: \'%{public}s\'", sysName);
329 return;
330 }
331
332 struct InputDeviceInfo info;
333 MakeDeviceInfo(inputDevice, info);
334 inputDevice_[deviceId] = info;
335 #ifdef OHOS_BUILD_ENABLE_COOPERATE
336 if (!IsRemote(inputDevice) || InputDevCooSM->GetCurrentCooperateState() != CooperateState::STATE_FREE) {
337 for (const auto &item : devListener_) {
338 CHKPC(item.first);
339 item.second(deviceId, "add");
340 }
341 }
342 #else
343 for (const auto &item : devListener_) {
344 CHKPC(item.first);
345 item.second(deviceId, "add");
346 }
347 #endif // OHOS_BUILD_ENABLE_COOPERATE
348
349 #ifdef OHOS_BUILD_ENABLE_COOPERATE
350 if (IsKeyboardDevice(inputDevice)) {
351 if (IsRemote(inputDevice)) {
352 InputDevCooSM->SetVirtualKeyBoardDevId(deviceId);
353 }
354 InputDevCooSM->OnKeyboardOnline(info.dhid);
355 }
356 #endif // OHOS_BUILD_ENABLE_COOPERATE
357 #if defined(OHOS_BUILD_ENABLE_POINTER) && defined(OHOS_BUILD_ENABLE_POINTER_DRAWING)
358 if (!hasPointer && info.isPointerDevice) {
359 bool visible = !info.isRemote || hasLocalPointer;
360 if (HasTouchDevice()) {
361 IPointerDrawingManager::GetInstance()->SetMouseDisplayState(false);
362 }
363 NotifyPointerDevice(true, visible);
364 OHOS::system::SetParameter(INPUT_POINTER_DEVICE, "true");
365 MMI_HILOGI("Set para input.pointer.device true");
366 }
367 #endif // OHOS_BUILD_ENABLE_POINTER && OHOS_BUILD_ENABLE_POINTER_DRAWING
368 #if defined(OHOS_BUILD_ENABLE_POINTER) && defined(OHOS_BUILD_ENABLE_POINTER_DRAWING)
369 if (info.isPointerDevice && !HasPointerDevice() &&
370 IPointerDrawingManager::GetInstance()->GetMouseDisplayState()) {
371 #ifdef OHOS_BUILD_ENABLE_POINTER
372 WinMgr->DispatchPointer(PointerEvent::POINTER_ACTION_ENTER_WINDOW);
373 #endif // OHOS_BUILD_ENABLE_POINTER
374 }
375 #endif // OHOS_BUILD_ENABLE_POINTER && OHOS_BUILD_ENABLE_POINTER_DRAWING
376 DfxHisysevent::OnDeviceConnect(deviceId, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR);
377 }
378
MakeDeviceInfo(struct libinput_device * inputDevice,struct InputDeviceInfo & info)379 void InputDeviceManager::MakeDeviceInfo(struct libinput_device *inputDevice, struct InputDeviceInfo& info)
380 {
381 info.inputDeviceOrigin = inputDevice;
382 info.isRemote = IsRemote(inputDevice);
383 info.isPointerDevice = IsPointerDevice(inputDevice);
384 info.isTouchableDevice = IsTouchDevice(inputDevice);
385 #ifdef OHOS_BUILD_ENABLE_COOPERATE
386 if (info.isRemote) {
387 info.networkIdOrigin = MakeNetworkId(libinput_device_get_phys(inputDevice));
388 }
389 info.dhid = GenerateDescriptor(inputDevice, info.isRemote);
390 #endif // OHOS_BUILD_ENABLE_COOPERATE
391 }
392
OnInputDeviceRemoved(struct libinput_device * inputDevice)393 void InputDeviceManager::OnInputDeviceRemoved(struct libinput_device *inputDevice)
394 {
395 CALL_DEBUG_ENTER;
396 CHKPV(inputDevice);
397 int32_t deviceId = INVALID_DEVICE_ID;
398 #ifdef OHOS_BUILD_ENABLE_COOPERATE
399 struct InputDeviceInfo removedInfo;
400 std::vector<std::string> dhids;
401 #endif // OHOS_BUILD_ENABLE_COOPERATE
402 for (auto it = inputDevice_.begin(); it != inputDevice_.end(); ++it) {
403 if (it->second.inputDeviceOrigin == inputDevice) {
404 deviceId = it->first;
405 #ifdef OHOS_BUILD_ENABLE_COOPERATE
406 removedInfo = it->second;
407 dhids = GetCooperateDhids(deviceId);
408 #endif // OHOS_BUILD_ENABLE_COOPERATE
409 DfxHisysevent::OnDeviceDisconnect(deviceId, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR);
410 inputDevice_.erase(it);
411 break;
412 }
413 }
414 #if defined(OHOS_BUILD_ENABLE_POINTER) && defined(OHOS_BUILD_ENABLE_POINTER_DRAWING)
415 if (IsPointerDevice(inputDevice) && !HasPointerDevice() &&
416 IPointerDrawingManager::GetInstance()->GetMouseDisplayState()) {
417 #ifdef OHOS_BUILD_ENABLE_POINTER
418 WinMgr->DispatchPointer(PointerEvent::POINTER_ACTION_LEAVE_WINDOW);
419 #endif // OHOS_BUILD_ENABLE_POINTER
420 }
421 #endif // OHOS_BUILD_ENABLE_POINTER && OHOS_BUILD_ENABLE_POINTER_DRAWING
422 #ifdef OHOS_BUILD_ENABLE_COOPERATE
423 if (!IsRemote(inputDevice) || InputDevCooSM->GetCurrentCooperateState() != CooperateState::STATE_FREE) {
424 for (const auto &item : devListener_) {
425 CHKPC(item.first);
426 item.second(deviceId, "remove");
427 }
428 }
429 #else
430 for (const auto &item : devListener_) {
431 CHKPC(item.first);
432 item.second(deviceId, "remove");
433 }
434 #endif // OHOS_BUILD_ENABLE_COOPERATE
435 ScanPointerDevice();
436 #ifdef OHOS_BUILD_ENABLE_COOPERATE
437 if (IsPointerDevice(inputDevice)) {
438 InputDevCooSM->OnPointerOffline(removedInfo.dhid, removedInfo.networkIdOrigin, dhids);
439 }
440 #endif // OHOS_BUILD_ENABLE_COOPERATE
441 if (deviceId == INVALID_DEVICE_ID) {
442 DfxHisysevent::OnDeviceDisconnect(INVALID_DEVICE_ID, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT);
443 }
444 }
445
ScanPointerDevice()446 void InputDeviceManager::ScanPointerDevice()
447 {
448 bool hasPointerDevice = false;
449 for (auto it = inputDevice_.begin(); it != inputDevice_.end(); ++it) {
450 if (it->second.isPointerDevice) {
451 hasPointerDevice = true;
452 break;
453 }
454 }
455 if (!hasPointerDevice) {
456 NotifyPointerDevice(false, false);
457 OHOS::system::SetParameter(INPUT_POINTER_DEVICE, "false");
458 MMI_HILOGI("Set para input.pointer.device false");
459 }
460 }
461
IsPointerDevice(struct libinput_device * device) const462 bool InputDeviceManager::IsPointerDevice(struct libinput_device* device) const
463 {
464 CHKPF(device);
465 return libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_POINTER);
466 }
467
IsKeyboardDevice(struct libinput_device * device) const468 bool InputDeviceManager::IsKeyboardDevice(struct libinput_device* device) const
469 {
470 CHKPF(device);
471 return libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_KEYBOARD);
472 }
473
IsTouchDevice(struct libinput_device * device) const474 bool InputDeviceManager::IsTouchDevice(struct libinput_device* device) const
475 {
476 CHKPF(device);
477 return libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TOUCH);
478 }
479
Attach(std::shared_ptr<IDeviceObserver> observer)480 void InputDeviceManager::Attach(std::shared_ptr<IDeviceObserver> observer)
481 {
482 CALL_DEBUG_ENTER;
483 observers_.push_back(observer);
484 }
485
Detach(std::shared_ptr<IDeviceObserver> observer)486 void InputDeviceManager::Detach(std::shared_ptr<IDeviceObserver> observer)
487 {
488 CALL_DEBUG_ENTER;
489 observers_.remove(observer);
490 }
491
NotifyPointerDevice(bool hasPointerDevice,bool isVisible)492 void InputDeviceManager::NotifyPointerDevice(bool hasPointerDevice, bool isVisible)
493 {
494 MMI_HILOGI("observers_ size:%{public}zu", observers_.size());
495 for (auto observer = observers_.begin(); observer != observers_.end(); observer++) {
496 (*observer)->UpdatePointerDevice(hasPointerDevice, isVisible);
497 }
498 }
499
FindInputDeviceId(struct libinput_device * inputDevice)500 int32_t InputDeviceManager::FindInputDeviceId(struct libinput_device* inputDevice)
501 {
502 CALL_DEBUG_ENTER;
503 CHKPR(inputDevice, INVALID_DEVICE_ID);
504 for (const auto &item : inputDevice_) {
505 if (item.second.inputDeviceOrigin == inputDevice) {
506 MMI_HILOGI("Find input device id success");
507 return item.first;
508 }
509 }
510 MMI_HILOGE("Find input device id failed");
511 return INVALID_DEVICE_ID;
512 }
513
GetKeyboardDevice() const514 struct libinput_device* InputDeviceManager::GetKeyboardDevice() const
515 {
516 CALL_DEBUG_ENTER;
517 std::vector<int32_t> keyCodes;
518 keyCodes.push_back(KeyEvent::KEYCODE_Q);
519 keyCodes.push_back(KeyEvent::KEYCODE_NUMPAD_1);
520 for (const auto &item : inputDevice_) {
521 const auto &device = item.second.inputDeviceOrigin;
522 if (IsMatchKeys(device, keyCodes)) {
523 MMI_HILOGI("Find keyboard device success");
524 return device;
525 }
526 }
527 MMI_HILOGW("No keyboard device is currently available");
528 return nullptr;
529 }
530
Dump(int32_t fd,const std::vector<std::string> & args)531 void InputDeviceManager::Dump(int32_t fd, const std::vector<std::string> &args)
532 {
533 CALL_DEBUG_ENTER;
534 mprintf(fd, "Device information:\t");
535 mprintf(fd, "Input devices: count=%d", inputDevice_.size());
536 for (const auto &item : inputDevice_) {
537 std::shared_ptr<InputDevice> inputDevice = GetInputDevice(item.first);
538 CHKPV(inputDevice);
539 mprintf(fd,
540 "deviceId:%d | deviceName:%s | deviceType:%d | bus:%d | version:%d "
541 "| product:%d | vendor:%d | phys:%s\t",
542 inputDevice->GetId(), inputDevice->GetName().c_str(), inputDevice->GetType(),
543 inputDevice->GetBus(), inputDevice->GetVersion(), inputDevice->GetProduct(),
544 inputDevice->GetVendor(), inputDevice->GetPhys().c_str());
545 std::vector<InputDevice::AxisInfo> axisinfo = inputDevice->GetAxisInfo();
546 mprintf(fd, "axis: count=%d", axisinfo.size());
547 for (const auto &axis : axisinfo) {
548 auto iter = axisType.find(axis.GetAxisType());
549 if (iter == axisType.end()) {
550 MMI_HILOGE("The axisType is not found");
551 return;
552 }
553 mprintf(fd,
554 "\t axisType:%s | minimum:%d | maximum:%d | fuzz:%d | flat:%d | resolution:%d\t",
555 iter->second.c_str(), axis.GetMinimum(), axis.GetMaximum(), axis.GetFuzz(),
556 axis.GetFlat(), axis.GetResolution());
557 }
558 }
559 }
560
DumpDeviceList(int32_t fd,const std::vector<std::string> & args)561 void InputDeviceManager::DumpDeviceList(int32_t fd, const std::vector<std::string> &args)
562 {
563 CALL_DEBUG_ENTER;
564 std::vector<int32_t> ids = GetInputDeviceIds();
565 mprintf(fd, "Total device:%d, Device list:\t", int32_t { ids.size() });
566 for (const auto &item : inputDevice_) {
567 std::shared_ptr<InputDevice> inputDevice = GetInputDevice(item.first);
568 CHKPV(inputDevice);
569 int32_t deviceId = inputDevice->GetId();
570 mprintf(fd,
571 "deviceId:%d | deviceName:%s | deviceType:%d | bus:%d | version:%d | product:%d | vendor:%d\t",
572 deviceId, inputDevice->GetName().c_str(), inputDevice->GetType(), inputDevice->GetBus(),
573 inputDevice->GetVersion(), inputDevice->GetProduct(), inputDevice->GetVendor());
574 }
575 }
576
IsRemote(struct libinput_device * inputDevice) const577 bool InputDeviceManager::IsRemote(struct libinput_device *inputDevice) const
578 {
579 CHKPF(inputDevice);
580 bool isRemote = false;
581 const char* name = libinput_device_get_name(inputDevice);
582 if (name == nullptr || name[0] == '\0') {
583 MMI_HILOGD("Device name is empty");
584 return false;
585 }
586 std::string strName = name;
587 std::string::size_type pos = strName.find(INPUT_VIRTUAL_DEVICE_NAME);
588 if (pos != std::string::npos) {
589 isRemote = true;
590 }
591 MMI_HILOGD("isRemote:%{public}s", isRemote ? "true" : "false");
592 return isRemote;
593 }
594
IsRemote(int32_t id) const595 bool InputDeviceManager::IsRemote(int32_t id) const
596 {
597 bool isRemote = false;
598 auto device = inputDevice_.find(id);
599 if (device != inputDevice_.end()) {
600 isRemote = device->second.isRemote;
601 }
602 MMI_HILOGD("isRemote: %{public}s", isRemote == true ? "true" : "false");
603 return isRemote;
604 }
605 #ifdef OHOS_BUILD_ENABLE_COOPERATE
GetCooperateDhids(int32_t deviceId)606 std::vector<std::string> InputDeviceManager::GetCooperateDhids(int32_t deviceId)
607 {
608 std::vector<std::string> dhids;
609 auto iter = inputDevice_.find(deviceId);
610 if (iter == inputDevice_.end()) {
611 MMI_HILOGI("Find pointer id failed");
612 return dhids;
613 }
614 if (!iter->second.isPointerDevice) {
615 MMI_HILOGI("Not pointer device");
616 return dhids;
617 }
618 dhids.push_back(iter->second.dhid);
619 MMI_HILOGI("unq: %{public}s, type:%{public}s", dhids.back().c_str(), "pointer");
620 auto pointerNetworkId = iter->second.networkIdOrigin;
621 std::string localNetworkId = GetLocalDeviceId();
622 pointerNetworkId = iter->second.isRemote ? iter->second.networkIdOrigin : localNetworkId;
623 for (const auto &item : inputDevice_) {
624 auto networkId = item.second.isRemote ? item.second.networkIdOrigin : localNetworkId;
625 if (networkId != pointerNetworkId) {
626 continue;
627 }
628 int32_t keyboardType = KEYBOARD_TYPE_NONE;
629 if (GetDeviceSupportKey(item.first, keyboardType) != RET_OK) {
630 MMI_HILOGI("Get device support key failed");
631 return dhids;
632 }
633 if (keyboardType == KEYBOARD_TYPE_ALPHABETICKEYBOARD) {
634 dhids.push_back(item.second.dhid);
635 MMI_HILOGI("unq: %{public}s, type:%{public}s", dhids.back().c_str(), "supportkey");
636 }
637 }
638 return dhids;
639 }
640
GetCooperateDhids(const std::string & dhid)641 std::vector<std::string> InputDeviceManager::GetCooperateDhids(const std::string &dhid)
642 {
643 int32_t inputDeviceId = INVALID_DEVICE_ID;
644 for (const auto &iter : inputDevice_) {
645 if (iter.second.dhid == dhid) {
646 inputDeviceId = iter.first;
647 break;
648 }
649 }
650 return GetCooperateDhids(inputDeviceId);
651 }
652
GetOriginNetworkId(int32_t id)653 std::string InputDeviceManager::GetOriginNetworkId(int32_t id)
654 {
655 auto iter = inputDevice_.find(id);
656 if (iter == inputDevice_.end()) {
657 MMI_HILOGE("Failed to search for the device: id %{public}d", id);
658 return "";
659 }
660 auto networkId = iter->second.networkIdOrigin;
661 if (networkId.empty()) {
662 networkId = GetLocalDeviceId();
663 }
664 return networkId;
665 }
666
GetOriginNetworkId(const std::string & dhid)667 std::string InputDeviceManager::GetOriginNetworkId(const std::string &dhid)
668 {
669 if (dhid.empty()) {
670 return "";
671 }
672 std::string networkId;
673 for (const auto &iter : inputDevice_) {
674 if (iter.second.isRemote && iter.second.dhid == dhid) {
675 networkId = iter.second.networkIdOrigin;
676 break;
677 }
678 }
679 return networkId;
680 }
681
GetDhid(int32_t deviceId) const682 std::string InputDeviceManager::GetDhid(int32_t deviceId) const
683 {
684 auto dev = inputDevice_.find(deviceId);
685 if (dev != inputDevice_.end()) {
686 return dev->second.dhid;
687 }
688 return "";
689 }
690
HasLocalPointerDevice() const691 bool InputDeviceManager::HasLocalPointerDevice() const
692 {
693 for (auto it = inputDevice_.begin(); it != inputDevice_.end(); ++it) {
694 if (!it->second.isRemote && it->second.isPointerDevice) {
695 return true;
696 }
697 }
698 return false;
699 }
700
NotifyVirtualKeyBoardStatus(int32_t deviceId,bool isAvailable) const701 void InputDeviceManager::NotifyVirtualKeyBoardStatus(int32_t deviceId, bool isAvailable) const
702 {
703 MMI_HILOGI("virtual keyboard device %{public}s", isAvailable ? "online" : "offline");
704 if (deviceId == -1) {
705 MMI_HILOGE("no virtual keyboard device for this device!");
706 return;
707 }
708
709 for (const auto &item : devListener_) {
710 CHKPC(item.first);
711 item.second(deviceId, isAvailable ? "add" : "remove");
712 }
713 }
714
MakeNetworkId(const char * phys) const715 std::string InputDeviceManager::MakeNetworkId(const char *phys) const
716 {
717 std::string networkId;
718 if (phys == nullptr || phys[0] == '\0') {
719 return networkId;
720 }
721 std::string strPhys = phys;
722 std::vector<std::string> strList;
723 StringSplit(strPhys, SPLIT_SYMBOL, strList);
724 if (strList.size() == 3) {
725 networkId = strList[1];
726 }
727 return networkId;
728 }
729
Sha256(const std::string & in) const730 std::string InputDeviceManager::Sha256(const std::string &in) const
731 {
732 unsigned char out[SHA256_DIGEST_LENGTH * 2 + 1] = {0};
733 SHA256_CTX ctx;
734 SHA256_Init(&ctx);
735 SHA256_Update(&ctx, in.data(), in.size());
736 SHA256_Final(&out[SHA256_DIGEST_LENGTH], &ctx);
737 // here we translate sha256 hash to hexadecimal. each 8-bit char will be presented by two characters([0-9a-f])
738 constexpr int32_t WIDTH = 4;
739 constexpr unsigned char MASK = 0x0F;
740 const char* hexCode = "0123456789abcdef";
741 constexpr int32_t DOUBLE_TIMES = 2;
742 for (int32_t i = 0; i < SHA256_DIGEST_LENGTH; ++i) {
743 unsigned char value = out[SHA256_DIGEST_LENGTH + i];
744 // uint8_t is 2 digits in hexadecimal.
745 out[i * DOUBLE_TIMES] = hexCode[(value >> WIDTH) & MASK];
746 out[i * DOUBLE_TIMES + 1] = hexCode[value & MASK];
747 }
748 out[SHA256_DIGEST_LENGTH * DOUBLE_TIMES] = 0;
749 return reinterpret_cast<char*>(out);
750 }
751
GenerateDescriptor(struct libinput_device * inputDevice,bool isRemote) const752 std::string InputDeviceManager::GenerateDescriptor(struct libinput_device *inputDevice, bool isRemote) const
753 {
754 const char* physicalPath = libinput_device_get_phys(inputDevice);
755 std::string descriptor;
756 if (isRemote && physicalPath != nullptr) {
757 MMI_HILOGI("physicalPath:%{public}s", physicalPath);
758 std::vector<std::string> strList;
759 StringSplit(physicalPath, SPLIT_SYMBOL, strList);
760 if (strList.size() == 3) {
761 descriptor = strList[2];
762 }
763 return descriptor;
764 }
765
766 uint16_t vendor = libinput_device_get_id_vendor(inputDevice);
767 const char* name = libinput_device_get_name(inputDevice);
768 const char* uniqueId = libinput_device_get_uniq(inputDevice);
769 uint16_t product = libinput_device_get_id_product(inputDevice);
770 std::string rawDescriptor;
771 rawDescriptor += StringPrintf(":%04x:%04x:", vendor, product);
772 // add handling for USB devices to not uniqueify kbs that show up twice
773 if (uniqueId != nullptr && uniqueId[0] != '\0') {
774 rawDescriptor += "uniqueId:" + std::string(uniqueId);
775 }
776 if (physicalPath != nullptr) {
777 rawDescriptor += "physicalPath:" + std::string(physicalPath);
778 }
779 if (name != nullptr && name[0] != '\0') {
780 rawDescriptor += "name:" + regex_replace(name, std::regex(" "), "");
781 }
782 descriptor = DH_ID_PREFIX + Sha256(rawDescriptor);
783 MMI_HILOGI("Created descriptor raw: %{public}s", rawDescriptor.c_str());
784 return descriptor;
785 }
786 #endif // OHOS_BUILD_ENABLE_COOPERATE
SetInputDevice(const std::string & dhid,const std::string & screenId)787 int32_t InputDeviceManager::SetInputDevice(const std::string& dhid, const std::string& screenId)
788 {
789 CALL_DEBUG_ENTER;
790 #ifdef OHOS_BUILD_ENABLE_COOPERATE
791 if (dhid.empty()) {
792 MMI_HILOGE("hdid is empty");
793 return RET_ERR;
794 }
795 if (screenId.empty()) {
796 MMI_HILOGE("screenId is empty");
797 return RET_ERR;
798 }
799 inputDeviceScreens_[dhid] = screenId;
800 #endif // OHOS_BUILD_ENABLE_COOPERATE
801 return RET_OK;
802 }
803
GetScreenId(int32_t deviceId) const804 const std::string& InputDeviceManager::GetScreenId(int32_t deviceId) const
805 {
806 CALL_DEBUG_ENTER;
807 #ifdef OHOS_BUILD_ENABLE_COOPERATE
808 auto item = inputDevice_.find(deviceId);
809 if (item != inputDevice_.end()) {
810 auto iter = inputDeviceScreens_.find(item->second.dhid);
811 if (iter != inputDeviceScreens_.end()) {
812 return iter->second;
813 }
814 }
815 MMI_HILOGE("Find input device screen id failed");
816 #endif // OHOS_BUILD_ENABLE_COOPERATE
817 return UNKNOWN_SCREEN_ID;
818 }
819 } // namespace MMI
820 } // namespace OHOS
821