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 #include <regex>
21 #include <unordered_map>
22
23 #include "dfx_hisysevent.h"
24 #include "event_dispatch_handler.h"
25 #include "input_windows_manager.h"
26 #include "key_auto_repeat.h"
27 #include "key_event_normalize.h"
28 #include "key_event_value_transformation.h"
29 #include "key_map_manager.h"
30 #include "pointer_drawing_manager.h"
31 #include "util_ex.h"
32 #include "util_napi_error.h"
33
34 namespace OHOS {
35 namespace MMI {
36 namespace {
37 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = { LOG_CORE, MMI_LOG_DOMAIN, "InputDeviceManager" };
38 constexpr int32_t INVALID_DEVICE_ID = -1;
39 constexpr int32_t SUPPORT_KEY = 1;
40 const std::string UNKNOWN_SCREEN_ID = "";
41 const std::string INPUT_VIRTUAL_DEVICE_NAME = "DistributedInput ";
42 std::unordered_map<int32_t, std::string> axisType{
43 { ABS_MT_TOUCH_MAJOR, "TOUCH_MAJOR" }, { ABS_MT_TOUCH_MINOR, "TOUCH_MINOR" }, { ABS_MT_ORIENTATION, "ORIENTATION" },
44 { ABS_MT_POSITION_X, "POSITION_X" }, { ABS_MT_POSITION_Y, "POSITION_Y" }, { ABS_MT_PRESSURE, "PRESSURE" },
45 { ABS_MT_WIDTH_MAJOR, "WIDTH_MAJOR" }, { ABS_MT_WIDTH_MINOR, "WIDTH_MINOR" }
46 };
47
48 std::vector<std::pair<enum libinput_device_capability, InputDeviceCapability>> devCapEnumMaps{
49 { LIBINPUT_DEVICE_CAP_KEYBOARD, InputDeviceCapability::INPUT_DEV_CAP_KEYBOARD },
50 { LIBINPUT_DEVICE_CAP_POINTER, InputDeviceCapability::INPUT_DEV_CAP_POINTER },
51 { LIBINPUT_DEVICE_CAP_TOUCH, InputDeviceCapability::INPUT_DEV_CAP_TOUCH },
52 { LIBINPUT_DEVICE_CAP_TABLET_TOOL, InputDeviceCapability::INPUT_DEV_CAP_TABLET_TOOL },
53 { LIBINPUT_DEVICE_CAP_TABLET_PAD, InputDeviceCapability::INPUT_DEV_CAP_TABLET_PAD },
54 { LIBINPUT_DEVICE_CAP_GESTURE, InputDeviceCapability::INPUT_DEV_CAP_GESTURE },
55 { LIBINPUT_DEVICE_CAP_SWITCH, InputDeviceCapability::INPUT_DEV_CAP_SWITCH },
56 { LIBINPUT_DEVICE_CAP_JOYSTICK, InputDeviceCapability::INPUT_DEV_CAP_JOYSTICK },
57 };
58
59 constexpr size_t EXPECTED_N_SUBMATCHES{ 2 };
60 constexpr size_t EXPECTED_SUBMATCH{ 1 };
61 } // namespace
62
InputDeviceManager()63 InputDeviceManager::InputDeviceManager() {}
~InputDeviceManager()64 InputDeviceManager::~InputDeviceManager() {}
65
GetInputDevice(int32_t id,bool checked) const66 std::shared_ptr<InputDevice> InputDeviceManager::GetInputDevice(int32_t id, bool checked) const
67 {
68 CALL_DEBUG_ENTER;
69 auto iter = inputDevice_.find(id);
70 if (iter == inputDevice_.end()) {
71 MMI_HILOGE("Failed to search for the device");
72 return nullptr;
73 }
74 if (checked && !iter->second.enable) {
75 MMI_HILOGE("The current device has been disabled");
76 return nullptr;
77 }
78 std::shared_ptr<InputDevice> inputDevice = std::make_shared<InputDevice>();
79 inputDevice->SetId(iter->first);
80 struct libinput_device *inputDeviceOrigin = iter->second.inputDeviceOrigin;
81 FillInputDevice(inputDevice, inputDeviceOrigin);
82
83 InputDevice::AxisInfo axis;
84 for (const auto &item : axisType) {
85 int32_t min = libinput_device_get_axis_min(inputDeviceOrigin, item.first);
86 if (min == -1) {
87 MMI_HILOGD("The device does not support this axis");
88 continue;
89 }
90 if (item.first == ABS_MT_PRESSURE) {
91 axis.SetMinimum(0);
92 axis.SetMaximum(1);
93 } else {
94 axis.SetMinimum(min);
95 axis.SetMaximum(libinput_device_get_axis_max(inputDeviceOrigin, item.first));
96 }
97 axis.SetAxisType(item.first);
98 axis.SetFuzz(libinput_device_get_axis_fuzz(inputDeviceOrigin, item.first));
99 axis.SetFlat(libinput_device_get_axis_flat(inputDeviceOrigin, item.first));
100 axis.SetResolution(libinput_device_get_axis_resolution(inputDeviceOrigin, item.first));
101 inputDevice->AddAxisInfo(axis);
102 }
103 return inputDevice;
104 }
105
FillInputDevice(std::shared_ptr<InputDevice> inputDevice,libinput_device * deviceOrigin) const106 void InputDeviceManager::FillInputDevice(std::shared_ptr<InputDevice> inputDevice, libinput_device *deviceOrigin) const
107 {
108 inputDevice->SetType(static_cast<int32_t>(libinput_device_get_tags(deviceOrigin)));
109 const char *name = libinput_device_get_name(deviceOrigin);
110 inputDevice->SetName((name == nullptr) ? ("null") : (name));
111 inputDevice->SetBus(libinput_device_get_id_bustype(deviceOrigin));
112 inputDevice->SetVersion(libinput_device_get_id_version(deviceOrigin));
113 inputDevice->SetProduct(libinput_device_get_id_product(deviceOrigin));
114 inputDevice->SetVendor(libinput_device_get_id_vendor(deviceOrigin));
115 const char *phys = libinput_device_get_phys(deviceOrigin);
116 inputDevice->SetPhys((phys == nullptr) ? ("null") : (phys));
117 const char *uniq = libinput_device_get_uniq(deviceOrigin);
118 inputDevice->SetUniq((uniq == nullptr) ? ("null") : (uniq));
119
120 for (const auto &[first, second] : devCapEnumMaps) {
121 if (libinput_device_has_capability(deviceOrigin, first)) {
122 inputDevice->AddCapability(second);
123 }
124 }
125 }
126
GetInputDeviceIds() const127 std::vector<int32_t> InputDeviceManager::GetInputDeviceIds() const
128 {
129 CALL_DEBUG_ENTER;
130 std::vector<int32_t> ids;
131 for (const auto &item : inputDevice_) {
132 if (!item.second.enable) {
133 MMI_HILOGE("The current device has been disabled");
134 continue;
135 }
136 ids.push_back(item.first);
137 }
138 return ids;
139 }
140
SupportKeys(int32_t deviceId,std::vector<int32_t> & keyCodes,std::vector<bool> & keystroke)141 int32_t InputDeviceManager::SupportKeys(int32_t deviceId, std::vector<int32_t> &keyCodes, std::vector<bool> &keystroke)
142 {
143 CALL_DEBUG_ENTER;
144 auto iter = inputDevice_.find(deviceId);
145 if (iter == inputDevice_.end()) {
146 return COMMON_PARAMETER_ERROR;
147 }
148 if (!iter->second.enable) {
149 MMI_HILOGE("The current device has been disabled");
150 return RET_ERR;
151 }
152 for (const auto &item : keyCodes) {
153 bool ret = false;
154 for (const auto &it : KeyMapMgr->InputTransferKeyValue(deviceId, item)) {
155 ret |= libinput_device_has_key(iter->second.inputDeviceOrigin, it) == SUPPORT_KEY;
156 }
157 keystroke.push_back(ret);
158 }
159 return RET_OK;
160 }
161
IsMatchKeys(struct libinput_device * device,const std::vector<int32_t> & keyCodes) const162 bool InputDeviceManager::IsMatchKeys(struct libinput_device *device, const std::vector<int32_t> &keyCodes) const
163 {
164 CHKPF(device);
165 for (const auto &key : keyCodes) {
166 int32_t value = InputTransformationKeyValue(key);
167 if (libinput_device_keyboard_has_key(device, value) == SUPPORT_KEY) {
168 return true;
169 }
170 }
171 return false;
172 }
173
GetDeviceConfig(int32_t deviceId,int32_t & keyboardType)174 bool InputDeviceManager::GetDeviceConfig(int32_t deviceId, int32_t &keyboardType)
175 {
176 CALL_DEBUG_ENTER;
177 if (auto iter = inputDevice_.find(deviceId); iter == inputDevice_.end()) {
178 MMI_HILOGE("Failed to search for the deviceID");
179 return false;
180 }
181 auto deviceConfig = KeyRepeat->GetDeviceConfig();
182 auto it = deviceConfig.find(deviceId);
183 if (it == deviceConfig.end()) {
184 MMI_HILOGD("Failed to obtain the keyboard type of the configuration file");
185 return false;
186 }
187 keyboardType = it->second.keyboardType;
188 MMI_HILOGD("Get keyboard type results from the configuration file:%{public}d", keyboardType);
189 return true;
190 }
191
GetKeyboardBusMode(int32_t deviceId)192 int32_t InputDeviceManager::GetKeyboardBusMode(int32_t deviceId)
193 {
194 CALL_DEBUG_ENTER;
195 std::shared_ptr dev = GetInputDevice(deviceId);
196 CHKPR(dev, ERROR_NULL_POINTER);
197 return dev->GetBus();
198 }
199
GetDeviceSupportKey(int32_t deviceId,int32_t & keyboardType)200 int32_t InputDeviceManager::GetDeviceSupportKey(int32_t deviceId, int32_t &keyboardType)
201 {
202 CALL_DEBUG_ENTER;
203 std::vector<int32_t> keyCodes;
204 keyCodes.push_back(KeyEvent::KEYCODE_Q);
205 keyCodes.push_back(KeyEvent::KEYCODE_NUMPAD_1);
206 keyCodes.push_back(KeyEvent::KEYCODE_HOME);
207 keyCodes.push_back(KeyEvent::KEYCODE_CTRL_LEFT);
208 keyCodes.push_back(KeyEvent::KEYCODE_SHIFT_RIGHT);
209 keyCodes.push_back(KeyEvent::KEYCODE_F20);
210 std::vector<bool> supportKey;
211 int32_t ret = SupportKeys(deviceId, keyCodes, supportKey);
212 if (ret != RET_OK) {
213 MMI_HILOGE("SupportKey call failed");
214 return ret;
215 }
216 std::map<int32_t, bool> determineKbType;
217 for (size_t i = 0; i < keyCodes.size(); i++) {
218 determineKbType[keyCodes[i]] = supportKey[i];
219 }
220 if (determineKbType[KeyEvent::KEYCODE_HOME] && GetKeyboardBusMode(deviceId) == BUS_BLUETOOTH) {
221 keyboardType = KEYBOARD_TYPE_REMOTECONTROL;
222 MMI_HILOGD("The keyboard type is remote control:%{public}d", keyboardType);
223 } else if (determineKbType[KeyEvent::KEYCODE_NUMPAD_1] && !determineKbType[KeyEvent::KEYCODE_Q]) {
224 keyboardType = KEYBOARD_TYPE_DIGITALKEYBOARD;
225 MMI_HILOGD("The keyboard type is digital keyboard:%{public}d", keyboardType);
226 } else if (determineKbType[KeyEvent::KEYCODE_Q]) {
227 keyboardType = KEYBOARD_TYPE_ALPHABETICKEYBOARD;
228 MMI_HILOGD("The keyboard type is standard:%{public}d", keyboardType);
229 } else if (determineKbType[KeyEvent::KEYCODE_CTRL_LEFT] && determineKbType[KeyEvent::KEYCODE_SHIFT_RIGHT] &&
230 determineKbType[KeyEvent::KEYCODE_F20]) {
231 keyboardType = KEYBOARD_TYPE_HANDWRITINGPEN;
232 MMI_HILOGD("The keyboard type is handwriting pen:%{public}d", keyboardType);
233 } else {
234 keyboardType = KEYBOARD_TYPE_UNKNOWN;
235 MMI_HILOGW("Undefined keyboard type");
236 }
237 MMI_HILOGD("Get keyboard type results by supporting keys:%{public}d", keyboardType);
238 return RET_OK;
239 }
240
GetKeyboardType(int32_t deviceId,int32_t & keyboardType)241 int32_t InputDeviceManager::GetKeyboardType(int32_t deviceId, int32_t &keyboardType)
242 {
243 CALL_DEBUG_ENTER;
244 int32_t tempKeyboardType = KEYBOARD_TYPE_NONE;
245 auto iter = inputDevice_.find(deviceId);
246 if (iter == inputDevice_.end()) {
247 MMI_HILOGE("Failed to search for the deviceID");
248 return COMMON_PARAMETER_ERROR;
249 }
250 if (!iter->second.enable) {
251 MMI_HILOGE("The current device has been disabled");
252 return RET_ERR;
253 }
254 if (GetDeviceConfig(deviceId, tempKeyboardType)) {
255 keyboardType = tempKeyboardType;
256 return RET_OK;
257 }
258 return GetDeviceSupportKey(deviceId, keyboardType);
259 }
260
SetInputStatusChangeCallback(inputDeviceCallback callback)261 void InputDeviceManager::SetInputStatusChangeCallback(inputDeviceCallback callback)
262 {
263 CALL_DEBUG_ENTER;
264 devCallbacks_ = callback;
265 }
266
AddDevListener(SessionPtr sess,std::function<void (int32_t,const std::string &)> callback)267 void InputDeviceManager::AddDevListener(SessionPtr sess, std::function<void(int32_t, const std::string &)> callback)
268 {
269 CALL_DEBUG_ENTER;
270 auto ret = devListener_.insert({ sess, callback });
271 if (!ret.second) {
272 MMI_HILOGE("Session is duplicated");
273 return;
274 }
275 }
276
RemoveDevListener(SessionPtr sess)277 void InputDeviceManager::RemoveDevListener(SessionPtr sess)
278 {
279 CALL_DEBUG_ENTER;
280 auto iter = devListener_.find(sess);
281 if (iter == devListener_.end()) {
282 MMI_HILOGE("Session does not exist");
283 return;
284 }
285 devListener_.erase(iter);
286 }
287
288 #ifdef OHOS_BUILD_ENABLE_POINTER_DRAWING
HasPointerDevice()289 bool InputDeviceManager::HasPointerDevice()
290 {
291 for (auto it = inputDevice_.begin(); it != inputDevice_.end(); ++it) {
292 if (it->second.isPointerDevice) {
293 return true;
294 }
295 }
296 return false;
297 }
298 #endif // OHOS_BUILD_ENABLE_POINTER_DRAWING
299
HasTouchDevice()300 bool InputDeviceManager::HasTouchDevice()
301 {
302 CALL_DEBUG_ENTER;
303 for (auto it = inputDevice_.begin(); it != inputDevice_.end(); ++it) {
304 if (it->second.isTouchableDevice) {
305 return true;
306 }
307 }
308 return false;
309 }
310
GetInputIdentification(struct libinput_device * inputDevice)311 std::string InputDeviceManager::GetInputIdentification(struct libinput_device *inputDevice)
312 {
313 CALL_DEBUG_ENTER;
314 int32_t deviceVendor = libinput_device_get_id_vendor(inputDevice);
315 int32_t deviceProduct = libinput_device_get_id_product(inputDevice);
316 struct udev_device *udevDevice = libinput_device_get_udev_device(inputDevice);
317 std::string sysPath = udev_device_get_syspath(udevDevice);
318 if ((deviceVendor < 0) || (deviceProduct < 0) || sysPath.empty()) {
319 MMI_HILOGE("Get device identification failed");
320 return "";
321 }
322 const size_t bufSize = 10;
323 char vid[bufSize] = "";
324 char pid[bufSize] = "";
325 sprintf_s(vid, sizeof(vid), "%04X", deviceVendor);
326 sprintf_s(pid, sizeof(pid), "%04X", deviceProduct);
327 std::string strVid(vid);
328 std::string strPid(pid);
329 std::string vendorProduct = strVid + ":" + strPid;
330 std::string deviceIdentification = sysPath.substr(0, sysPath.find(vendorProduct)) + vendorProduct;
331 MMI_HILOGI("Device identification is:%{public}s", deviceIdentification.c_str());
332 return deviceIdentification;
333 }
334
NotifyDevCallback(int32_t deviceId,struct InputDeviceInfo inDevice)335 void InputDeviceManager::NotifyDevCallback(int32_t deviceId, struct InputDeviceInfo inDevice)
336 {
337 if (!inDevice.isTouchableDevice || (deviceId < 0)) {
338 MMI_HILOGI("The device is not touchable device already existent");
339 return;
340 }
341 if (!inDevice.sysUid.empty()) {
342 devCallbacks_(deviceId, inDevice.sysUid, "add");
343 MMI_HILOGI("Send device info to window manager, device id:%{public}d, system uid:%{public}s, status:add",
344 deviceId, inDevice.sysUid.c_str());
345 } else {
346 MMI_HILOGE("Get device system uid id is empty, deviceId:%{public}d", deviceId);
347 }
348 }
349
ParseDeviceId(const std::string & sysName)350 int32_t InputDeviceManager::ParseDeviceId(const std::string &sysName)
351 {
352 CALL_DEBUG_ENTER;
353 std::regex pattern("^event(\\d+)$");
354 std::smatch mr;
355
356 if (std::regex_match(sysName, mr, pattern)) {
357 if (mr.ready() && mr.size() == EXPECTED_N_SUBMATCHES) {
358 return std::stoi(mr[EXPECTED_SUBMATCH].str());
359 }
360 }
361 return -1;
362 }
363
OnInputDeviceAdded(struct libinput_device * inputDevice)364 void InputDeviceManager::OnInputDeviceAdded(struct libinput_device *inputDevice)
365 {
366 CALL_DEBUG_ENTER;
367 CHKPV(inputDevice);
368 bool hasPointer = false;
369 for (const auto &item : inputDevice_) {
370 if (item.second.inputDeviceOrigin == inputDevice) {
371 MMI_HILOGI("The device is already existent");
372 DfxHisysevent::OnDeviceConnect(item.first, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT);
373 return;
374 }
375 if ((!item.second.isRemote && item.second.isPointerDevice) ||
376 (item.second.isRemote && item.second.isPointerDevice && item.second.enable)) {
377 hasPointer = true;
378 }
379 }
380 const char *sysName = libinput_device_get_sysname(inputDevice);
381 CHKPV(sysName);
382 int32_t deviceId = ParseDeviceId(std::string(sysName));
383 if (deviceId < 0) {
384 MMI_HILOGE("Parsing sysname failed: \'%{public}s\'", sysName);
385 return;
386 }
387 struct InputDeviceInfo info;
388 MakeDeviceInfo(inputDevice, info);
389 inputDevice_[deviceId] = info;
390 if (info.enable) {
391 for (const auto &item : devListener_) {
392 CHKPC(item.first);
393 item.second(deviceId, "add");
394 }
395 }
396 NotifyDevCallback(deviceId, info);
397 if (!hasPointer && info.isPointerDevice) {
398 #ifdef OHOS_BUILD_ENABLE_POINTER_DRAWING
399 if (HasTouchDevice()) {
400 IPointerDrawingManager::GetInstance()->SetMouseDisplayState(false);
401 }
402 #endif // OHOS_BUILD_ENABLE_POINTER_DRAWING
403 NotifyPointerDevice(true, true);
404 OHOS::system::SetParameter(INPUT_POINTER_DEVICE, "true");
405 MMI_HILOGI("Set para input.pointer.device true");
406 }
407 #ifdef OHOS_BUILD_ENABLE_POINTER_DRAWING
408 if (IsPointerDevice(inputDevice) && !HasPointerDevice() &&
409 IPointerDrawingManager::GetInstance()->GetMouseDisplayState()) {
410 #ifdef OHOS_BUILD_ENABLE_POINTER
411 WinMgr->DispatchPointer(PointerEvent::POINTER_ACTION_ENTER_WINDOW);
412 #endif // OHOS_BUILD_ENABLE_POINTER
413 }
414 #endif // OHOS_BUILD_ENABLE_POINTER_DRAWING
415 DfxHisysevent::OnDeviceConnect(deviceId, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR);
416 }
417
MakeDeviceInfo(struct libinput_device * inputDevice,struct InputDeviceInfo & info)418 void InputDeviceManager::MakeDeviceInfo(struct libinput_device *inputDevice, struct InputDeviceInfo &info)
419 {
420 info.inputDeviceOrigin = inputDevice;
421 info.isRemote = IsRemote(inputDevice);
422 info.enable = info.isRemote ? false : true;
423 info.isPointerDevice = IsPointerDevice(inputDevice);
424 info.isTouchableDevice = IsTouchDevice(inputDevice);
425 info.sysUid = GetInputIdentification(inputDevice);
426 info.vendorConfig = configManagement_.GetVendorConfig(inputDevice);
427 }
428
OnInputDeviceRemoved(struct libinput_device * inputDevice)429 void InputDeviceManager::OnInputDeviceRemoved(struct libinput_device *inputDevice)
430 {
431 CALL_DEBUG_ENTER;
432 CHKPV(inputDevice);
433 int32_t deviceId = INVALID_DEVICE_ID;
434 bool enable = false;
435 for (auto it = inputDevice_.begin(); it != inputDevice_.end(); ++it) {
436 if (it->second.inputDeviceOrigin == inputDevice) {
437 deviceId = it->first;
438 enable = it->second.enable;
439 DfxHisysevent::OnDeviceDisconnect(deviceId, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR);
440 inputDevice_.erase(it);
441 break;
442 }
443 }
444 std::string sysUid = GetInputIdentification(inputDevice);
445 if (!sysUid.empty()) {
446 devCallbacks_(deviceId, sysUid, "remove");
447 MMI_HILOGI("Send device info to window manager, device id:%{public}d, system uid:%{public}s, status:remove",
448 deviceId, sysUid.c_str());
449 }
450
451 #ifdef OHOS_BUILD_ENABLE_POINTER_DRAWING
452 if (IsPointerDevice(inputDevice) && !HasPointerDevice() &&
453 IPointerDrawingManager::GetInstance()->GetMouseDisplayState()) {
454 #ifdef OHOS_BUILD_ENABLE_POINTER
455 WinMgr->DispatchPointer(PointerEvent::POINTER_ACTION_LEAVE_WINDOW);
456 #endif // OHOS_BUILD_ENABLE_POINTER
457 }
458 #endif // OHOS_BUILD_ENABLE_POINTER_DRAWING
459 if (enable) {
460 for (const auto &item : devListener_) {
461 CHKPC(item.first);
462 item.second(deviceId, "remove");
463 }
464 }
465 ScanPointerDevice();
466 if (deviceId == INVALID_DEVICE_ID) {
467 DfxHisysevent::OnDeviceDisconnect(INVALID_DEVICE_ID, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT);
468 }
469 }
470
ScanPointerDevice()471 void InputDeviceManager::ScanPointerDevice()
472 {
473 bool hasPointerDevice = false;
474 for (auto it = inputDevice_.begin(); it != inputDevice_.end(); ++it) {
475 if (it->second.isPointerDevice) {
476 hasPointerDevice = true;
477 break;
478 }
479 }
480 if (!hasPointerDevice) {
481 NotifyPointerDevice(false, false);
482 OHOS::system::SetParameter(INPUT_POINTER_DEVICE, "false");
483 MMI_HILOGI("Set para input.pointer.device false");
484 }
485 }
486
IsPointerDevice(struct libinput_device * device) const487 bool InputDeviceManager::IsPointerDevice(struct libinput_device *device) const
488 {
489 CHKPF(device);
490 enum evdev_device_udev_tags udevTags = libinput_device_get_tags(device);
491 MMI_HILOGD("The current device udev tag:%{public}d", static_cast<int32_t>(udevTags));
492 return (udevTags & (EVDEV_UDEV_TAG_MOUSE | EVDEV_UDEV_TAG_TRACKBALL | EVDEV_UDEV_TAG_POINTINGSTICK |
493 EVDEV_UDEV_TAG_TOUCHPAD | EVDEV_UDEV_TAG_TABLET_PAD)) != 0;
494 }
495
IsKeyboardDevice(struct libinput_device * device) const496 bool InputDeviceManager::IsKeyboardDevice(struct libinput_device *device) const
497 {
498 CHKPF(device);
499 enum evdev_device_udev_tags udevTags = libinput_device_get_tags(device);
500 MMI_HILOGD("The current device udev tag:%{public}d", static_cast<int32_t>(udevTags));
501 return udevTags & EVDEV_UDEV_TAG_KEYBOARD;
502 }
503
IsTouchDevice(struct libinput_device * device) const504 bool InputDeviceManager::IsTouchDevice(struct libinput_device *device) const
505 {
506 CHKPF(device);
507 return libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TOUCH);
508 }
509
Attach(std::shared_ptr<IDeviceObserver> observer)510 void InputDeviceManager::Attach(std::shared_ptr<IDeviceObserver> observer)
511 {
512 CALL_DEBUG_ENTER;
513 observers_.push_back(observer);
514 }
515
Detach(std::shared_ptr<IDeviceObserver> observer)516 void InputDeviceManager::Detach(std::shared_ptr<IDeviceObserver> observer)
517 {
518 CALL_DEBUG_ENTER;
519 observers_.remove(observer);
520 }
521
NotifyPointerDevice(bool hasPointerDevice,bool isVisible)522 void InputDeviceManager::NotifyPointerDevice(bool hasPointerDevice, bool isVisible)
523 {
524 MMI_HILOGI("observers_ size:%{public}zu", observers_.size());
525 for (auto observer = observers_.begin(); observer != observers_.end(); observer++) {
526 (*observer)->UpdatePointerDevice(hasPointerDevice, isVisible);
527 }
528 }
529
FindInputDeviceId(struct libinput_device * inputDevice)530 int32_t InputDeviceManager::FindInputDeviceId(struct libinput_device *inputDevice)
531 {
532 CALL_DEBUG_ENTER;
533 CHKPR(inputDevice, INVALID_DEVICE_ID);
534 for (const auto &item : inputDevice_) {
535 if (item.second.inputDeviceOrigin == inputDevice) {
536 MMI_HILOGD("Find input device id success");
537 return item.first;
538 }
539 }
540 MMI_HILOGE("Find input device id failed");
541 return INVALID_DEVICE_ID;
542 }
543
GetKeyboardDevice() const544 struct libinput_device *InputDeviceManager::GetKeyboardDevice() const
545 {
546 CALL_DEBUG_ENTER;
547 std::vector<int32_t> keyCodes;
548 keyCodes.push_back(KeyEvent::KEYCODE_Q);
549 keyCodes.push_back(KeyEvent::KEYCODE_NUMPAD_1);
550 for (const auto &item : inputDevice_) {
551 const auto &device = item.second.inputDeviceOrigin;
552 if (IsMatchKeys(device, keyCodes)) {
553 MMI_HILOGI("Find keyboard device success");
554 return device;
555 }
556 }
557 MMI_HILOGW("No keyboard device is currently available");
558 return nullptr;
559 }
560
Dump(int32_t fd,const std::vector<std::string> & args)561 void InputDeviceManager::Dump(int32_t fd, const std::vector<std::string> &args)
562 {
563 CALL_DEBUG_ENTER;
564 mprintf(fd, "Device information:\t");
565 mprintf(fd, "Input devices: count=%d", inputDevice_.size());
566 for (const auto &item : inputDevice_) {
567 std::shared_ptr<InputDevice> inputDevice = GetInputDevice(item.first, false);
568 CHKPV(inputDevice);
569 mprintf(fd,
570 "deviceId:%d | deviceName:%s | deviceType:%d | bus:%d | version:%d "
571 "| product:%d | vendor:%d | phys:%s\t",
572 inputDevice->GetId(), inputDevice->GetName().c_str(), inputDevice->GetType(), inputDevice->GetBus(),
573 inputDevice->GetVersion(), inputDevice->GetProduct(), inputDevice->GetVendor(),
574 inputDevice->GetPhys().c_str());
575 std::vector<InputDevice::AxisInfo> axisinfo = inputDevice->GetAxisInfo();
576 mprintf(fd, "axis: count=%d", axisinfo.size());
577 for (const auto &axis : axisinfo) {
578 auto iter = axisType.find(axis.GetAxisType());
579 if (iter == axisType.end()) {
580 MMI_HILOGE("The axisType is not found");
581 return;
582 }
583 mprintf(fd, "\t axisType:%s | minimum:%d | maximum:%d | fuzz:%d | flat:%d | resolution:%d\t",
584 iter->second.c_str(), axis.GetMinimum(), axis.GetMaximum(), axis.GetFuzz(), axis.GetFlat(),
585 axis.GetResolution());
586 }
587 }
588 }
589
DumpDeviceList(int32_t fd,const std::vector<std::string> & args)590 void InputDeviceManager::DumpDeviceList(int32_t fd, const std::vector<std::string> &args)
591 {
592 CALL_DEBUG_ENTER;
593 std::vector<int32_t> ids = GetInputDeviceIds();
594 mprintf(fd, "Total device:%d, Device list:\t", int32_t{ ids.size() });
595 for (const auto &item : inputDevice_) {
596 std::shared_ptr<InputDevice> inputDevice = GetInputDevice(item.first, false);
597 CHKPV(inputDevice);
598 int32_t deviceId = inputDevice->GetId();
599 mprintf(fd, "deviceId:%d | deviceName:%s | deviceType:%d | bus:%d | version:%d | product:%d | vendor:%d\t",
600 deviceId, inputDevice->GetName().c_str(), inputDevice->GetType(), inputDevice->GetBus(),
601 inputDevice->GetVersion(), inputDevice->GetProduct(), inputDevice->GetVendor());
602 }
603 }
604
IsRemote(struct libinput_device * inputDevice) const605 bool InputDeviceManager::IsRemote(struct libinput_device *inputDevice) const
606 {
607 CHKPF(inputDevice);
608 bool isRemote = false;
609 const char *name = libinput_device_get_name(inputDevice);
610 if (name == nullptr || name[0] == '\0') {
611 MMI_HILOGD("Device name is empty");
612 return false;
613 }
614 std::string strName = name;
615 std::string::size_type pos = strName.find(INPUT_VIRTUAL_DEVICE_NAME);
616 if (pos != std::string::npos) {
617 isRemote = true;
618 }
619 MMI_HILOGD("isRemote:%{public}s", isRemote ? "true" : "false");
620 return isRemote;
621 }
622
IsRemote(int32_t id) const623 bool InputDeviceManager::IsRemote(int32_t id) const
624 {
625 bool isRemote = false;
626 auto device = inputDevice_.find(id);
627 if (device != inputDevice_.end()) {
628 isRemote = device->second.isRemote;
629 }
630 MMI_HILOGD("isRemote:%{public}s", isRemote ? "true" : "false");
631 return isRemote;
632 }
633
GetVendorConfig(int32_t deviceId) const634 VendorConfig InputDeviceManager::GetVendorConfig(int32_t deviceId) const
635 {
636 CALL_DEBUG_ENTER;
637 auto it = inputDevice_.find(deviceId);
638 if (it == inputDevice_.end()) {
639 MMI_HILOGE("Device info not find id: %{public}d", deviceId);
640 return {};
641 }
642 return it->second.vendorConfig;
643 }
644
OnEnableInputDevice(bool enable)645 int32_t InputDeviceManager::OnEnableInputDevice(bool enable)
646 {
647 CALL_DEBUG_ENTER;
648 MMI_HILOGD("Enable input device: %{public}s", enable ? "true" : "false");
649 for (auto &item : inputDevice_) {
650 if (item.second.isRemote && item.second.enable != enable) {
651 int32_t keyboardType = KEYBOARD_TYPE_NONE;
652 if (enable) {
653 item.second.enable = enable;
654 GetKeyboardType(item.first, keyboardType);
655 } else {
656 GetKeyboardType(item.first, keyboardType);
657 item.second.enable = enable;
658 }
659 if (keyboardType != KEYBOARD_TYPE_ALPHABETICKEYBOARD) {
660 continue;
661 }
662 for (const auto &listener : devListener_) {
663 CHKPC(listener.first);
664 listener.second(item.first, enable ? "add" : "remove");
665 }
666 }
667 }
668 return RET_OK;
669 }
670 } // namespace MMI
671 } // namespace OHOS
672