• 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_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