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 
HasVirtualPointerDevice()336 bool InputDeviceManager::HasVirtualPointerDevice()
337 {
338     for (auto it = virtualInputDevices_.begin(); it != virtualInputDevices_.end(); ++it) {
339         if (it->second->HasCapability(InputDeviceCapability::INPUT_DEV_CAP_POINTER)) {
340             return true;
341         }
342     }
343     return false;
344 }
345 #endif // OHOS_BUILD_ENABLE_POINTER_DRAWING
346 
HasTouchDevice()347 bool InputDeviceManager::HasTouchDevice()
348 {
349     CALL_DEBUG_ENTER;
350     for (auto it = inputDevice_.begin(); it != inputDevice_.end(); ++it) {
351         if (it->second.isTouchableDevice) {
352             return true;
353         }
354     }
355     return false;
356 }
357 
GetInputIdentification(struct libinput_device * inputDevice)358 std::string InputDeviceManager::GetInputIdentification(struct libinput_device *inputDevice)
359 {
360     CALL_DEBUG_ENTER;
361     int32_t deviceVendor = libinput_device_get_id_vendor(inputDevice);
362     int32_t deviceProduct = libinput_device_get_id_product(inputDevice);
363     struct udev_device *udevDevice = libinput_device_get_udev_device(inputDevice);
364     std::string sysPath = udev_device_get_syspath(udevDevice);
365     udev_device_unref(udevDevice);
366     if ((deviceVendor < 0) || (deviceProduct < 0) || sysPath.empty()) {
367         MMI_HILOGE("Get device identification failed");
368         return "";
369     }
370     const size_t bufSize = 10;
371     char vid[bufSize] = "";
372     char pid[bufSize] = "";
373     sprintf_s(vid, sizeof(vid), "%04X", deviceVendor);
374     sprintf_s(pid, sizeof(pid), "%04X", deviceProduct);
375     std::string strVid(vid);
376     std::string strPid(pid);
377     std::string vendorProduct = strVid + ":" + strPid;
378     std::string deviceIdentification = sysPath.substr(0, sysPath.find(vendorProduct)) + vendorProduct;
379     MMI_HILOGI("Device identification is:%{public}s", deviceIdentification.c_str());
380     return deviceIdentification;
381 }
382 
NotifyDevCallback(int32_t deviceId,struct InputDeviceInfo inDevice)383 void InputDeviceManager::NotifyDevCallback(int32_t deviceId, struct InputDeviceInfo inDevice)
384 {
385     if (!inDevice.isTouchableDevice || (deviceId < 0)) {
386         MMI_HILOGI("The device is not touchable device already existent");
387         return;
388     }
389     if (!inDevice.sysUid.empty()) {
390         devCallbacks_(deviceId, inDevice.sysUid, "add");
391         MMI_HILOGI("Send device info to window manager, device id:%{public}d, system uid:%s, status:add",
392             deviceId, inDevice.sysUid.c_str());
393     } else {
394         MMI_HILOGE("Get device system uid id is empty, deviceId:%{public}d", deviceId);
395     }
396 }
397 
ParseDeviceId(struct libinput_device * inputDevice)398 int32_t InputDeviceManager::ParseDeviceId(struct libinput_device *inputDevice)
399 {
400     CALL_DEBUG_ENTER;
401     std::regex pattern("^event(\\d+)$");
402     std::smatch mr;
403     const char *sysName = libinput_device_get_sysname(inputDevice);
404     CHKPR(sysName, RET_ERR);
405     std::string strName(sysName);
406     if (std::regex_match(strName, mr, pattern)) {
407         if (mr.ready() && mr.size() == EXPECTED_N_SUBMATCHES) {
408             return std::stoi(mr[EXPECTED_SUBMATCH].str());
409         }
410     }
411     MMI_HILOGE("Parsing strName failed: \'%{public}s\'", strName.c_str());
412     return RET_ERR;
413 }
414 
OnInputDeviceAdded(struct libinput_device * inputDevice)415 void InputDeviceManager::OnInputDeviceAdded(struct libinput_device *inputDevice)
416 {
417     CALL_DEBUG_ENTER;
418     CHKPV(inputDevice);
419     bool hasPointer = false;
420     for (const auto &item : inputDevice_) {
421         if (item.second.inputDeviceOrigin == inputDevice) {
422             MMI_HILOGI("The device is already existent");
423             DfxHisysevent::OnDeviceConnect(item.first, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT);
424             return;
425         }
426         if ((!item.second.isRemote && item.second.isPointerDevice) ||
427             (item.second.isRemote && item.second.isPointerDevice && item.second.enable)) {
428             hasPointer = true;
429         }
430     }
431     int32_t deviceId = ParseDeviceId(inputDevice);
432     if (deviceId < 0) {
433         return;
434     }
435     struct InputDeviceInfo info;
436     MakeDeviceInfo(inputDevice, info);
437     inputDevice_[deviceId] = info;
438     MMI_HILOGI("Device added successfully, deviceId:%{public}s, system uid:%{private}s",
439         GetMaskedDeviceId(std::to_string(deviceId)).c_str(), info.sysUid.c_str());
440     if (info.enable) {
441         for (const auto& item : devListeners_) {
442             CHKPC(item);
443             NotifyMessage(item, deviceId, "add");
444         }
445     }
446     NotifyDevCallback(deviceId, info);
447     if (!hasPointer && info.isPointerDevice) {
448 #if defined(OHOS_BUILD_ENABLE_POINTER) && defined(OHOS_BUILD_ENABLE_POINTER_DRAWING)
449         if (HasTouchDevice()) {
450             IPointerDrawingManager::GetInstance()->SetMouseDisplayState(false);
451         }
452 #endif // OHOS_BUILD_ENABLE_POINTER && OHOS_BUILD_ENABLE_POINTER_DRAWING
453         NotifyPointerDevice(true, true, true);
454         OHOS::system::SetParameter(INPUT_POINTER_DEVICES, "true");
455         MMI_HILOGI("Set para input.pointer.device true");
456     }
457 #if defined(OHOS_BUILD_ENABLE_POINTER) && defined(OHOS_BUILD_ENABLE_POINTER_DRAWING)
458     if (IsPointerDevice(inputDevice)) {
459         WIN_MGR->UpdatePointerChangeAreas();
460     }
461     if (IsPointerDevice(inputDevice) && !HasPointerDevice() &&
462         IPointerDrawingManager::GetInstance()->GetMouseDisplayState()) {
463         WIN_MGR->DispatchPointer(PointerEvent::POINTER_ACTION_ENTER_WINDOW);
464     }
465 #endif // OHOS_BUILD_ENABLE_POINTER && OHOS_BUILD_ENABLE_POINTER_DRAWING
466     DfxHisysevent::OnDeviceConnect(deviceId, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR);
467 }
468 
MakeDeviceInfo(struct libinput_device * inputDevice,struct InputDeviceInfo & info)469 void InputDeviceManager::MakeDeviceInfo(struct libinput_device *inputDevice, struct InputDeviceInfo &info)
470 {
471     info.inputDeviceOrigin = inputDevice;
472     info.isRemote = IsRemote(inputDevice);
473     info.enable = info.isRemote ? false : true;
474     info.isPointerDevice = IsPointerDevice(inputDevice);
475     info.isTouchableDevice = IsTouchDevice(inputDevice);
476     info.sysUid = GetInputIdentification(inputDevice);
477     info.vendorConfig = configManagement_.GetVendorConfig(inputDevice);
478 }
479 
OnInputDeviceRemoved(struct libinput_device * inputDevice)480 void InputDeviceManager::OnInputDeviceRemoved(struct libinput_device *inputDevice)
481 {
482     CALL_DEBUG_ENTER;
483     CHKPV(inputDevice);
484     int32_t deviceId = INVALID_DEVICE_ID;
485     bool enable = false;
486     for (auto it = inputDevice_.begin(); it != inputDevice_.end(); ++it) {
487         if (it->second.inputDeviceOrigin == inputDevice) {
488             deviceId = it->first;
489             enable = it->second.enable;
490             DfxHisysevent::OnDeviceDisconnect(deviceId, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR);
491             inputDevice_.erase(it);
492             break;
493         }
494     }
495     MMI_HILOGI("Device added successfully, deviceId:%{public}s", GetMaskedDeviceId(std::to_string(deviceId)).c_str());
496     std::string sysUid = GetInputIdentification(inputDevice);
497     if (!sysUid.empty()) {
498         CHKPV(devCallbacks_);
499         devCallbacks_(deviceId, sysUid, "remove");
500         MMI_HILOGI("Send device info to window manager, device id:%{public}d, system uid:%s, status:remove",
501             deviceId, sysUid.c_str());
502     }
503 
504 #if defined(OHOS_BUILD_ENABLE_POINTER) && defined(OHOS_BUILD_ENABLE_POINTER_DRAWING)
505     if (IsPointerDevice(inputDevice) && !HasPointerDevice() &&
506         IPointerDrawingManager::GetInstance()->GetMouseDisplayState()) {
507         WIN_MGR->DispatchPointer(PointerEvent::POINTER_ACTION_LEAVE_WINDOW);
508     }
509 #endif // OHOS_BUILD_ENABLE_POINTER && OHOS_BUILD_ENABLE_POINTER_DRAWING
510     if (enable) {
511         for (const auto& item : devListeners_) {
512             CHKPV(item);
513             NotifyMessage(item, deviceId, "remove");
514         }
515     }
516     ScanPointerDevice();
517     if (deviceId == INVALID_DEVICE_ID) {
518         DfxHisysevent::OnDeviceDisconnect(INVALID_DEVICE_ID, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT);
519     }
520 }
521 
ScanPointerDevice()522 void InputDeviceManager::ScanPointerDevice()
523 {
524     bool hasPointerDevice = false;
525     for (auto it = inputDevice_.begin(); it != inputDevice_.end(); ++it) {
526         if (it->second.isPointerDevice && it->second.enable) {
527             hasPointerDevice = true;
528             break;
529         }
530     }
531     if (!hasPointerDevice) {
532         NotifyPointerDevice(false, false, true);
533         OHOS::system::SetParameter(INPUT_POINTER_DEVICES, "false");
534         MMI_HILOGI("Set para input.pointer.device false");
535     }
536 }
537 
IsPointerDevice(struct libinput_device * device) const538 bool InputDeviceManager::IsPointerDevice(struct libinput_device *device) const
539 {
540     CHKPF(device);
541     enum evdev_device_udev_tags udevTags = libinput_device_get_tags(device);
542     MMI_HILOGD("The current device udev tag:%{public}d", static_cast<int32_t>(udevTags));
543     std::string name = libinput_device_get_name(device);
544     if (name == "hw_fingerprint_mouse") {
545         return false;
546     }
547     if (name.find("HUAWEI Magnetic Keyboard") != std::string::npos) {
548         if (name.find("TouchPad") == std::string::npos) {
549             return (udevTags & (EVDEV_UDEV_TAG_MOUSE | EVDEV_UDEV_TAG_TRACKBALL | EVDEV_UDEV_TAG_POINTINGSTICK |
550                 EVDEV_UDEV_TAG_TOUCHPAD | EVDEV_UDEV_TAG_TABLET_PAD)) != 0;
551         }
552         return false;
553     }
554     if (name.find("HUAWEI M-Pencil") != std::string::npos) {
555         return false;
556     }
557     return (udevTags & (EVDEV_UDEV_TAG_MOUSE | EVDEV_UDEV_TAG_TRACKBALL | EVDEV_UDEV_TAG_POINTINGSTICK |
558         EVDEV_UDEV_TAG_TOUCHPAD | EVDEV_UDEV_TAG_TABLET_PAD)) != 0;
559 }
560 
IsKeyboardDevice(struct libinput_device * device) const561 bool InputDeviceManager::IsKeyboardDevice(struct libinput_device *device) const
562 {
563     CHKPF(device);
564     enum evdev_device_udev_tags udevTags = libinput_device_get_tags(device);
565     MMI_HILOGD("The current device udev tag:%{public}d", static_cast<int32_t>(udevTags));
566     return udevTags & EVDEV_UDEV_TAG_KEYBOARD;
567 }
568 
IsTouchDevice(struct libinput_device * device) const569 bool InputDeviceManager::IsTouchDevice(struct libinput_device *device) const
570 {
571     CHKPF(device);
572     return libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TOUCH);
573 }
574 
Attach(std::shared_ptr<IDeviceObserver> observer)575 void InputDeviceManager::Attach(std::shared_ptr<IDeviceObserver> observer)
576 {
577     CALL_DEBUG_ENTER;
578     observers_.push_back(observer);
579 }
580 
Detach(std::shared_ptr<IDeviceObserver> observer)581 void InputDeviceManager::Detach(std::shared_ptr<IDeviceObserver> observer)
582 {
583     CALL_DEBUG_ENTER;
584     observers_.remove(observer);
585 }
586 
NotifyPointerDevice(bool hasPointerDevice,bool isVisible,bool isHotPlug)587 void InputDeviceManager::NotifyPointerDevice(bool hasPointerDevice, bool isVisible, bool isHotPlug)
588 {
589     MMI_HILOGI("observers_ size:%{public}zu", observers_.size());
590     for (auto observer = observers_.begin(); observer != observers_.end(); observer++) {
591         (*observer)->UpdatePointerDevice(hasPointerDevice, isVisible, isHotPlug);
592     }
593 }
594 
FindInputDeviceId(struct libinput_device * inputDevice)595 int32_t InputDeviceManager::FindInputDeviceId(struct libinput_device *inputDevice)
596 {
597     CALL_DEBUG_ENTER;
598     CHKPR(inputDevice, INVALID_DEVICE_ID);
599     for (const auto &item : inputDevice_) {
600         if (item.second.inputDeviceOrigin == inputDevice) {
601             MMI_HILOGD("Find input device id success");
602             return item.first;
603         }
604     }
605     MMI_HILOGE("Find input device id failed");
606     return INVALID_DEVICE_ID;
607 }
608 
GetKeyboardDevice() const609 struct libinput_device *InputDeviceManager::GetKeyboardDevice() const
610 {
611     CALL_DEBUG_ENTER;
612     std::vector<int32_t> keyCodes;
613     keyCodes.push_back(KeyEvent::KEYCODE_Q);
614     keyCodes.push_back(KeyEvent::KEYCODE_NUMPAD_1);
615     for (const auto &item : inputDevice_) {
616         const auto &device = item.second.inputDeviceOrigin;
617         if (IsMatchKeys(device, keyCodes)) {
618             MMI_HILOGI("Find keyboard device success");
619             return device;
620         }
621     }
622     MMI_HILOGW("No keyboard device is currently available");
623     return nullptr;
624 }
625 
Dump(int32_t fd,const std::vector<std::string> & args)626 void InputDeviceManager::Dump(int32_t fd, const std::vector<std::string> &args)
627 {
628     CALL_DEBUG_ENTER;
629     mprintf(fd, "Device information:\t");
630     mprintf(fd, "Input devices: count=%zu", inputDevice_.size());
631     mprintf(fd, "Virtual input devices: count=%zu", virtualInputDevices_.size());
632     std::vector<int32_t> deviceIds = GetInputDeviceIds();
633     for (auto deviceId : deviceIds) {
634         std::shared_ptr<InputDevice> inputDevice = GetInputDevice(deviceId, false);
635         CHKPV(inputDevice);
636         mprintf(fd,
637             "deviceId:%d | deviceName:%s | deviceType:%d | bus:%d | version:%d "
638             "| product:%d | vendor:%d | phys:%s\t",
639             inputDevice->GetId(), inputDevice->GetName().c_str(), inputDevice->GetType(), inputDevice->GetBus(),
640             inputDevice->GetVersion(), inputDevice->GetProduct(), inputDevice->GetVendor(),
641             inputDevice->GetPhys().c_str());
642         std::vector<InputDevice::AxisInfo> axisinfo = inputDevice->GetAxisInfo();
643         mprintf(fd, "axis: count=%zu", axisinfo.size());
644         for (const auto &axis : axisinfo) {
645             auto iter = axisType.find(axis.GetAxisType());
646             if (iter == axisType.end()) {
647                 MMI_HILOGE("The axisType is not found");
648                 return;
649             }
650             mprintf(fd, "\t axisType:%s | minimum:%d | maximum:%d | fuzz:%d | flat:%d | resolution:%d\t",
651                 iter->second.c_str(), axis.GetMinimum(), axis.GetMaximum(), axis.GetFuzz(), axis.GetFlat(),
652                 axis.GetResolution());
653         }
654     }
655 }
656 
DumpDeviceList(int32_t fd,const std::vector<std::string> & args)657 void InputDeviceManager::DumpDeviceList(int32_t fd, const std::vector<std::string> &args)
658 {
659     CALL_DEBUG_ENTER;
660     std::vector<int32_t> ids = GetInputDeviceIds();
661     mprintf(fd, "Total device:%zu, Device list:\t", ids.size());
662     for (const auto &item : inputDevice_) {
663         std::shared_ptr<InputDevice> inputDevice = GetInputDevice(item.first, false);
664         CHKPV(inputDevice);
665         int32_t deviceId = inputDevice->GetId();
666         mprintf(fd, "deviceId:%d | deviceName:%s | deviceType:%d | bus:%d | version:%d | product:%d | vendor:%d\t",
667             deviceId, inputDevice->GetName().c_str(), inputDevice->GetType(), inputDevice->GetBus(),
668             inputDevice->GetVersion(), inputDevice->GetProduct(), inputDevice->GetVendor());
669     }
670 }
671 
IsRemote(struct libinput_device * inputDevice) const672 bool InputDeviceManager::IsRemote(struct libinput_device *inputDevice) const
673 {
674     CHKPF(inputDevice);
675     bool isRemote = false;
676     const char *name = libinput_device_get_name(inputDevice);
677     if (name == nullptr || name[0] == '\0') {
678         MMI_HILOGD("Device name is empty");
679         return false;
680     }
681     std::string strName = name;
682     std::string::size_type pos = strName.find(INPUT_VIRTUAL_DEVICE_NAME);
683     if (pos != std::string::npos) {
684         isRemote = true;
685     }
686     MMI_HILOGD("isRemote:%{public}s", isRemote ? "true" : "false");
687     return isRemote;
688 }
689 
IsRemote(int32_t id) const690 bool InputDeviceManager::IsRemote(int32_t id) const
691 {
692     bool isRemote = false;
693     auto device = inputDevice_.find(id);
694     if (device != inputDevice_.end()) {
695         isRemote = device->second.isRemote;
696     }
697     MMI_HILOGD("isRemote:%{public}s", isRemote ? "true" : "false");
698     return isRemote;
699 }
700 
GetVendorConfig(int32_t deviceId) const701 VendorConfig InputDeviceManager::GetVendorConfig(int32_t deviceId) const
702 {
703     CALL_DEBUG_ENTER;
704     auto it = inputDevice_.find(deviceId);
705     if (it == inputDevice_.end()) {
706         MMI_HILOGE("Device info not find id:%{public}d", deviceId);
707         return {};
708     }
709     return it->second.vendorConfig;
710 }
711 
OnEnableInputDevice(bool enable)712 int32_t InputDeviceManager::OnEnableInputDevice(bool enable)
713 {
714     CALL_DEBUG_ENTER;
715     MMI_HILOGD("Enable input device:%{public}s", enable ? "true" : "false");
716     for (auto &item : inputDevice_) {
717         if (item.second.isRemote && item.second.enable != enable) {
718             int32_t keyboardType = KEYBOARD_TYPE_NONE;
719             if (enable) {
720                 item.second.enable = enable;
721                 GetKeyboardType(item.first, keyboardType);
722             } else {
723                 GetKeyboardType(item.first, keyboardType);
724                 item.second.enable = enable;
725             }
726             if (keyboardType != KEYBOARD_TYPE_ALPHABETICKEYBOARD) {
727                 continue;
728             }
729             for (const auto& listener : devListeners_) {
730                 CHKPC(listener);
731                 NotifyMessage(listener, item.first, enable ? "add" : "remove");
732             }
733         }
734     }
735     for (const auto &item : inputDevice_) {
736         if (item.second.isPointerDevice && item.second.enable) {
737             NotifyPointerDevice(true, true, false);
738             break;
739         }
740     }
741     return RET_OK;
742 }
743 
AddVirtualInputDevice(std::shared_ptr<InputDevice> device,int32_t & deviceId)744 int32_t InputDeviceManager::AddVirtualInputDevice(std::shared_ptr<InputDevice> device, int32_t &deviceId)
745 {
746     CALL_INFO_TRACE;
747     CHKPR(device, RET_ERR);
748     if (GenerateVirtualDeviceId(deviceId) != RET_OK) {
749         MMI_HILOGE("GenerateVirtualDeviceId failed");
750         deviceId = INVALID_DEVICE_ID;
751         return RET_ERR;
752     }
753     device->SetId(deviceId);
754     virtualInputDevices_[deviceId] = device;
755     MMI_HILOGI("AddVirtualInputDevice successfully, deviceId:%{public}d", deviceId);
756     for (const auto& item : devListeners_) {
757         CHKPC(item);
758         NotifyMessage(item, deviceId, "add");
759     }
760     InputDeviceInfo deviceInfo;
761     if (MakeVirtualDeviceInfo(device, deviceInfo) != RET_OK) {
762         MMI_HILOGE("MakeVirtualDeviceInfo failed");
763         return RET_ERR;
764     }
765     NotifyDevCallback(deviceId, deviceInfo);
766     DfxHisysevent::OnDeviceConnect(deviceId, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR);
767     return RET_OK;
768 }
769 
RemoveVirtualInputDevice(int32_t deviceId)770 int32_t InputDeviceManager::RemoveVirtualInputDevice(int32_t deviceId)
771 {
772     CALL_INFO_TRACE;
773     auto iter = virtualInputDevices_.find(deviceId);
774     if (iter == virtualInputDevices_.end()) {
775         MMI_HILOGE("No virtual deviceId:%{public}d existed", deviceId);
776         return RET_ERR;
777     }
778     InputDeviceInfo deviceInfo;
779     if (MakeVirtualDeviceInfo(iter->second, deviceInfo) != RET_OK) {
780         MMI_HILOGE("MakeVirtualDeviceInfo failed");
781         return RET_ERR;
782     }
783     NotifyDevRemoveCallback(deviceId, deviceInfo);
784     virtualInputDevices_.erase(deviceId);
785     MMI_HILOGI("RemoveVirtualInputDevice successfully, deviceId:%{public}d", deviceId);
786     for (const auto& item : devListeners_) {
787         CHKPC(item);
788         NotifyMessage(item, deviceId, "remove");
789     }
790     DfxHisysevent::OnDeviceDisconnect(deviceId, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR);
791     return RET_OK;
792 }
793 
MakeVirtualDeviceInfo(std::shared_ptr<InputDevice> device,InputDeviceInfo & deviceInfo)794 int32_t InputDeviceManager::MakeVirtualDeviceInfo(std::shared_ptr<InputDevice> device, InputDeviceInfo &deviceInfo)
795 {
796     CALL_INFO_TRACE;
797     CHKPR(device, ERROR_NULL_POINTER);
798     deviceInfo = {
799         .isRemote = false,
800         .isPointerDevice = device->HasCapability(InputDeviceCapability::INPUT_DEV_CAP_POINTER),
801         .isTouchableDevice = device->HasCapability(InputDeviceCapability::INPUT_DEV_CAP_TOUCH),
802         .enable = true,
803     };
804     return RET_OK;
805 }
806 
GenerateVirtualDeviceId(int32_t & deviceId)807 int32_t InputDeviceManager::GenerateVirtualDeviceId(int32_t &deviceId)
808 {
809     CALL_INFO_TRACE;
810     static int32_t virtualDeviceId { MIN_VIRTUAL_INPUT_DEVICE_ID };
811     if (virtualInputDevices_.size() >= MAX_VIRTUAL_INPUT_DEVICE_NUM) {
812         MMI_HILOGE("Virtual device num exceeds limit:%{public}d", MAX_VIRTUAL_INPUT_DEVICE_NUM);
813         return RET_ERR;
814     }
815     if (virtualDeviceId == std::numeric_limits<int32_t>::max()) {
816         MMI_HILOGW("Request id exceeds the maximum");
817         virtualDeviceId = MIN_VIRTUAL_INPUT_DEVICE_ID;
818     }
819     deviceId = virtualDeviceId++;
820     if (virtualInputDevices_.find(deviceId) != virtualInputDevices_.end()) {
821         MMI_HILOGE("Repeated deviceId:%{public}d", deviceId);
822         deviceId = INVALID_DEVICE_ID;
823         return RET_ERR;
824     }
825     return RET_OK;
826 }
827 
NotifyDevRemoveCallback(int32_t deviceId,const InputDeviceInfo & deviceInfo)828 void InputDeviceManager::NotifyDevRemoveCallback(int32_t deviceId, const InputDeviceInfo &deviceInfo)
829 {
830     CALL_DEBUG_ENTER;
831     if (auto sysUid = deviceInfo.sysUid; !sysUid.empty()) {
832         devCallbacks_(deviceId, sysUid, "remove");
833         MMI_HILOGI("Send device info to window manager, deivceId:%{public}d, status:remove", deviceId);
834     }
835 }
836 
NotifyMessage(SessionPtr sess,int32_t id,const std::string & type)837 int32_t InputDeviceManager::NotifyMessage(SessionPtr sess, int32_t id, const std::string &type)
838 {
839     CALL_DEBUG_ENTER;
840     CHKPR(sess, ERROR_NULL_POINTER);
841     NetPacket pkt(MmiMessageId::ADD_INPUT_DEVICE_LISTENER);
842     pkt << type << id;
843     if (pkt.ChkRWError()) {
844         MMI_HILOGE("Packet write data failed");
845         return RET_ERR;
846     }
847     if (!sess->SendMsg(pkt)) {
848         MMI_HILOGE("Sending failed");
849     }
850     return RET_OK;
851 }
852 
InitSessionLostCallback()853 void InputDeviceManager::InitSessionLostCallback()
854 {
855     if (sessionLostCallbackInitialized_)  {
856         MMI_HILOGE("Init session is failed");
857         return;
858     }
859     auto udsServerPtr = InputHandler->GetUDSServer();
860     CHKPV(udsServerPtr);
861     udsServerPtr->AddSessionDeletedCallback([this] (SessionPtr session) {
862         return this->OnSessionLost(session);
863     }
864     );
865     sessionLostCallbackInitialized_ = true;
866     MMI_HILOGD("The callback on session deleted is registered successfully");
867 }
868 
OnSessionLost(SessionPtr session)869 void InputDeviceManager::OnSessionLost(SessionPtr session)
870 {
871     CALL_DEBUG_ENTER;
872     devListeners_.remove(session);
873 }
874 
IsPointerDevice(std::shared_ptr<InputDevice> inputDevice) const875 bool InputDeviceManager::IsPointerDevice(std::shared_ptr<InputDevice> inputDevice) const
876 {
877     CHKPR(inputDevice, false);
878     return inputDevice->HasCapability(InputDeviceCapability::INPUT_DEV_CAP_POINTER);
879 }
880 
IsTouchableDevice(std::shared_ptr<InputDevice> inputDevice) const881 bool InputDeviceManager::IsTouchableDevice(std::shared_ptr<InputDevice> inputDevice) const
882 {
883     CHKPR(inputDevice, false);
884     return inputDevice->HasCapability(InputDeviceCapability::INPUT_DEV_CAP_TOUCH);
885 }
886 
IsKeyboardDevice(std::shared_ptr<InputDevice> inputDevice) const887 bool InputDeviceManager::IsKeyboardDevice(std::shared_ptr<InputDevice> inputDevice) const
888 {
889     CHKPR(inputDevice, false);
890     return inputDevice->HasCapability(InputDeviceCapability::INPUT_DEV_CAP_KEYBOARD);
891 }
892 
GetTouchPadIds()893 std::vector<int32_t> InputDeviceManager::GetTouchPadIds()
894 {
895     CALL_DEBUG_ENTER;
896     std::vector<int32_t> ids;
897     for (const auto &item : inputDevice_) {
898         auto inputDevice = item.second.inputDeviceOrigin;
899         if (inputDevice == nullptr) {
900             continue;
901         }
902         enum evdev_device_udev_tags udevTags = libinput_device_get_tags(inputDevice);
903         if ((udevTags & EVDEV_UDEV_TAG_TOUCHPAD) != 0) {
904             ids.push_back(item.first);
905         }
906     }
907     return ids;
908 }
909 
GetTouchPadDeviceOrigin()910 struct libinput_device *InputDeviceManager::GetTouchPadDeviceOrigin()
911 {
912     CALL_DEBUG_ENTER;
913     struct libinput_device *touchPadDevice = nullptr;
914     for (const auto &item : inputDevice_) {
915         auto inputDevice = item.second.inputDeviceOrigin;
916         if (inputDevice == nullptr) {
917             continue;
918         }
919         enum evdev_device_udev_tags udevTags = libinput_device_get_tags(inputDevice);
920         if ((udevTags & EVDEV_UDEV_TAG_TOUCHPAD) != 0) {
921             touchPadDevice = inputDevice;
922             break;
923         }
924     }
925     return touchPadDevice;
926 }
927 
GetMaskedDeviceId(const std::string & str)928 std::string InputDeviceManager::GetMaskedDeviceId(const std::string& str)
929 {
930     return GetMaskedStr(str, RESERVE_LEN);
931 }
932 
GetMaskedStr(const std::string & str,size_t reserveLen)933 std::string InputDeviceManager::GetMaskedStr(const std::string& str, size_t reserveLen)
934 {
935     std::string mask("**");
936     if (static_cast<size_t>(str.length()) < reserveLen + reserveLen) {
937         return "";
938     }
939     return str.substr(0, reserveLen) + mask + str.substr(str.length() - reserveLen);
940 }
941 } // namespace MMI
942 } // namespace OHOS
943