• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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