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