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
GetMultiKeyboardDevice(std::vector<struct libinput_device * > & inputDevice)626 void InputDeviceManager::GetMultiKeyboardDevice(std::vector<struct libinput_device*> &inputDevice)
627 {
628 CALL_DEBUG_ENTER;
629 std::vector<int32_t> keyCodes;
630 keyCodes.push_back(KeyEvent::KEYCODE_Q);
631 keyCodes.push_back(KeyEvent::KEYCODE_NUMPAD_1);
632 for (const auto &item : inputDevice_) {
633 const auto &device = item.second.inputDeviceOrigin;
634 if (IsMatchKeys(device, keyCodes)) {
635 MMI_HILOGI("Find keyboard device success id %{public}d", item.first);
636 inputDevice.push_back(device);
637 }
638 }
639 }
640
Dump(int32_t fd,const std::vector<std::string> & args)641 void InputDeviceManager::Dump(int32_t fd, const std::vector<std::string> &args)
642 {
643 CALL_DEBUG_ENTER;
644 mprintf(fd, "Device information:\t");
645 mprintf(fd, "Input devices: count=%zu", inputDevice_.size());
646 mprintf(fd, "Virtual input devices: count=%zu", virtualInputDevices_.size());
647 std::vector<int32_t> deviceIds = GetInputDeviceIds();
648 for (auto deviceId : deviceIds) {
649 std::shared_ptr<InputDevice> inputDevice = GetInputDevice(deviceId, false);
650 CHKPV(inputDevice);
651 mprintf(fd,
652 "deviceId:%d | deviceName:%s | deviceType:%d | bus:%d | version:%d "
653 "| product:%d | vendor:%d | phys:%s\t",
654 inputDevice->GetId(), inputDevice->GetName().c_str(), inputDevice->GetType(), inputDevice->GetBus(),
655 inputDevice->GetVersion(), inputDevice->GetProduct(), inputDevice->GetVendor(),
656 inputDevice->GetPhys().c_str());
657 std::vector<InputDevice::AxisInfo> axisinfo = inputDevice->GetAxisInfo();
658 mprintf(fd, "axis: count=%zu", axisinfo.size());
659 for (const auto &axis : axisinfo) {
660 auto iter = axisType.find(axis.GetAxisType());
661 if (iter == axisType.end()) {
662 MMI_HILOGE("The axisType is not found");
663 return;
664 }
665 mprintf(fd, "\t axisType:%s | minimum:%d | maximum:%d | fuzz:%d | flat:%d | resolution:%d\t",
666 iter->second.c_str(), axis.GetMinimum(), axis.GetMaximum(), axis.GetFuzz(), axis.GetFlat(),
667 axis.GetResolution());
668 }
669 }
670 }
671
DumpDeviceList(int32_t fd,const std::vector<std::string> & args)672 void InputDeviceManager::DumpDeviceList(int32_t fd, const std::vector<std::string> &args)
673 {
674 CALL_DEBUG_ENTER;
675 std::vector<int32_t> ids = GetInputDeviceIds();
676 mprintf(fd, "Total device:%zu, Device list:\t", ids.size());
677 for (const auto &item : inputDevice_) {
678 std::shared_ptr<InputDevice> inputDevice = GetInputDevice(item.first, false);
679 CHKPV(inputDevice);
680 int32_t deviceId = inputDevice->GetId();
681 mprintf(fd, "deviceId:%d | deviceName:%s | deviceType:%d | bus:%d | version:%d | product:%d | vendor:%d\t",
682 deviceId, inputDevice->GetName().c_str(), inputDevice->GetType(), inputDevice->GetBus(),
683 inputDevice->GetVersion(), inputDevice->GetProduct(), inputDevice->GetVendor());
684 }
685 }
686
IsRemote(struct libinput_device * inputDevice) const687 bool InputDeviceManager::IsRemote(struct libinput_device *inputDevice) const
688 {
689 CHKPF(inputDevice);
690 bool isRemote = false;
691 const char *name = libinput_device_get_name(inputDevice);
692 if (name == nullptr || name[0] == '\0') {
693 MMI_HILOGD("Device name is empty");
694 return false;
695 }
696 std::string strName = name;
697 std::string::size_type pos = strName.find(INPUT_VIRTUAL_DEVICE_NAME);
698 if (pos != std::string::npos) {
699 isRemote = true;
700 }
701 MMI_HILOGD("isRemote:%{public}s", isRemote ? "true" : "false");
702 return isRemote;
703 }
704
IsRemote(int32_t id) const705 bool InputDeviceManager::IsRemote(int32_t id) const
706 {
707 bool isRemote = false;
708 auto device = inputDevice_.find(id);
709 if (device != inputDevice_.end()) {
710 isRemote = device->second.isRemote;
711 }
712 MMI_HILOGD("isRemote:%{public}s", isRemote ? "true" : "false");
713 return isRemote;
714 }
715
GetVendorConfig(int32_t deviceId) const716 VendorConfig InputDeviceManager::GetVendorConfig(int32_t deviceId) const
717 {
718 CALL_DEBUG_ENTER;
719 auto it = inputDevice_.find(deviceId);
720 if (it == inputDevice_.end()) {
721 MMI_HILOGE("Device info not find id:%{public}d", deviceId);
722 return {};
723 }
724 return it->second.vendorConfig;
725 }
726
OnEnableInputDevice(bool enable)727 int32_t InputDeviceManager::OnEnableInputDevice(bool enable)
728 {
729 CALL_DEBUG_ENTER;
730 MMI_HILOGD("Enable input device:%{public}s", enable ? "true" : "false");
731 for (auto &item : inputDevice_) {
732 if (item.second.isRemote && item.second.enable != enable) {
733 int32_t keyboardType = KEYBOARD_TYPE_NONE;
734 if (enable) {
735 item.second.enable = enable;
736 GetKeyboardType(item.first, keyboardType);
737 } else {
738 GetKeyboardType(item.first, keyboardType);
739 item.second.enable = enable;
740 }
741 if (keyboardType != KEYBOARD_TYPE_ALPHABETICKEYBOARD) {
742 continue;
743 }
744 for (const auto& listener : devListeners_) {
745 CHKPC(listener);
746 NotifyMessage(listener, item.first, enable ? "add" : "remove");
747 }
748 }
749 }
750 for (const auto &item : inputDevice_) {
751 if (item.second.isPointerDevice && item.second.enable) {
752 NotifyPointerDevice(true, true, false);
753 break;
754 }
755 }
756 return RET_OK;
757 }
758
AddVirtualInputDevice(std::shared_ptr<InputDevice> device,int32_t & deviceId)759 int32_t InputDeviceManager::AddVirtualInputDevice(std::shared_ptr<InputDevice> device, int32_t &deviceId)
760 {
761 CALL_INFO_TRACE;
762 CHKPR(device, RET_ERR);
763 if (GenerateVirtualDeviceId(deviceId) != RET_OK) {
764 MMI_HILOGE("GenerateVirtualDeviceId failed");
765 deviceId = INVALID_DEVICE_ID;
766 return RET_ERR;
767 }
768 device->SetId(deviceId);
769 virtualInputDevices_[deviceId] = device;
770 MMI_HILOGI("AddVirtualInputDevice successfully, deviceId:%{public}d", deviceId);
771 for (const auto& item : devListeners_) {
772 CHKPC(item);
773 NotifyMessage(item, deviceId, "add");
774 }
775 InputDeviceInfo deviceInfo;
776 if (MakeVirtualDeviceInfo(device, deviceInfo) != RET_OK) {
777 MMI_HILOGE("MakeVirtualDeviceInfo failed");
778 return RET_ERR;
779 }
780 NotifyDevCallback(deviceId, deviceInfo);
781 DfxHisysevent::OnDeviceConnect(deviceId, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR);
782 return RET_OK;
783 }
784
RemoveVirtualInputDevice(int32_t deviceId)785 int32_t InputDeviceManager::RemoveVirtualInputDevice(int32_t deviceId)
786 {
787 CALL_INFO_TRACE;
788 auto iter = virtualInputDevices_.find(deviceId);
789 if (iter == virtualInputDevices_.end()) {
790 MMI_HILOGE("No virtual deviceId:%{public}d existed", deviceId);
791 return RET_ERR;
792 }
793 InputDeviceInfo deviceInfo;
794 if (MakeVirtualDeviceInfo(iter->second, deviceInfo) != RET_OK) {
795 MMI_HILOGE("MakeVirtualDeviceInfo failed");
796 return RET_ERR;
797 }
798 NotifyDevRemoveCallback(deviceId, deviceInfo);
799 virtualInputDevices_.erase(deviceId);
800 MMI_HILOGI("RemoveVirtualInputDevice successfully, deviceId:%{public}d", deviceId);
801 for (const auto& item : devListeners_) {
802 CHKPC(item);
803 NotifyMessage(item, deviceId, "remove");
804 }
805 DfxHisysevent::OnDeviceDisconnect(deviceId, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR);
806 return RET_OK;
807 }
808
MakeVirtualDeviceInfo(std::shared_ptr<InputDevice> device,InputDeviceInfo & deviceInfo)809 int32_t InputDeviceManager::MakeVirtualDeviceInfo(std::shared_ptr<InputDevice> device, InputDeviceInfo &deviceInfo)
810 {
811 CALL_INFO_TRACE;
812 CHKPR(device, ERROR_NULL_POINTER);
813 deviceInfo = {
814 .isRemote = false,
815 .isPointerDevice = device->HasCapability(InputDeviceCapability::INPUT_DEV_CAP_POINTER),
816 .isTouchableDevice = device->HasCapability(InputDeviceCapability::INPUT_DEV_CAP_TOUCH),
817 .enable = true,
818 };
819 return RET_OK;
820 }
821
GenerateVirtualDeviceId(int32_t & deviceId)822 int32_t InputDeviceManager::GenerateVirtualDeviceId(int32_t &deviceId)
823 {
824 CALL_INFO_TRACE;
825 static int32_t virtualDeviceId { MIN_VIRTUAL_INPUT_DEVICE_ID };
826 if (virtualInputDevices_.size() >= MAX_VIRTUAL_INPUT_DEVICE_NUM) {
827 MMI_HILOGE("Virtual device num exceeds limit:%{public}d", MAX_VIRTUAL_INPUT_DEVICE_NUM);
828 return RET_ERR;
829 }
830 if (virtualDeviceId == std::numeric_limits<int32_t>::max()) {
831 MMI_HILOGW("Request id exceeds the maximum");
832 virtualDeviceId = MIN_VIRTUAL_INPUT_DEVICE_ID;
833 }
834 deviceId = virtualDeviceId++;
835 if (virtualInputDevices_.find(deviceId) != virtualInputDevices_.end()) {
836 MMI_HILOGE("Repeated deviceId:%{public}d", deviceId);
837 deviceId = INVALID_DEVICE_ID;
838 return RET_ERR;
839 }
840 return RET_OK;
841 }
842
NotifyDevRemoveCallback(int32_t deviceId,const InputDeviceInfo & deviceInfo)843 void InputDeviceManager::NotifyDevRemoveCallback(int32_t deviceId, const InputDeviceInfo &deviceInfo)
844 {
845 CALL_DEBUG_ENTER;
846 if (auto sysUid = deviceInfo.sysUid; !sysUid.empty()) {
847 devCallbacks_(deviceId, sysUid, "remove");
848 MMI_HILOGI("Send device info to window manager, deivceId:%{public}d, status:remove", deviceId);
849 }
850 }
851
NotifyMessage(SessionPtr sess,int32_t id,const std::string & type)852 int32_t InputDeviceManager::NotifyMessage(SessionPtr sess, int32_t id, const std::string &type)
853 {
854 CALL_DEBUG_ENTER;
855 CHKPR(sess, ERROR_NULL_POINTER);
856 NetPacket pkt(MmiMessageId::ADD_INPUT_DEVICE_LISTENER);
857 pkt << type << id;
858 if (pkt.ChkRWError()) {
859 MMI_HILOGE("Packet write data failed");
860 return RET_ERR;
861 }
862 if (!sess->SendMsg(pkt)) {
863 MMI_HILOGE("Sending failed");
864 }
865 return RET_OK;
866 }
867
InitSessionLostCallback()868 void InputDeviceManager::InitSessionLostCallback()
869 {
870 if (sessionLostCallbackInitialized_) {
871 MMI_HILOGE("Init session is failed");
872 return;
873 }
874 auto udsServerPtr = InputHandler->GetUDSServer();
875 CHKPV(udsServerPtr);
876 udsServerPtr->AddSessionDeletedCallback([this] (SessionPtr session) {
877 return this->OnSessionLost(session);
878 }
879 );
880 sessionLostCallbackInitialized_ = true;
881 MMI_HILOGD("The callback on session deleted is registered successfully");
882 }
883
OnSessionLost(SessionPtr session)884 void InputDeviceManager::OnSessionLost(SessionPtr session)
885 {
886 CALL_DEBUG_ENTER;
887 devListeners_.remove(session);
888 }
889
IsPointerDevice(std::shared_ptr<InputDevice> inputDevice) const890 bool InputDeviceManager::IsPointerDevice(std::shared_ptr<InputDevice> inputDevice) const
891 {
892 CHKPR(inputDevice, false);
893 return inputDevice->HasCapability(InputDeviceCapability::INPUT_DEV_CAP_POINTER);
894 }
895
IsTouchableDevice(std::shared_ptr<InputDevice> inputDevice) const896 bool InputDeviceManager::IsTouchableDevice(std::shared_ptr<InputDevice> inputDevice) const
897 {
898 CHKPR(inputDevice, false);
899 return inputDevice->HasCapability(InputDeviceCapability::INPUT_DEV_CAP_TOUCH);
900 }
901
IsKeyboardDevice(std::shared_ptr<InputDevice> inputDevice) const902 bool InputDeviceManager::IsKeyboardDevice(std::shared_ptr<InputDevice> inputDevice) const
903 {
904 CHKPR(inputDevice, false);
905 return inputDevice->HasCapability(InputDeviceCapability::INPUT_DEV_CAP_KEYBOARD);
906 }
907
GetTouchPadIds()908 std::vector<int32_t> InputDeviceManager::GetTouchPadIds()
909 {
910 CALL_DEBUG_ENTER;
911 std::vector<int32_t> ids;
912 for (const auto &item : inputDevice_) {
913 auto inputDevice = item.second.inputDeviceOrigin;
914 if (inputDevice == nullptr) {
915 continue;
916 }
917 enum evdev_device_udev_tags udevTags = libinput_device_get_tags(inputDevice);
918 if ((udevTags & EVDEV_UDEV_TAG_TOUCHPAD) != 0) {
919 ids.push_back(item.first);
920 }
921 }
922 return ids;
923 }
924
GetTouchPadDeviceOrigin()925 struct libinput_device *InputDeviceManager::GetTouchPadDeviceOrigin()
926 {
927 CALL_DEBUG_ENTER;
928 struct libinput_device *touchPadDevice = nullptr;
929 for (const auto &item : inputDevice_) {
930 auto inputDevice = item.second.inputDeviceOrigin;
931 if (inputDevice == nullptr) {
932 continue;
933 }
934 enum evdev_device_udev_tags udevTags = libinput_device_get_tags(inputDevice);
935 if ((udevTags & EVDEV_UDEV_TAG_TOUCHPAD) != 0) {
936 touchPadDevice = inputDevice;
937 break;
938 }
939 }
940 return touchPadDevice;
941 }
942
GetMaskedDeviceId(const std::string & str)943 std::string InputDeviceManager::GetMaskedDeviceId(const std::string& str)
944 {
945 return GetMaskedStr(str, RESERVE_LEN);
946 }
947
GetMaskedStr(const std::string & str,size_t reserveLen)948 std::string InputDeviceManager::GetMaskedStr(const std::string& str, size_t reserveLen)
949 {
950 std::string mask("**");
951 if (static_cast<size_t>(str.length()) < reserveLen + reserveLen) {
952 return "";
953 }
954 return str.substr(0, reserveLen) + mask + str.substr(str.length() - reserveLen);
955 }
956 } // namespace MMI
957 } // namespace OHOS
958