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