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