• 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 "i_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 
36 #undef MMI_LOG_DOMAIN
37 #define MMI_LOG_DOMAIN MMI_LOG_SERVER
38 #undef MMI_LOG_TAG
39 #define MMI_LOG_TAG "InputDeviceManager"
40 
41 namespace OHOS {
42 namespace MMI {
43 namespace {
44 constexpr int32_t INVALID_DEVICE_ID { -1 };
45 constexpr int32_t SUPPORT_KEY { 1 };
46 const std::string UNKNOWN_SCREEN_ID { "" };
47 const std::string INPUT_VIRTUAL_DEVICE_NAME { "DistributedInput " };
48 constexpr int32_t MIN_VIRTUAL_INPUT_DEVICE_ID { 1000 };
49 constexpr int32_t MAX_VIRTUAL_INPUT_DEVICE_NUM { 128 };
50 constexpr int32_t COMMON_PARAMETER_ERROR { 401 };
51 
52 std::unordered_map<int32_t, std::string> axisType{
53     { ABS_MT_TOUCH_MAJOR, "TOUCH_MAJOR" }, { ABS_MT_TOUCH_MINOR, "TOUCH_MINOR" }, { ABS_MT_ORIENTATION, "ORIENTATION" },
54     { ABS_MT_POSITION_X, "POSITION_X" },   { ABS_MT_POSITION_Y, "POSITION_Y" },   { ABS_MT_PRESSURE, "PRESSURE" },
55     { ABS_MT_WIDTH_MAJOR, "WIDTH_MAJOR" }, { ABS_MT_WIDTH_MINOR, "WIDTH_MINOR" }
56 };
57 
58 std::vector<std::pair<enum libinput_device_capability, InputDeviceCapability>> devCapEnumMaps{
59     { LIBINPUT_DEVICE_CAP_KEYBOARD, InputDeviceCapability::INPUT_DEV_CAP_KEYBOARD },
60     { LIBINPUT_DEVICE_CAP_POINTER, InputDeviceCapability::INPUT_DEV_CAP_POINTER },
61     { LIBINPUT_DEVICE_CAP_TOUCH, InputDeviceCapability::INPUT_DEV_CAP_TOUCH },
62     { LIBINPUT_DEVICE_CAP_TABLET_TOOL, InputDeviceCapability::INPUT_DEV_CAP_TABLET_TOOL },
63     { LIBINPUT_DEVICE_CAP_TABLET_PAD, InputDeviceCapability::INPUT_DEV_CAP_TABLET_PAD },
64     { LIBINPUT_DEVICE_CAP_GESTURE, InputDeviceCapability::INPUT_DEV_CAP_GESTURE },
65     { LIBINPUT_DEVICE_CAP_SWITCH, InputDeviceCapability::INPUT_DEV_CAP_SWITCH },
66     { LIBINPUT_DEVICE_CAP_JOYSTICK, InputDeviceCapability::INPUT_DEV_CAP_JOYSTICK },
67 };
68 
69 constexpr size_t EXPECTED_N_SUBMATCHES{ 2 };
70 constexpr size_t EXPECTED_SUBMATCH{ 1 };
71 constexpr size_t RESERVE_LEN { 5 };
72 } // namespace
73 
74 std::shared_ptr<InputDeviceManager> InputDeviceManager::instance_ = nullptr;
75 std::mutex InputDeviceManager::mutex_;
76 
GetInstance()77 std::shared_ptr<InputDeviceManager> InputDeviceManager::GetInstance()
78 {
79     if (instance_ == nullptr) {
80         std::lock_guard<std::mutex> lock(mutex_);
81         if (instance_ == nullptr) {
82             instance_ = std::make_shared<InputDeviceManager>();
83         }
84     }
85     return instance_;
86 }
87 
GetInputDevice(int32_t deviceId,bool checked) const88 std::shared_ptr<InputDevice> InputDeviceManager::GetInputDevice(int32_t deviceId, bool checked) const
89 {
90     CALL_DEBUG_ENTER;
91     if (virtualInputDevices_.find(deviceId) != virtualInputDevices_.end()) {
92         MMI_HILOGI("Virtual device with id:%{public}d", deviceId);
93         std::shared_ptr<InputDevice> dev = virtualInputDevices_.at(deviceId);
94         CHKPP(dev);
95         MMI_HILOGI("DeviceId:%{public}d, name:%{public}s", dev->GetId(), dev->GetName().c_str());
96         return dev;
97     }
98     auto iter = inputDevice_.find(deviceId);
99     if (iter == inputDevice_.end()) {
100         MMI_HILOGE("Failed to search for the device");
101         return nullptr;
102     }
103     if (checked && !iter->second.enable) {
104         MMI_HILOGE("The current device has been disabled");
105         return nullptr;
106     }
107     std::shared_ptr<InputDevice> inputDevice = std::make_shared<InputDevice>();
108     inputDevice->SetId(iter->first);
109     struct libinput_device *inputDeviceOrigin = iter->second.inputDeviceOrigin;
110     FillInputDevice(inputDevice, inputDeviceOrigin);
111 
112     InputDevice::AxisInfo axis;
113     for (const auto &item : axisType) {
114         int32_t min = libinput_device_get_axis_min(inputDeviceOrigin, item.first);
115         if (min == -1) {
116             MMI_HILOGD("The device does not support this axis");
117             continue;
118         }
119         if (item.first == ABS_MT_PRESSURE) {
120             axis.SetMinimum(0);
121             axis.SetMaximum(1);
122         } else {
123             axis.SetMinimum(min);
124             axis.SetMaximum(libinput_device_get_axis_max(inputDeviceOrigin, item.first));
125         }
126         axis.SetAxisType(item.first);
127         axis.SetFuzz(libinput_device_get_axis_fuzz(inputDeviceOrigin, item.first));
128         axis.SetFlat(libinput_device_get_axis_flat(inputDeviceOrigin, item.first));
129         axis.SetResolution(libinput_device_get_axis_resolution(inputDeviceOrigin, item.first));
130         inputDevice->AddAxisInfo(axis);
131     }
132     return inputDevice;
133 }
134 
FillInputDevice(std::shared_ptr<InputDevice> inputDevice,libinput_device * deviceOrigin) const135 void InputDeviceManager::FillInputDevice(std::shared_ptr<InputDevice> inputDevice, libinput_device *deviceOrigin) const
136 {
137     CHKPV(inputDevice);
138     CHKPV(deviceOrigin);
139     inputDevice->SetType(static_cast<int32_t>(libinput_device_get_tags(deviceOrigin)));
140     const char *name = libinput_device_get_name(deviceOrigin);
141     inputDevice->SetName((name == nullptr) ? ("null") : (name));
142     inputDevice->SetBus(libinput_device_get_id_bustype(deviceOrigin));
143     inputDevice->SetVersion(libinput_device_get_id_version(deviceOrigin));
144     inputDevice->SetProduct(libinput_device_get_id_product(deviceOrigin));
145     inputDevice->SetVendor(libinput_device_get_id_vendor(deviceOrigin));
146     const char *phys = libinput_device_get_phys(deviceOrigin);
147     inputDevice->SetPhys((phys == nullptr) ? ("null") : (phys));
148     const char *uniq = libinput_device_get_uniq(deviceOrigin);
149     inputDevice->SetUniq((uniq == nullptr) ? ("null") : (uniq));
150 
151     for (const auto &[first, second] : devCapEnumMaps) {
152         if (libinput_device_has_capability(deviceOrigin, first)) {
153             inputDevice->AddCapability(second);
154         }
155     }
156 }
157 
GetInputDeviceIds() const158 std::vector<int32_t> InputDeviceManager::GetInputDeviceIds() const
159 {
160     CALL_DEBUG_ENTER;
161     std::vector<int32_t> ids;
162     for (const auto &item : inputDevice_) {
163         if (!item.second.enable) {
164             MMI_HILOGD("The current device has been disabled");
165             continue;
166         }
167         ids.push_back(item.first);
168     }
169     for (const auto &item : virtualInputDevices_) {
170         ids.push_back(item.first);
171     }
172     return ids;
173 }
174 
SupportKeys(int32_t deviceId,std::vector<int32_t> & keyCodes,std::vector<bool> & keystroke)175 int32_t InputDeviceManager::SupportKeys(int32_t deviceId, std::vector<int32_t> &keyCodes, std::vector<bool> &keystroke)
176 {
177     CALL_DEBUG_ENTER;
178     auto iter = inputDevice_.find(deviceId);
179     if (iter == inputDevice_.end()) {
180         return COMMON_PARAMETER_ERROR;
181     }
182     if (!iter->second.enable) {
183         MMI_HILOGE("The current device has been disabled");
184         return RET_ERR;
185     }
186     for (const auto &item : keyCodes) {
187         bool ret = false;
188         for (const auto &it : KeyMapMgr->InputTransferKeyValue(deviceId, item)) {
189             ret |= libinput_device_has_key(iter->second.inputDeviceOrigin, it) == SUPPORT_KEY;
190         }
191         keystroke.push_back(ret);
192     }
193     return RET_OK;
194 }
195 
IsMatchKeys(struct libinput_device * device,const std::vector<int32_t> & keyCodes) const196 bool InputDeviceManager::IsMatchKeys(struct libinput_device *device, const std::vector<int32_t> &keyCodes) const
197 {
198     CHKPF(device);
199     for (const auto &key : keyCodes) {
200         int32_t value = InputTransformationKeyValue(key);
201         if (libinput_device_keyboard_has_key(device, value) == SUPPORT_KEY) {
202             return true;
203         }
204     }
205     return false;
206 }
207 
GetDeviceConfig(int32_t deviceId,int32_t & keyboardType)208 bool InputDeviceManager::GetDeviceConfig(int32_t deviceId, int32_t &keyboardType)
209 {
210     CALL_DEBUG_ENTER;
211     if (auto iter = inputDevice_.find(deviceId); iter == inputDevice_.end()) {
212         MMI_HILOGE("Failed to search for the deviceID");
213         return false;
214     }
215     auto deviceConfig = KeyRepeat->GetDeviceConfig();
216     auto it = deviceConfig.find(deviceId);
217     if (it == deviceConfig.end()) {
218         MMI_HILOGD("Failed to obtain the keyboard type of the configuration file");
219         return false;
220     }
221     keyboardType = it->second.keyboardType;
222     MMI_HILOGD("Get keyboard type results from the configuration file:%{public}d", keyboardType);
223     return true;
224 }
225 
GetKeyboardBusMode(int32_t deviceId)226 int32_t InputDeviceManager::GetKeyboardBusMode(int32_t deviceId)
227 {
228     CALL_DEBUG_ENTER;
229     std::shared_ptr dev = GetInputDevice(deviceId);
230     CHKPR(dev, ERROR_NULL_POINTER);
231     return dev->GetBus();
232 }
233 
GetDeviceSupportKey(int32_t deviceId,int32_t & keyboardType)234 int32_t InputDeviceManager::GetDeviceSupportKey(int32_t deviceId, int32_t &keyboardType)
235 {
236     CALL_DEBUG_ENTER;
237     std::vector<int32_t> keyCodes;
238     keyCodes.push_back(KeyEvent::KEYCODE_Q);
239     keyCodes.push_back(KeyEvent::KEYCODE_NUMPAD_1);
240     keyCodes.push_back(KeyEvent::KEYCODE_HOME);
241     keyCodes.push_back(KeyEvent::KEYCODE_CTRL_LEFT);
242     keyCodes.push_back(KeyEvent::KEYCODE_SHIFT_RIGHT);
243     keyCodes.push_back(KeyEvent::KEYCODE_F20);
244     std::vector<bool> supportKey;
245     int32_t ret = SupportKeys(deviceId, keyCodes, supportKey);
246     if (ret != RET_OK) {
247         MMI_HILOGE("SupportKey call failed");
248         return ret;
249     }
250     std::map<int32_t, bool> determineKbType;
251     for (size_t i = 0; i < keyCodes.size(); i++) {
252         determineKbType[keyCodes[i]] = supportKey[i];
253     }
254     if (determineKbType[KeyEvent::KEYCODE_HOME] && GetKeyboardBusMode(deviceId) == BUS_BLUETOOTH) {
255         keyboardType = KEYBOARD_TYPE_REMOTECONTROL;
256         MMI_HILOGD("The keyboard type is remote control:%{public}d", keyboardType);
257     } else if (determineKbType[KeyEvent::KEYCODE_NUMPAD_1] && !determineKbType[KeyEvent::KEYCODE_Q]) {
258         keyboardType = KEYBOARD_TYPE_DIGITALKEYBOARD;
259         MMI_HILOGD("The keyboard type is digital keyboard:%{public}d", keyboardType);
260     } else if (determineKbType[KeyEvent::KEYCODE_Q]) {
261         keyboardType = KEYBOARD_TYPE_ALPHABETICKEYBOARD;
262         MMI_HILOGD("The keyboard type is standard:%{public}d", keyboardType);
263     } else if (determineKbType[KeyEvent::KEYCODE_CTRL_LEFT] && determineKbType[KeyEvent::KEYCODE_SHIFT_RIGHT] &&
264         determineKbType[KeyEvent::KEYCODE_F20]) {
265         keyboardType = KEYBOARD_TYPE_HANDWRITINGPEN;
266         MMI_HILOGD("The keyboard type is handwriting pen:%{public}d", keyboardType);
267     } else {
268         keyboardType = KEYBOARD_TYPE_UNKNOWN;
269         MMI_HILOGD("Undefined keyboard type");
270     }
271     MMI_HILOGD("Get keyboard type results by supporting keys:%{public}d", keyboardType);
272     return RET_OK;
273 }
274 
GetKeyboardType(int32_t deviceId,int32_t & keyboardType)275 int32_t InputDeviceManager::GetKeyboardType(int32_t deviceId, int32_t &keyboardType)
276 {
277     CALL_DEBUG_ENTER;
278     auto item = virtualInputDevices_.find(deviceId);
279     if (item != virtualInputDevices_.end()) {
280         if (!IsKeyboardDevice(item->second)) {
281             MMI_HILOGW("Virtual device with id:%{public}d is not keyboard", deviceId);
282             keyboardType = KEYBOARD_TYPE_NONE;
283             return RET_OK;
284         }
285         MMI_HILOGI("Virtual device with id:%{public}d, only KEYBOARD_TYPE_ALPHABETICKEYBOARD supported", deviceId);
286         keyboardType = KEYBOARD_TYPE_ALPHABETICKEYBOARD;
287         return RET_OK;
288     }
289     int32_t tempKeyboardType = KEYBOARD_TYPE_NONE;
290     auto iter = inputDevice_.find(deviceId);
291     if (iter == inputDevice_.end()) {
292         MMI_HILOGD("Failed to search for the deviceID");
293         return COMMON_PARAMETER_ERROR;
294     }
295     if (!iter->second.enable) {
296         MMI_HILOGE("The current device has been disabled");
297         return RET_ERR;
298     }
299     if (GetDeviceConfig(deviceId, tempKeyboardType)) {
300         keyboardType = tempKeyboardType;
301         return RET_OK;
302     }
303     return GetDeviceSupportKey(deviceId, keyboardType);
304 }
305 
SetInputStatusChangeCallback(inputDeviceCallback callback)306 void InputDeviceManager::SetInputStatusChangeCallback(inputDeviceCallback callback)
307 {
308     CALL_DEBUG_ENTER;
309     devCallbacks_ = callback;
310 }
311 
AddDevListener(SessionPtr sess)312 void InputDeviceManager::AddDevListener(SessionPtr sess)
313 {
314     CALL_DEBUG_ENTER;
315     InitSessionLostCallback();
316     devListeners_.push_back(sess);
317 }
318 
RemoveDevListener(SessionPtr sess)319 void InputDeviceManager::RemoveDevListener(SessionPtr sess)
320 {
321     CALL_DEBUG_ENTER;
322     devListeners_.remove(sess);
323 }
324 
325 #ifdef OHOS_BUILD_ENABLE_POINTER_DRAWING
HasPointerDevice()326 bool InputDeviceManager::HasPointerDevice()
327 {
328     for (auto it = inputDevice_.begin(); it != inputDevice_.end(); ++it) {
329         if (it->second.isPointerDevice) {
330             return true;
331         }
332     }
333     return false;
334 }
335 #endif // OHOS_BUILD_ENABLE_POINTER_DRAWING
336 
HasTouchDevice()337 bool InputDeviceManager::HasTouchDevice()
338 {
339     CALL_DEBUG_ENTER;
340     for (auto it = inputDevice_.begin(); it != inputDevice_.end(); ++it) {
341         if (it->second.isTouchableDevice) {
342             return true;
343         }
344     }
345     return false;
346 }
347 
GetInputIdentification(struct libinput_device * inputDevice)348 std::string InputDeviceManager::GetInputIdentification(struct libinput_device *inputDevice)
349 {
350     CALL_DEBUG_ENTER;
351     int32_t deviceVendor = libinput_device_get_id_vendor(inputDevice);
352     int32_t deviceProduct = libinput_device_get_id_product(inputDevice);
353     struct udev_device *udevDevice = libinput_device_get_udev_device(inputDevice);
354     std::string sysPath = udev_device_get_syspath(udevDevice);
355     udev_device_unref(udevDevice);
356     if ((deviceVendor < 0) || (deviceProduct < 0) || sysPath.empty()) {
357         MMI_HILOGE("Get device identification failed");
358         return "";
359     }
360     const size_t bufSize = 10;
361     char vid[bufSize] = "";
362     char pid[bufSize] = "";
363     sprintf_s(vid, sizeof(vid), "%04X", deviceVendor);
364     sprintf_s(pid, sizeof(pid), "%04X", deviceProduct);
365     std::string strVid(vid);
366     std::string strPid(pid);
367     std::string vendorProduct = strVid + ":" + strPid;
368     std::string deviceIdentification = sysPath.substr(0, sysPath.find(vendorProduct)) + vendorProduct;
369     MMI_HILOGI("Device identification is:%{public}s", deviceIdentification.c_str());
370     return deviceIdentification;
371 }
372 
NotifyDevCallback(int32_t deviceId,struct InputDeviceInfo inDevice)373 void InputDeviceManager::NotifyDevCallback(int32_t deviceId, struct InputDeviceInfo inDevice)
374 {
375     if (!inDevice.isTouchableDevice || (deviceId < 0)) {
376         MMI_HILOGI("The device is not touchable device already existent");
377         return;
378     }
379     if (!inDevice.sysUid.empty()) {
380         devCallbacks_(deviceId, inDevice.sysUid, "add");
381         MMI_HILOGI("Send device info to window manager, device id:%{public}d, system uid:%s, status:add",
382             deviceId, inDevice.sysUid.c_str());
383     } else {
384         MMI_HILOGE("Get device system uid id is empty, deviceId:%{public}d", deviceId);
385     }
386 }
387 
ParseDeviceId(struct libinput_device * inputDevice)388 int32_t InputDeviceManager::ParseDeviceId(struct libinput_device *inputDevice)
389 {
390     CALL_DEBUG_ENTER;
391     std::regex pattern("^event(\\d+)$");
392     std::smatch mr;
393     const char *sysName = libinput_device_get_sysname(inputDevice);
394     CHKPR(sysName, RET_ERR);
395     std::string strName(sysName);
396     if (std::regex_match(strName, mr, pattern)) {
397         if (mr.ready() && mr.size() == EXPECTED_N_SUBMATCHES) {
398             return std::stoi(mr[EXPECTED_SUBMATCH].str());
399         }
400     }
401     MMI_HILOGE("Parsing strName failed: \'%{public}s\'", strName.c_str());
402     return RET_ERR;
403 }
404 
OnInputDeviceAdded(struct libinput_device * inputDevice)405 void InputDeviceManager::OnInputDeviceAdded(struct libinput_device *inputDevice)
406 {
407     CALL_DEBUG_ENTER;
408     CHKPV(inputDevice);
409     bool hasPointer = false;
410     for (const auto &item : inputDevice_) {
411         if (item.second.inputDeviceOrigin == inputDevice) {
412             MMI_HILOGI("The device is already existent");
413             DfxHisysevent::OnDeviceConnect(item.first, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT);
414             return;
415         }
416         if ((!item.second.isRemote && item.second.isPointerDevice) ||
417             (item.second.isRemote && item.second.isPointerDevice && item.second.enable)) {
418             hasPointer = true;
419         }
420     }
421     int32_t deviceId = ParseDeviceId(inputDevice);
422     if (deviceId < 0) {
423         return;
424     }
425     struct InputDeviceInfo info;
426     MakeDeviceInfo(inputDevice, info);
427     inputDevice_[deviceId] = info;
428     MMI_HILOGI("Device added successfully, deviceId:%{public}s, system uid:%{private}s",
429         GetMaskedDeviceId(std::to_string(deviceId)).c_str(), info.sysUid.c_str());
430     if (info.enable) {
431         for (const auto& item : devListeners_) {
432             CHKPC(item);
433             NotifyMessage(item, deviceId, "add");
434         }
435     }
436     NotifyDevCallback(deviceId, info);
437     if (!hasPointer && info.isPointerDevice) {
438 #if defined(OHOS_BUILD_ENABLE_POINTER) && defined(OHOS_BUILD_ENABLE_POINTER_DRAWING)
439         if (HasTouchDevice()) {
440             IPointerDrawingManager::GetInstance()->SetMouseDisplayState(false);
441         }
442 #endif // OHOS_BUILD_ENABLE_POINTER && OHOS_BUILD_ENABLE_POINTER_DRAWING
443         NotifyPointerDevice(true, true, true);
444         OHOS::system::SetParameter(INPUT_POINTER_DEVICES, "true");
445         MMI_HILOGI("Set para input.pointer.device true");
446     }
447 #if defined(OHOS_BUILD_ENABLE_POINTER) && defined(OHOS_BUILD_ENABLE_POINTER_DRAWING)
448     if (IsPointerDevice(inputDevice)) {
449         WIN_MGR->UpdatePointerChangeAreas();
450     }
451     if (IsPointerDevice(inputDevice) && !HasPointerDevice() &&
452         IPointerDrawingManager::GetInstance()->GetMouseDisplayState()) {
453         WIN_MGR->DispatchPointer(PointerEvent::POINTER_ACTION_ENTER_WINDOW);
454     }
455 #endif // OHOS_BUILD_ENABLE_POINTER && OHOS_BUILD_ENABLE_POINTER_DRAWING
456     DfxHisysevent::OnDeviceConnect(deviceId, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR);
457 }
458 
MakeDeviceInfo(struct libinput_device * inputDevice,struct InputDeviceInfo & info)459 void InputDeviceManager::MakeDeviceInfo(struct libinput_device *inputDevice, struct InputDeviceInfo &info)
460 {
461     info.inputDeviceOrigin = inputDevice;
462     info.isRemote = IsRemote(inputDevice);
463     info.enable = info.isRemote ? false : true;
464     info.isPointerDevice = IsPointerDevice(inputDevice);
465     info.isTouchableDevice = IsTouchDevice(inputDevice);
466     info.sysUid = GetInputIdentification(inputDevice);
467     info.vendorConfig = configManagement_.GetVendorConfig(inputDevice);
468 }
469 
OnInputDeviceRemoved(struct libinput_device * inputDevice)470 void InputDeviceManager::OnInputDeviceRemoved(struct libinput_device *inputDevice)
471 {
472     CALL_DEBUG_ENTER;
473     CHKPV(inputDevice);
474     int32_t deviceId = INVALID_DEVICE_ID;
475     bool enable = false;
476     for (auto it = inputDevice_.begin(); it != inputDevice_.end(); ++it) {
477         if (it->second.inputDeviceOrigin == inputDevice) {
478             deviceId = it->first;
479             enable = it->second.enable;
480             DfxHisysevent::OnDeviceDisconnect(deviceId, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR);
481             inputDevice_.erase(it);
482             break;
483         }
484     }
485     MMI_HILOGI("Device added successfully, deviceId:%{public}s", GetMaskedDeviceId(std::to_string(deviceId)).c_str());
486     std::string sysUid = GetInputIdentification(inputDevice);
487     if (!sysUid.empty()) {
488         CHKPV(devCallbacks_);
489         devCallbacks_(deviceId, sysUid, "remove");
490         MMI_HILOGI("Send device info to window manager, device id:%{public}d, system uid:%s, status:remove",
491             deviceId, sysUid.c_str());
492     }
493 
494 #if defined(OHOS_BUILD_ENABLE_POINTER) && defined(OHOS_BUILD_ENABLE_POINTER_DRAWING)
495     if (IsPointerDevice(inputDevice) && !HasPointerDevice() &&
496         IPointerDrawingManager::GetInstance()->GetMouseDisplayState()) {
497         WIN_MGR->DispatchPointer(PointerEvent::POINTER_ACTION_LEAVE_WINDOW);
498     }
499 #endif // OHOS_BUILD_ENABLE_POINTER && OHOS_BUILD_ENABLE_POINTER_DRAWING
500     if (enable) {
501         for (const auto& item : devListeners_) {
502             CHKPV(item);
503             NotifyMessage(item, deviceId, "remove");
504         }
505     }
506     ScanPointerDevice();
507     if (deviceId == INVALID_DEVICE_ID) {
508         DfxHisysevent::OnDeviceDisconnect(INVALID_DEVICE_ID, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT);
509     }
510 }
511 
ScanPointerDevice()512 void InputDeviceManager::ScanPointerDevice()
513 {
514     bool hasPointerDevice = false;
515     for (auto it = inputDevice_.begin(); it != inputDevice_.end(); ++it) {
516         if (it->second.isPointerDevice && it->second.enable) {
517             hasPointerDevice = true;
518             break;
519         }
520     }
521     if (!hasPointerDevice) {
522         NotifyPointerDevice(false, false, true);
523         OHOS::system::SetParameter(INPUT_POINTER_DEVICES, "false");
524         MMI_HILOGI("Set para input.pointer.device false");
525     }
526 }
527 
IsPointerDevice(struct libinput_device * device) const528 bool InputDeviceManager::IsPointerDevice(struct libinput_device *device) const
529 {
530     CHKPF(device);
531     enum evdev_device_udev_tags udevTags = libinput_device_get_tags(device);
532     MMI_HILOGD("The current device udev tag:%{public}d", static_cast<int32_t>(udevTags));
533     std::string name = libinput_device_get_name(device);
534     if (name == "hw_fingerprint_mouse") {
535         return false;
536     }
537     if (name.find("HUAWEI Magnetic Keyboard") != std::string::npos) {
538         if (name.find("TouchPad") == std::string::npos) {
539             return (udevTags & (EVDEV_UDEV_TAG_MOUSE | EVDEV_UDEV_TAG_TRACKBALL | EVDEV_UDEV_TAG_POINTINGSTICK |
540                 EVDEV_UDEV_TAG_TOUCHPAD | EVDEV_UDEV_TAG_TABLET_PAD)) != 0;
541         }
542         return false;
543     }
544     if (name.find("HUAWEI M-Pencil") != std::string::npos) {
545         return false;
546     }
547     return (udevTags & (EVDEV_UDEV_TAG_MOUSE | EVDEV_UDEV_TAG_TRACKBALL | EVDEV_UDEV_TAG_POINTINGSTICK |
548         EVDEV_UDEV_TAG_TOUCHPAD | EVDEV_UDEV_TAG_TABLET_PAD)) != 0;
549 }
550 
IsKeyboardDevice(struct libinput_device * device) const551 bool InputDeviceManager::IsKeyboardDevice(struct libinput_device *device) const
552 {
553     CHKPF(device);
554     enum evdev_device_udev_tags udevTags = libinput_device_get_tags(device);
555     MMI_HILOGD("The current device udev tag:%{public}d", static_cast<int32_t>(udevTags));
556     return udevTags & EVDEV_UDEV_TAG_KEYBOARD;
557 }
558 
IsTouchDevice(struct libinput_device * device) const559 bool InputDeviceManager::IsTouchDevice(struct libinput_device *device) const
560 {
561     CHKPF(device);
562     return libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TOUCH);
563 }
564 
Attach(std::shared_ptr<IDeviceObserver> observer)565 void InputDeviceManager::Attach(std::shared_ptr<IDeviceObserver> observer)
566 {
567     CALL_DEBUG_ENTER;
568     observers_.push_back(observer);
569 }
570 
Detach(std::shared_ptr<IDeviceObserver> observer)571 void InputDeviceManager::Detach(std::shared_ptr<IDeviceObserver> observer)
572 {
573     CALL_DEBUG_ENTER;
574     observers_.remove(observer);
575 }
576 
NotifyPointerDevice(bool hasPointerDevice,bool isVisible,bool isHotPlug)577 void InputDeviceManager::NotifyPointerDevice(bool hasPointerDevice, bool isVisible, bool isHotPlug)
578 {
579     MMI_HILOGI("observers_ size:%{public}zu", observers_.size());
580     for (auto observer = observers_.begin(); observer != observers_.end(); observer++) {
581         (*observer)->UpdatePointerDevice(hasPointerDevice, isVisible, isHotPlug);
582     }
583 }
584 
FindInputDeviceId(struct libinput_device * inputDevice)585 int32_t InputDeviceManager::FindInputDeviceId(struct libinput_device *inputDevice)
586 {
587     CALL_DEBUG_ENTER;
588     CHKPR(inputDevice, INVALID_DEVICE_ID);
589     for (const auto &item : inputDevice_) {
590         if (item.second.inputDeviceOrigin == inputDevice) {
591             MMI_HILOGD("Find input device id success");
592             return item.first;
593         }
594     }
595     MMI_HILOGE("Find input device id failed");
596     return INVALID_DEVICE_ID;
597 }
598 
GetKeyboardDevice() const599 struct libinput_device *InputDeviceManager::GetKeyboardDevice() const
600 {
601     CALL_DEBUG_ENTER;
602     std::vector<int32_t> keyCodes;
603     keyCodes.push_back(KeyEvent::KEYCODE_Q);
604     keyCodes.push_back(KeyEvent::KEYCODE_NUMPAD_1);
605     for (const auto &item : inputDevice_) {
606         const auto &device = item.second.inputDeviceOrigin;
607         if (IsMatchKeys(device, keyCodes)) {
608             MMI_HILOGI("Find keyboard device success");
609             return device;
610         }
611     }
612     MMI_HILOGW("No keyboard device is currently available");
613     return nullptr;
614 }
615 
Dump(int32_t fd,const std::vector<std::string> & args)616 void InputDeviceManager::Dump(int32_t fd, const std::vector<std::string> &args)
617 {
618     CALL_DEBUG_ENTER;
619     mprintf(fd, "Device information:\t");
620     mprintf(fd, "Input devices: count=%zu", inputDevice_.size());
621     mprintf(fd, "Virtual input devices: count=%zu", virtualInputDevices_.size());
622     std::vector<int32_t> deviceIds = GetInputDeviceIds();
623     for (auto deviceId : deviceIds) {
624         std::shared_ptr<InputDevice> inputDevice = GetInputDevice(deviceId, false);
625         CHKPV(inputDevice);
626         mprintf(fd,
627             "deviceId:%d | deviceName:%s | deviceType:%d | bus:%d | version:%d "
628             "| product:%d | vendor:%d | phys:%s\t",
629             inputDevice->GetId(), inputDevice->GetName().c_str(), inputDevice->GetType(), inputDevice->GetBus(),
630             inputDevice->GetVersion(), inputDevice->GetProduct(), inputDevice->GetVendor(),
631             inputDevice->GetPhys().c_str());
632         std::vector<InputDevice::AxisInfo> axisinfo = inputDevice->GetAxisInfo();
633         mprintf(fd, "axis: count=%zu", axisinfo.size());
634         for (const auto &axis : axisinfo) {
635             auto iter = axisType.find(axis.GetAxisType());
636             if (iter == axisType.end()) {
637                 MMI_HILOGE("The axisType is not found");
638                 return;
639             }
640             mprintf(fd, "\t axisType:%s | minimum:%d | maximum:%d | fuzz:%d | flat:%d | resolution:%d\t",
641                 iter->second.c_str(), axis.GetMinimum(), axis.GetMaximum(), axis.GetFuzz(), axis.GetFlat(),
642                 axis.GetResolution());
643         }
644     }
645 }
646 
DumpDeviceList(int32_t fd,const std::vector<std::string> & args)647 void InputDeviceManager::DumpDeviceList(int32_t fd, const std::vector<std::string> &args)
648 {
649     CALL_DEBUG_ENTER;
650     std::vector<int32_t> ids = GetInputDeviceIds();
651     mprintf(fd, "Total device:%zu, Device list:\t", ids.size());
652     for (const auto &item : inputDevice_) {
653         std::shared_ptr<InputDevice> inputDevice = GetInputDevice(item.first, false);
654         CHKPV(inputDevice);
655         int32_t deviceId = inputDevice->GetId();
656         mprintf(fd, "deviceId:%d | deviceName:%s | deviceType:%d | bus:%d | version:%d | product:%d | vendor:%d\t",
657             deviceId, inputDevice->GetName().c_str(), inputDevice->GetType(), inputDevice->GetBus(),
658             inputDevice->GetVersion(), inputDevice->GetProduct(), inputDevice->GetVendor());
659     }
660 }
661 
IsRemote(struct libinput_device * inputDevice) const662 bool InputDeviceManager::IsRemote(struct libinput_device *inputDevice) const
663 {
664     CHKPF(inputDevice);
665     bool isRemote = false;
666     const char *name = libinput_device_get_name(inputDevice);
667     if (name == nullptr || name[0] == '\0') {
668         MMI_HILOGD("Device name is empty");
669         return false;
670     }
671     std::string strName = name;
672     std::string::size_type pos = strName.find(INPUT_VIRTUAL_DEVICE_NAME);
673     if (pos != std::string::npos) {
674         isRemote = true;
675     }
676     MMI_HILOGD("isRemote:%{public}s", isRemote ? "true" : "false");
677     return isRemote;
678 }
679 
IsRemote(int32_t id) const680 bool InputDeviceManager::IsRemote(int32_t id) const
681 {
682     bool isRemote = false;
683     auto device = inputDevice_.find(id);
684     if (device != inputDevice_.end()) {
685         isRemote = device->second.isRemote;
686     }
687     MMI_HILOGD("isRemote:%{public}s", isRemote ? "true" : "false");
688     return isRemote;
689 }
690 
GetVendorConfig(int32_t deviceId) const691 VendorConfig InputDeviceManager::GetVendorConfig(int32_t deviceId) const
692 {
693     CALL_DEBUG_ENTER;
694     auto it = inputDevice_.find(deviceId);
695     if (it == inputDevice_.end()) {
696         MMI_HILOGE("Device info not find id:%{public}d", deviceId);
697         return {};
698     }
699     return it->second.vendorConfig;
700 }
701 
OnEnableInputDevice(bool enable)702 int32_t InputDeviceManager::OnEnableInputDevice(bool enable)
703 {
704     CALL_DEBUG_ENTER;
705     MMI_HILOGD("Enable input device:%{public}s", enable ? "true" : "false");
706     for (auto &item : inputDevice_) {
707         if (item.second.isRemote && item.second.enable != enable) {
708             int32_t keyboardType = KEYBOARD_TYPE_NONE;
709             if (enable) {
710                 item.second.enable = enable;
711                 GetKeyboardType(item.first, keyboardType);
712             } else {
713                 GetKeyboardType(item.first, keyboardType);
714                 item.second.enable = enable;
715             }
716             if (keyboardType != KEYBOARD_TYPE_ALPHABETICKEYBOARD) {
717                 continue;
718             }
719             for (const auto& listener : devListeners_) {
720                 CHKPC(listener);
721                 NotifyMessage(listener, item.first, enable ? "add" : "remove");
722             }
723         }
724     }
725     for (const auto &item : inputDevice_) {
726         if (item.second.isPointerDevice && item.second.enable) {
727             NotifyPointerDevice(true, true, false);
728             break;
729         }
730     }
731     return RET_OK;
732 }
733 
AddVirtualInputDevice(std::shared_ptr<InputDevice> device,int32_t & deviceId)734 int32_t InputDeviceManager::AddVirtualInputDevice(std::shared_ptr<InputDevice> device, int32_t &deviceId)
735 {
736     CALL_INFO_TRACE;
737     CHKPR(device, RET_ERR);
738     if (GenerateVirtualDeviceId(deviceId) != RET_OK) {
739         MMI_HILOGE("GenerateVirtualDeviceId failed");
740         deviceId = INVALID_DEVICE_ID;
741         return RET_ERR;
742     }
743     device->SetId(deviceId);
744     virtualInputDevices_[deviceId] = device;
745     MMI_HILOGI("AddVirtualInputDevice successfully, deviceId:%{public}d", deviceId);
746     for (const auto& item : devListeners_) {
747         CHKPC(item);
748         NotifyMessage(item, deviceId, "add");
749     }
750     InputDeviceInfo deviceInfo;
751     if (MakeVirtualDeviceInfo(device, deviceInfo) != RET_OK) {
752         MMI_HILOGE("MakeVirtualDeviceInfo failed");
753         return RET_ERR;
754     }
755     NotifyDevCallback(deviceId, deviceInfo);
756     DfxHisysevent::OnDeviceConnect(deviceId, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR);
757     return RET_OK;
758 }
759 
RemoveVirtualInputDevice(int32_t deviceId)760 int32_t InputDeviceManager::RemoveVirtualInputDevice(int32_t deviceId)
761 {
762     CALL_INFO_TRACE;
763     auto iter = virtualInputDevices_.find(deviceId);
764     if (iter == virtualInputDevices_.end()) {
765         MMI_HILOGE("No virtual deviceId:%{public}d existed", deviceId);
766         return RET_ERR;
767     }
768     InputDeviceInfo deviceInfo;
769     if (MakeVirtualDeviceInfo(iter->second, deviceInfo) != RET_OK) {
770         MMI_HILOGE("MakeVirtualDeviceInfo failed");
771         return RET_ERR;
772     }
773     NotifyDevRemoveCallback(deviceId, deviceInfo);
774     virtualInputDevices_.erase(deviceId);
775     MMI_HILOGI("RemoveVirtualInputDevice successfully, deviceId:%{public}d", deviceId);
776     for (const auto& item : devListeners_) {
777         CHKPC(item);
778         NotifyMessage(item, deviceId, "remove");
779     }
780     DfxHisysevent::OnDeviceDisconnect(deviceId, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR);
781     return RET_OK;
782 }
783 
MakeVirtualDeviceInfo(std::shared_ptr<InputDevice> device,InputDeviceInfo & deviceInfo)784 int32_t InputDeviceManager::MakeVirtualDeviceInfo(std::shared_ptr<InputDevice> device, InputDeviceInfo &deviceInfo)
785 {
786     CALL_INFO_TRACE;
787     CHKPR(device, ERROR_NULL_POINTER);
788     deviceInfo = {
789         .isRemote = false,
790         .isPointerDevice = device->HasCapability(InputDeviceCapability::INPUT_DEV_CAP_POINTER),
791         .isTouchableDevice = device->HasCapability(InputDeviceCapability::INPUT_DEV_CAP_TOUCH),
792         .enable = true,
793     };
794     return RET_OK;
795 }
796 
GenerateVirtualDeviceId(int32_t & deviceId)797 int32_t InputDeviceManager::GenerateVirtualDeviceId(int32_t &deviceId)
798 {
799     CALL_INFO_TRACE;
800     static int32_t virtualDeviceId { MIN_VIRTUAL_INPUT_DEVICE_ID };
801     if (virtualInputDevices_.size() >= MAX_VIRTUAL_INPUT_DEVICE_NUM) {
802         MMI_HILOGE("Virtual device num exceeds limit:%{public}d", MAX_VIRTUAL_INPUT_DEVICE_NUM);
803         return RET_ERR;
804     }
805     if (virtualDeviceId == std::numeric_limits<int32_t>::max()) {
806         MMI_HILOGW("Request id exceeds the maximum");
807         virtualDeviceId = MIN_VIRTUAL_INPUT_DEVICE_ID;
808     }
809     deviceId = virtualDeviceId++;
810     if (virtualInputDevices_.find(deviceId) != virtualInputDevices_.end()) {
811         MMI_HILOGE("Repeated deviceId:%{public}d", deviceId);
812         deviceId = INVALID_DEVICE_ID;
813         return RET_ERR;
814     }
815     return RET_OK;
816 }
817 
NotifyDevRemoveCallback(int32_t deviceId,const InputDeviceInfo & deviceInfo)818 void InputDeviceManager::NotifyDevRemoveCallback(int32_t deviceId, const InputDeviceInfo &deviceInfo)
819 {
820     CALL_DEBUG_ENTER;
821     if (auto sysUid = deviceInfo.sysUid; !sysUid.empty()) {
822         devCallbacks_(deviceId, sysUid, "remove");
823         MMI_HILOGI("Send device info to window manager, deivceId:%{public}d, status:remove", deviceId);
824     }
825 }
826 
NotifyMessage(SessionPtr sess,int32_t id,const std::string & type)827 int32_t InputDeviceManager::NotifyMessage(SessionPtr sess, int32_t id, const std::string &type)
828 {
829     CALL_DEBUG_ENTER;
830     CHKPR(sess, ERROR_NULL_POINTER);
831     NetPacket pkt(MmiMessageId::ADD_INPUT_DEVICE_LISTENER);
832     pkt << type << id;
833     if (pkt.ChkRWError()) {
834         MMI_HILOGE("Packet write data failed");
835         return RET_ERR;
836     }
837     if (!sess->SendMsg(pkt)) {
838         MMI_HILOGE("Sending failed");
839     }
840     return RET_OK;
841 }
842 
InitSessionLostCallback()843 void InputDeviceManager::InitSessionLostCallback()
844 {
845     if (sessionLostCallbackInitialized_)  {
846         MMI_HILOGE("Init session is failed");
847         return;
848     }
849     auto udsServerPtr = InputHandler->GetUDSServer();
850     CHKPV(udsServerPtr);
851     udsServerPtr->AddSessionDeletedCallback([this] (SessionPtr session) {
852         return this->OnSessionLost(session);
853     }
854     );
855     sessionLostCallbackInitialized_ = true;
856     MMI_HILOGD("The callback on session deleted is registered successfully");
857 }
858 
OnSessionLost(SessionPtr session)859 void InputDeviceManager::OnSessionLost(SessionPtr session)
860 {
861     CALL_DEBUG_ENTER;
862     devListeners_.remove(session);
863 }
864 
IsPointerDevice(std::shared_ptr<InputDevice> inputDevice) const865 bool InputDeviceManager::IsPointerDevice(std::shared_ptr<InputDevice> inputDevice) const
866 {
867     CHKPR(inputDevice, false);
868     return inputDevice->HasCapability(InputDeviceCapability::INPUT_DEV_CAP_POINTER);
869 }
870 
IsTouchableDevice(std::shared_ptr<InputDevice> inputDevice) const871 bool InputDeviceManager::IsTouchableDevice(std::shared_ptr<InputDevice> inputDevice) const
872 {
873     CHKPR(inputDevice, false);
874     return inputDevice->HasCapability(InputDeviceCapability::INPUT_DEV_CAP_TOUCH);
875 }
876 
IsKeyboardDevice(std::shared_ptr<InputDevice> inputDevice) const877 bool InputDeviceManager::IsKeyboardDevice(std::shared_ptr<InputDevice> inputDevice) const
878 {
879     CHKPR(inputDevice, false);
880     return inputDevice->HasCapability(InputDeviceCapability::INPUT_DEV_CAP_KEYBOARD);
881 }
882 
GetTouchPadIds()883 std::vector<int32_t> InputDeviceManager::GetTouchPadIds()
884 {
885     CALL_DEBUG_ENTER;
886     std::vector<int32_t> ids;
887     for (const auto &item : inputDevice_) {
888         auto inputDevice = item.second.inputDeviceOrigin;
889         if (inputDevice == nullptr) {
890             continue;
891         }
892         enum evdev_device_udev_tags udevTags = libinput_device_get_tags(inputDevice);
893         if ((udevTags & EVDEV_UDEV_TAG_TOUCHPAD) != 0) {
894             ids.push_back(item.first);
895         }
896     }
897     return ids;
898 }
GetMaskedDeviceId(const std::string & str)899 std::string InputDeviceManager::GetMaskedDeviceId(const std::string& str)
900 {
901     return GetMaskedStr(str, RESERVE_LEN);
902 }
903 
GetMaskedStr(const std::string & str,size_t reserveLen)904 std::string InputDeviceManager::GetMaskedStr(const std::string& str, size_t reserveLen)
905 {
906     std::string mask("**");
907     if (static_cast<size_t>(str.length()) < reserveLen + reserveLen) {
908         return "";
909     }
910     return str.substr(0, reserveLen) + mask + str.substr(str.length() - reserveLen);
911 }
912 } // namespace MMI
913 } // namespace OHOS
914