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 <regex>
20
21 #include "input_event_handler.h"
22 #include "key_auto_repeat.h"
23 #include "util_ex.h"
24 #include "dfx_hisysevent_device.h"
25 #include "cursor_drawing_component.h"
26 #include "parameters.h"
27 #include "pointer_device_manager.h"
28 #include "special_input_device_parser.h"
29
30 #undef MMI_LOG_DOMAIN
31 #define MMI_LOG_DOMAIN MMI_LOG_SERVER
32 #undef MMI_LOG_TAG
33 #define MMI_LOG_TAG "InputDeviceManager"
34
35 namespace OHOS {
36 namespace MMI {
37 namespace {
38 constexpr int32_t INVALID_DEVICE_ID { -1 };
39 constexpr int32_t SUPPORT_KEY { 1 };
40 const char* INPUT_VIRTUAL_DEVICE_NAME { "DistributedInput " };
41 constexpr int32_t MIN_VIRTUAL_INPUT_DEVICE_ID { 1000 };
42 constexpr int32_t MAX_VIRTUAL_INPUT_DEVICE_NUM { 128 };
43 constexpr int32_t COMMON_PARAMETER_ERROR { 401 };
44
45 std::unordered_map<int32_t, std::string> axisType{
46 { ABS_MT_TOUCH_MAJOR, "TOUCH_MAJOR" }, { ABS_MT_TOUCH_MINOR, "TOUCH_MINOR" }, { ABS_MT_ORIENTATION, "ORIENTATION" },
47 { ABS_MT_POSITION_X, "POSITION_X" }, { ABS_MT_POSITION_Y, "POSITION_Y" }, { ABS_MT_PRESSURE, "PRESSURE" },
48 { ABS_MT_WIDTH_MAJOR, "WIDTH_MAJOR" }, { ABS_MT_WIDTH_MINOR, "WIDTH_MINOR" }
49 };
50
51 std::vector<std::pair<enum libinput_device_capability, InputDeviceCapability>> devCapEnumMaps{
52 { LIBINPUT_DEVICE_CAP_KEYBOARD, InputDeviceCapability::INPUT_DEV_CAP_KEYBOARD },
53 { LIBINPUT_DEVICE_CAP_POINTER, InputDeviceCapability::INPUT_DEV_CAP_POINTER },
54 { LIBINPUT_DEVICE_CAP_TOUCH, InputDeviceCapability::INPUT_DEV_CAP_TOUCH },
55 { LIBINPUT_DEVICE_CAP_TABLET_TOOL, InputDeviceCapability::INPUT_DEV_CAP_TABLET_TOOL },
56 { LIBINPUT_DEVICE_CAP_TABLET_PAD, InputDeviceCapability::INPUT_DEV_CAP_TABLET_PAD },
57 { LIBINPUT_DEVICE_CAP_GESTURE, InputDeviceCapability::INPUT_DEV_CAP_GESTURE },
58 { LIBINPUT_DEVICE_CAP_SWITCH, InputDeviceCapability::INPUT_DEV_CAP_SWITCH },
59 { LIBINPUT_DEVICE_CAP_JOYSTICK, InputDeviceCapability::INPUT_DEV_CAP_JOYSTICK },
60 };
61
62 constexpr size_t EXPECTED_N_SUBMATCHES{ 2 };
63 constexpr size_t EXPECTED_SUBMATCH{ 1 };
64 } // namespace
65
66 std::shared_ptr<InputDeviceManager> InputDeviceManager::instance_ = nullptr;
67 std::mutex InputDeviceManager::mutex_;
68
GetInstance()69 std::shared_ptr<InputDeviceManager> InputDeviceManager::GetInstance()
70 {
71 if (instance_ == nullptr) {
72 std::lock_guard<std::mutex> lock(mutex_);
73 if (instance_ == nullptr) {
74 instance_ = std::make_shared<InputDeviceManager>();
75 }
76 }
77 return instance_;
78 }
79
GetInputDevice(int32_t deviceId,bool checked) const80 std::shared_ptr<InputDevice> InputDeviceManager::GetInputDevice(int32_t deviceId, bool checked) const
81 {
82 CALL_DEBUG_ENTER;
83 if (virtualInputDevices_.find(deviceId) != virtualInputDevices_.end()) {
84 MMI_HILOGI("Virtual device with id:%{public}d", deviceId);
85 std::shared_ptr<InputDevice> dev = virtualInputDevices_.at(deviceId);
86 CHKPP(dev);
87 MMI_HILOGI("DeviceId:%{public}d, name:%{public}s", dev->GetId(), dev->GetName().c_str());
88 return dev;
89 }
90 auto iter = inputDevice_.find(deviceId);
91 if (iter == inputDevice_.end()) {
92 MMI_HILOGE("Failed to search for the device");
93 return nullptr;
94 }
95 if (checked && !iter->second.enable) {
96 MMI_HILOGE("The current device has been disabled");
97 return nullptr;
98 }
99 std::shared_ptr<InputDevice> inputDevice = std::make_shared<InputDevice>();
100 inputDevice->SetId(iter->first);
101 struct libinput_device *inputDeviceOrigin = iter->second.inputDeviceOrigin;
102 FillInputDevice(inputDevice, inputDeviceOrigin);
103 #ifdef OHOS_BUILD_ENABLE_VKEYBOARD
104 FillInputDeviceWithVirtualCapability(inputDevice, iter->second);
105 #endif // OHOS_BUILD_ENABLE_VKEYBOARD
106
107 InputDevice::AxisInfo axis;
108 for (const auto &item : axisType) {
109 int32_t min = libinput_device_get_axis_min(inputDeviceOrigin, item.first);
110 if (min == -1) {
111 MMI_HILOGD("The device does not support this axis");
112 continue;
113 }
114 if (item.first == ABS_MT_PRESSURE) {
115 axis.SetMinimum(0);
116 axis.SetMaximum(1);
117 } else {
118 axis.SetMinimum(min);
119 axis.SetMaximum(libinput_device_get_axis_max(inputDeviceOrigin, item.first));
120 }
121 axis.SetAxisType(item.first);
122 axis.SetFuzz(libinput_device_get_axis_fuzz(inputDeviceOrigin, item.first));
123 axis.SetFlat(libinput_device_get_axis_flat(inputDeviceOrigin, item.first));
124 axis.SetResolution(libinput_device_get_axis_resolution(inputDeviceOrigin, item.first));
125 inputDevice->AddAxisInfo(axis);
126 }
127 return inputDevice;
128 }
129
FillInputDevice(std::shared_ptr<InputDevice> inputDevice,libinput_device * deviceOrigin) const130 void InputDeviceManager::FillInputDevice(std::shared_ptr<InputDevice> inputDevice, libinput_device *deviceOrigin) const
131 {
132 CHKPV(inputDevice);
133 CHKPV(deviceOrigin);
134 inputDevice->SetType(static_cast<int32_t>(libinput_device_get_tags(deviceOrigin)));
135 const char *name = libinput_device_get_name(deviceOrigin);
136 inputDevice->SetName((name == nullptr) ? ("null") : (name));
137 inputDevice->SetBus(libinput_device_get_id_bustype(deviceOrigin));
138 inputDevice->SetVersion(libinput_device_get_id_version(deviceOrigin));
139 inputDevice->SetProduct(libinput_device_get_id_product(deviceOrigin));
140 inputDevice->SetVendor(libinput_device_get_id_vendor(deviceOrigin));
141 const char *phys = libinput_device_get_phys(deviceOrigin);
142 inputDevice->SetPhys((phys == nullptr) ? ("null") : (phys));
143 const char *uniq = libinput_device_get_uniq(deviceOrigin);
144 inputDevice->SetUniq((uniq == nullptr) ? ("null") : (uniq));
145
146 for (const auto &[first, second] : devCapEnumMaps) {
147 if (libinput_device_has_capability(deviceOrigin, first)) {
148 inputDevice->AddCapability(second);
149 }
150 }
151 }
152
GetInputDeviceIds() const153 std::vector<int32_t> InputDeviceManager::GetInputDeviceIds() const
154 {
155 CALL_DEBUG_ENTER;
156 std::vector<int32_t> ids;
157 for (const auto &item : inputDevice_) {
158 ids.push_back(item.first);
159 }
160 for (const auto &item : virtualInputDevices_) {
161 ids.push_back(item.first);
162 }
163 return ids;
164 }
165
SupportKeys(int32_t deviceId,std::vector<int32_t> & keyCodes,std::vector<bool> & keystroke)166 int32_t InputDeviceManager::SupportKeys(int32_t deviceId, std::vector<int32_t> &keyCodes, std::vector<bool> &keystroke)
167 {
168 CALL_DEBUG_ENTER;
169 auto iter = inputDevice_.find(deviceId);
170 if (iter == inputDevice_.end()) {
171 return COMMON_PARAMETER_ERROR;
172 }
173 if (!iter->second.enable) {
174 MMI_HILOGE("The current device has been disabled");
175 return RET_ERR;
176 }
177 for (const auto &item : keyCodes) {
178 bool ret = false;
179 for (const auto &it : KeyMapMgr->InputTransferKeyValue(deviceId, item)) {
180 ret |= libinput_device_has_key(iter->second.inputDeviceOrigin, it) == SUPPORT_KEY;
181 }
182 keystroke.push_back(ret);
183 }
184 return RET_OK;
185 }
186
IsMatchKeys(struct libinput_device * device,const std::vector<int32_t> & keyCodes) const187 bool InputDeviceManager::IsMatchKeys(struct libinput_device *device, const std::vector<int32_t> &keyCodes) const
188 {
189 CHKPF(device);
190 for (const auto &key : keyCodes) {
191 int32_t value = InputTransformationKeyValue(key);
192 if (libinput_device_keyboard_has_key(device, value) == SUPPORT_KEY) {
193 return true;
194 }
195 }
196 return false;
197 }
198
GetDeviceConfig(int32_t deviceId,int32_t & keyboardType)199 bool InputDeviceManager::GetDeviceConfig(int32_t deviceId, int32_t &keyboardType)
200 {
201 CALL_DEBUG_ENTER;
202 if (auto iter = inputDevice_.find(deviceId); iter == inputDevice_.end()) {
203 MMI_HILOGE("Failed to search for the deviceId");
204 return false;
205 }
206 auto deviceConfig = KeyRepeat->GetDeviceConfig();
207 auto it = deviceConfig.find(deviceId);
208 if (it == deviceConfig.end()) {
209 MMI_HILOGD("Failed to obtain the keyboard type of the configuration file");
210 return false;
211 }
212 keyboardType = it->second.keyboardType;
213 MMI_HILOGD("Get keyboard type results from the configuration file:%{public}d", keyboardType);
214 return true;
215 }
216
GetKeyboardBusMode(int32_t deviceId)217 int32_t InputDeviceManager::GetKeyboardBusMode(int32_t deviceId)
218 {
219 CALL_DEBUG_ENTER;
220 std::shared_ptr dev = GetInputDevice(deviceId);
221 CHKPR(dev, ERROR_NULL_POINTER);
222 return dev->GetBus();
223 }
224
GetDeviceSupportKey(int32_t deviceId,int32_t & keyboardType)225 int32_t InputDeviceManager::GetDeviceSupportKey(int32_t deviceId, int32_t &keyboardType)
226 {
227 CALL_DEBUG_ENTER;
228 std::vector<int32_t> keyCodes;
229 keyCodes.push_back(KeyEvent::KEYCODE_Q);
230 keyCodes.push_back(KeyEvent::KEYCODE_NUMPAD_1);
231 keyCodes.push_back(KeyEvent::KEYCODE_HOME);
232 keyCodes.push_back(KeyEvent::KEYCODE_CTRL_LEFT);
233 keyCodes.push_back(KeyEvent::KEYCODE_SHIFT_RIGHT);
234 keyCodes.push_back(KeyEvent::KEYCODE_F20);
235 std::vector<bool> supportKey;
236 int32_t ret = SupportKeys(deviceId, keyCodes, supportKey);
237 if (ret != RET_OK) {
238 MMI_HILOGE("SupportKey call failed");
239 return ret;
240 }
241 std::map<int32_t, bool> determineKbType;
242 for (size_t i = 0; i < keyCodes.size(); i++) {
243 determineKbType[keyCodes[i]] = supportKey[i];
244 }
245 if (determineKbType[KeyEvent::KEYCODE_HOME] && GetKeyboardBusMode(deviceId) == BUS_BLUETOOTH) {
246 keyboardType = KEYBOARD_TYPE_REMOTECONTROL;
247 MMI_HILOGD("The keyboard type is remote control:%{public}d", keyboardType);
248 } else if (determineKbType[KeyEvent::KEYCODE_NUMPAD_1] &&
249 !determineKbType[KeyEvent::KEYCODE_CTRL_LEFT] &&
250 !determineKbType[KeyEvent::KEYCODE_Q]) {
251 keyboardType = KEYBOARD_TYPE_DIGITALKEYBOARD;
252 MMI_HILOGD("The keyboard type is digital keyboard:%{public}d", keyboardType);
253 } else if (determineKbType[KeyEvent::KEYCODE_Q]) {
254 keyboardType = KEYBOARD_TYPE_ALPHABETICKEYBOARD;
255 MMI_HILOGD("The keyboard type is standard:%{public}d", keyboardType);
256 } else if (determineKbType[KeyEvent::KEYCODE_CTRL_LEFT] && determineKbType[KeyEvent::KEYCODE_SHIFT_RIGHT] &&
257 determineKbType[KeyEvent::KEYCODE_F20]) {
258 keyboardType = KEYBOARD_TYPE_HANDWRITINGPEN;
259 MMI_HILOGD("The keyboard type is handwriting pen:%{public}d", keyboardType);
260 } else {
261 keyboardType = KEYBOARD_TYPE_UNKNOWN;
262 MMI_HILOGD("Undefined keyboard type");
263 }
264 MMI_HILOGD("Get keyboard type results by supporting keys:%{public}d", keyboardType);
265 return RET_OK;
266 }
267
GetKeyboardType(int32_t deviceId,int32_t & keyboardType)268 int32_t InputDeviceManager::GetKeyboardType(int32_t deviceId, int32_t &keyboardType)
269 {
270 CALL_DEBUG_ENTER;
271 if (GetVirtualKeyboardType(deviceId, keyboardType) == RET_OK) {
272 return RET_OK;
273 }
274 int32_t tempKeyboardType = KEYBOARD_TYPE_NONE;
275 auto iter = inputDevice_.find(deviceId);
276 if (iter == inputDevice_.end()) {
277 MMI_HILOGD("Failed to search for the deviceID");
278 return COMMON_PARAMETER_ERROR;
279 }
280 if (!iter->second.enable) {
281 MMI_HILOGE("The current device has been disabled");
282 return RET_ERR;
283 }
284 if (GetDeviceConfig(deviceId, tempKeyboardType)) {
285 keyboardType = tempKeyboardType;
286 return RET_OK;
287 }
288 #ifdef OHOS_BUILD_ENABLE_VKEYBOARD
289 if (GetTouchscreenKeyboardType(iter->second, keyboardType) == RET_OK) {
290 return RET_OK;
291 }
292 #endif // OHOS_BUILD_ENABLE_VKEYBOARD
293 return GetDeviceSupportKey(deviceId, keyboardType);
294 }
295
SetInputStatusChangeCallback(inputDeviceCallback callback)296 void InputDeviceManager::SetInputStatusChangeCallback(inputDeviceCallback callback)
297 {
298 CALL_DEBUG_ENTER;
299 devCallbacks_ = callback;
300 }
301
AddDevListener(SessionPtr sess)302 void InputDeviceManager::AddDevListener(SessionPtr sess)
303 {
304 CALL_DEBUG_ENTER;
305 InitSessionLostCallback();
306 devListeners_.push_back(sess);
307 }
308
RemoveDevListener(SessionPtr sess)309 void InputDeviceManager::RemoveDevListener(SessionPtr sess)
310 {
311 CALL_DEBUG_ENTER;
312 devListeners_.remove(sess);
313 }
314
315 #ifdef OHOS_BUILD_ENABLE_POINTER_DRAWING
HasPointerDevice()316 bool InputDeviceManager::HasPointerDevice()
317 {
318 for (auto it = inputDevice_.begin(); it != inputDevice_.end(); ++it) {
319 if (it->second.isPointerDevice) {
320 return true;
321 }
322 }
323 return false;
324 }
325
HasVirtualPointerDevice()326 bool InputDeviceManager::HasVirtualPointerDevice()
327 {
328 for (auto it = virtualInputDevices_.begin(); it != virtualInputDevices_.end(); ++it) {
329 if (IsPointerDevice(it->second)) {
330 return true;
331 }
332 }
333 return false;
334 }
335 #endif // OHOS_BUILD_ENABLE_POINTER_DRAWING
336
337 #ifdef OHOS_BUILD_ENABLE_VKEYBOARD
HasVirtualKeyboardDevice()338 bool InputDeviceManager::HasVirtualKeyboardDevice()
339 {
340 for (auto it = virtualInputDevices_.begin(); it != virtualInputDevices_.end(); ++it) {
341 if (IsKeyboardDevice(it->second)) {
342 return true;
343 }
344 }
345 return false;
346 }
347 #endif // OHOS_BUILD_ENABLE_VKEYBOARD
348
HasTouchDevice()349 bool InputDeviceManager::HasTouchDevice()
350 {
351 CALL_DEBUG_ENTER;
352 for (auto it = inputDevice_.begin(); it != inputDevice_.end(); ++it) {
353 if (it->second.isTouchableDevice) {
354 return true;
355 }
356 }
357 return false;
358 }
359
GetInputIdentification(struct libinput_device * inputDevice)360 std::string InputDeviceManager::GetInputIdentification(struct libinput_device *inputDevice)
361 {
362 CALL_DEBUG_ENTER;
363 int32_t deviceVendor = libinput_device_get_id_vendor(inputDevice);
364 int32_t deviceProduct = libinput_device_get_id_product(inputDevice);
365 struct udev_device *udevDevice = libinput_device_get_udev_device(inputDevice);
366 std::string sysPath = udev_device_get_syspath(udevDevice);
367 udev_device_unref(udevDevice);
368 if ((deviceVendor < 0) || (deviceProduct < 0) || sysPath.empty()) {
369 MMI_HILOGE("Get device identification failed");
370 return "";
371 }
372 const size_t bufSize = 10;
373 char vid[bufSize] = "";
374 char pid[bufSize] = "";
375 sprintf_s(vid, sizeof(vid), "%04X", deviceVendor);
376 sprintf_s(pid, sizeof(pid), "%04X", deviceProduct);
377 std::string strVid(vid);
378 std::string strPid(pid);
379 std::string vendorProduct = strVid + ":" + strPid;
380 std::string deviceIdentification = sysPath.substr(0, sysPath.find(vendorProduct)) + vendorProduct;
381 MMI_HILOGI("Device identification is:%{public}s", deviceIdentification.c_str());
382 return deviceIdentification;
383 }
384
NotifyDevCallback(int32_t deviceId,struct InputDeviceInfo inDevice)385 void InputDeviceManager::NotifyDevCallback(int32_t deviceId, struct InputDeviceInfo inDevice)
386 {
387 #ifdef OHOS_BUILD_ENABLE_KEYBOARD_EXT_FLAG
388 NotifyDevCallbackExt(deviceId, inDevice.inputDeviceOrigin);
389 #endif // OHOS_BUILD_ENABLE_KEYBOARD_EXT_FLAG
390 if (!inDevice.isTouchableDevice || (deviceId < 0)) {
391 MMI_HILOGI("The device is not touchable device already existent");
392 return;
393 }
394 std::string name = "null";
395 if (inDevice.inputDeviceOrigin != nullptr) {
396 name = libinput_device_get_name(inDevice.inputDeviceOrigin);
397 }
398 if (!inDevice.sysUid.empty()) {
399 CHKPV(devCallbacks_);
400 devCallbacks_(deviceId, name, inDevice.sysUid, "add");
401 MMI_HILOGI("Send device info to window manager, device id:%{public}d, name:%{private}s,"
402 "system uid:%s, status:add", deviceId, name.c_str(), inDevice.sysUid.c_str());
403 } else {
404 MMI_HILOGE("Get device system uid id is empty, deviceId:%{public}d", deviceId);
405 }
406 }
407
ParseDeviceId(struct libinput_device * inputDevice)408 int32_t InputDeviceManager::ParseDeviceId(struct libinput_device *inputDevice)
409 {
410 CALL_DEBUG_ENTER;
411 std::regex pattern("^event(\\d+)$");
412 std::smatch mr;
413 const char *sysName = libinput_device_get_sysname(inputDevice);
414 CHKPR(sysName, RET_ERR);
415 std::string strName(sysName);
416 if (std::regex_match(strName, mr, pattern)) {
417 if (mr.ready() && mr.size() == EXPECTED_N_SUBMATCHES) {
418 return std::stoi(mr[EXPECTED_SUBMATCH].str());
419 }
420 }
421 std::string errStr = "Parsing strName failed: \'" + strName + "\'";
422 MMI_HILOGE("%{public}s", errStr.c_str());
423 #ifdef OHOS_BUILD_ENABLE_DFX_RADAR
424 DfxHisyseventDevice::ReportDeviceFault(DfxHisyseventDevice::DeviceFaultType::DEVICE_FAULT_TYPE_INNER, errStr);
425 #endif
426 return RET_ERR;
427 }
428
OnInputDeviceAdded(struct libinput_device * inputDevice)429 void InputDeviceManager::OnInputDeviceAdded(struct libinput_device *inputDevice)
430 {
431 CALL_DEBUG_ENTER;
432 CHKPV(inputDevice);
433 if (CheckDuplicateInputDevice(inputDevice)) {
434 return;
435 }
436 // if we have enabled physical/virtual pointer before adding this one.
437 bool existEnabledPointerDevice = HasEnabledPhysicalPointerDevice();
438 #ifdef OHOS_BUILD_ENABLE_POINTER_DRAWING
439 // parse virtual devices for pointer devices.
440 if (HasVirtualPointerDevice()) {
441 existEnabledPointerDevice = true;
442 }
443 #endif // OHOS_BUILD_ENABLE_POINTER_DRAWING
444 int32_t deviceId = ParseDeviceId(inputDevice);
445 if (deviceId < 0) {
446 return;
447 }
448 struct InputDeviceInfo info;
449 MakeDeviceInfo(inputDevice, info);
450 AddPhysicalInputDeviceInner(deviceId, info);
451 MMI_HILOGI("OnInputDeviceAdded successfully, deviceId:%{public}d, info.sysUid:%{public}s, info.enable:%{public}d",
452 deviceId, info.sysUid.c_str(), info.enable);
453 if (info.enable) {
454 NotifyAddDeviceListeners(deviceId);
455 }
456 NotifyDeviceAdded(deviceId);
457 NotifyDevCallback(deviceId, info);
458 NotifyAddPointerDevice(info.isPointerDevice, existEnabledPointerDevice);
459 #ifdef OHOS_BUILD_ENABLE_DFX_RADAR
460 DfxHisyseventDevice::ReportDeviceBehavior(deviceId, "Device added successfully");
461 #endif
462 }
463
MakeDeviceInfo(struct libinput_device * inputDevice,struct InputDeviceInfo & info)464 void InputDeviceManager::MakeDeviceInfo(struct libinput_device *inputDevice, struct InputDeviceInfo &info)
465 {
466 info.inputDeviceOrigin = inputDevice;
467 info.isRemote = IsRemote(inputDevice);
468 info.enable = info.isRemote ? false : true;
469 info.isPointerDevice = IsPointerDevice(inputDevice);
470 info.isTouchableDevice = IsTouchDevice(inputDevice);
471 info.sysUid = GetInputIdentification(inputDevice);
472 #ifndef OHOS_BUILD_ENABLE_WATCH
473 info.vendorConfig = configManagement_.GetVendorConfig(inputDevice);
474 #endif // OHOS_BUILD_ENABLE_WATCH
475 }
476
OnInputDeviceRemoved(struct libinput_device * inputDevice)477 void InputDeviceManager::OnInputDeviceRemoved(struct libinput_device *inputDevice)
478 {
479 CALL_DEBUG_ENTER;
480 CHKPV(inputDevice);
481 int32_t deviceId = INVALID_DEVICE_ID;
482 bool enable = false;
483 RemovePhysicalInputDeviceInner(inputDevice, deviceId, enable);
484 std::string sysUid = GetInputIdentification(inputDevice);
485 if (!sysUid.empty()) {
486 #ifdef OHOS_BUILD_ENABLE_KEYBOARD_EXT_FLAG
487 NotifyDevRemoveCallbackExt(deviceId);
488 #endif // OHOS_BUILD_ENABLE_KEYBOARD_EXT_FLAG
489 std::string name = libinput_device_get_name(inputDevice);
490 CHKPV(devCallbacks_);
491 devCallbacks_(deviceId, name, sysUid, "remove");
492 MMI_HILOGI("Send device info to window manager, device id:%{public}d, name:%{private}s, system uid:%s, "
493 "status:remove", deviceId, name.c_str(), sysUid.c_str());
494 }
495
496 NotifyRemovePointerDevice(IsPointerDevice(inputDevice));
497 if (enable) {
498 NotifyRemoveDeviceListeners(deviceId);
499 }
500 NotifyDeviceRemoved(deviceId);
501 ScanPointerDevice();
502 if (deviceId == INVALID_DEVICE_ID) {
503 #ifdef OHOS_BUILD_ENABLE_DFX_RADAR
504 DfxHisyseventDevice::ReportDeviceFault(DfxHisyseventDevice::DeviceFaultType::DEVICE_FAULT_TYPE_INNER,
505 "Device reomved failed becaused of not found");
506 #endif
507 }
508 }
509
ScanPointerDevice()510 void InputDeviceManager::ScanPointerDevice()
511 {
512 bool existEnabledPointerDevice = HasEnabledPhysicalPointerDevice();
513 #ifdef OHOS_BUILD_ENABLE_POINTER_DRAWING
514 // parse virtual devices for pointer devices.
515 if (HasVirtualPointerDevice()) {
516 existEnabledPointerDevice = true;
517 }
518 #endif // OHOS_BUILD_ENABLE_POINTER_DRAWING
519 if (!existEnabledPointerDevice) {
520 NotifyPointerDevice(false, false, true);
521 OHOS::system::SetParameter(INPUT_POINTER_DEVICES, "false");
522 MMI_HILOGI("Set para input.pointer.device false");
523 if (POINTER_DEV_MGR.isInit) {
524 POINTER_DEV_MGR.isInit = false;
525 CursorDrawingComponent::GetInstance().UnLoad();
526 }
527 }
528 }
529
IsPointerDevice(struct libinput_device * device) const530 bool InputDeviceManager::IsPointerDevice(struct libinput_device *device) const
531 {
532 CHKPF(device);
533 enum evdev_device_udev_tags udevTags = libinput_device_get_tags(device);
534 MMI_HILOGD("The current device udev tag:%{public}d", static_cast<int32_t>(udevTags));
535 std::string name = libinput_device_get_name(device);
536 if (bool isPointerDevice = false; SPECIAL_INPUT_DEVICE_PARSER.IsPointerDevice(name, isPointerDevice) == RET_OK) {
537 return isPointerDevice;
538 }
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
IsKeyboardDevice(struct libinput_device * device) const543 bool InputDeviceManager::IsKeyboardDevice(struct libinput_device *device) const
544 {
545 CHKPF(device);
546 enum evdev_device_udev_tags udevTags = libinput_device_get_tags(device);
547 MMI_HILOGD("The current device udev tag:%{public}d", static_cast<int32_t>(udevTags));
548 return udevTags & EVDEV_UDEV_TAG_KEYBOARD;
549 }
550
IsTouchDevice(struct libinput_device * device) const551 bool InputDeviceManager::IsTouchDevice(struct libinput_device *device) const
552 {
553 CHKPF(device);
554 return libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TOUCH);
555 }
556
IsTouchPadDevice(struct libinput_device * device) const557 bool InputDeviceManager::IsTouchPadDevice(struct libinput_device *device) const
558 {
559 CHKPF(device);
560 enum evdev_device_udev_tags udevTags = libinput_device_get_tags(device);
561 return udevTags & EVDEV_UDEV_TAG_TOUCHPAD;
562 }
563
Attach(std::shared_ptr<IDeviceObserver> observer)564 void InputDeviceManager::Attach(std::shared_ptr<IDeviceObserver> observer)
565 {
566 CALL_DEBUG_ENTER;
567 observers_.push_back(observer);
568 }
569
Detach(std::shared_ptr<IDeviceObserver> observer)570 void InputDeviceManager::Detach(std::shared_ptr<IDeviceObserver> observer)
571 {
572 CALL_DEBUG_ENTER;
573 observers_.remove(observer);
574 }
575
NotifyPointerDevice(bool hasPointerDevice,bool isVisible,bool isHotPlug)576 void InputDeviceManager::NotifyPointerDevice(bool hasPointerDevice, bool isVisible, bool isHotPlug)
577 {
578 MMI_HILOGI("The observers_ size:%{public}zu", observers_.size());
579 for (auto observer = observers_.begin(); observer != observers_.end(); observer++) {
580 CHKPV(*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
GetMultiKeyboardDevice(std::vector<struct libinput_device * > & inputDevice)616 void InputDeviceManager::GetMultiKeyboardDevice(std::vector<struct libinput_device*> &inputDevice)
617 {
618 CALL_DEBUG_ENTER;
619 std::vector<int32_t> keyCodes;
620 keyCodes.push_back(KeyEvent::KEYCODE_Q);
621 keyCodes.push_back(KeyEvent::KEYCODE_NUMPAD_1);
622 for (const auto &item : inputDevice_) {
623 const auto &device = item.second.inputDeviceOrigin;
624 if (IsMatchKeys(device, keyCodes)) {
625 MMI_HILOGI("Find keyboard device success id %{public}d", item.first);
626 inputDevice.push_back(device);
627 }
628 }
629 }
630
Dump(int32_t fd,const std::vector<std::string> & args)631 void InputDeviceManager::Dump(int32_t fd, const std::vector<std::string> &args)
632 {
633 CALL_DEBUG_ENTER;
634 mprintf(fd, "Device information:\t");
635 mprintf(fd, "Input devices: count=%zu", inputDevice_.size());
636 mprintf(fd, "Virtual input devices: count=%zu", virtualInputDevices_.size());
637 std::vector<int32_t> deviceIds = GetInputDeviceIds();
638 for (auto deviceId : deviceIds) {
639 std::shared_ptr<InputDevice> inputDevice = GetInputDevice(deviceId, false);
640 CHKPV(inputDevice);
641 mprintf(fd,
642 "deviceId:%d | deviceName:%s | deviceType:%d | bus:%d | version:%d "
643 "| product:%d | vendor:%d | phys:%s\t",
644 inputDevice->GetId(), inputDevice->GetName().c_str(), inputDevice->GetType(), inputDevice->GetBus(),
645 inputDevice->GetVersion(), inputDevice->GetProduct(), inputDevice->GetVendor(),
646 inputDevice->GetPhys().c_str());
647 std::vector<InputDevice::AxisInfo> axisinfo = inputDevice->GetAxisInfo();
648 mprintf(fd, "axis: count=%zu", axisinfo.size());
649 for (const auto &axis : axisinfo) {
650 auto iter = axisType.find(axis.GetAxisType());
651 if (iter == axisType.end()) {
652 MMI_HILOGE("The axisType is not found");
653 return;
654 }
655 mprintf(fd, "\t axisType:%s | minimum:%d | maximum:%d | fuzz:%d | flat:%d | resolution:%d\t",
656 iter->second.c_str(), axis.GetMinimum(), axis.GetMaximum(), axis.GetFuzz(), axis.GetFlat(),
657 axis.GetResolution());
658 }
659 }
660 }
661
DumpDeviceList(int32_t fd,const std::vector<std::string> & args)662 void InputDeviceManager::DumpDeviceList(int32_t fd, const std::vector<std::string> &args)
663 {
664 CALL_DEBUG_ENTER;
665 std::vector<int32_t> ids = GetInputDeviceIds();
666 mprintf(fd, "Total device:%zu, Device list:\t", ids.size());
667 for (const auto &item : inputDevice_) {
668 std::shared_ptr<InputDevice> inputDevice = GetInputDevice(item.first, false);
669 CHKPV(inputDevice);
670 int32_t deviceId = inputDevice->GetId();
671 mprintf(fd, "deviceId:%d | deviceName:%s | deviceType:%d | bus:%d | version:%d | product:%d | vendor:%d\t",
672 deviceId, inputDevice->GetName().c_str(), inputDevice->GetType(), inputDevice->GetBus(),
673 inputDevice->GetVersion(), inputDevice->GetProduct(), inputDevice->GetVendor());
674 }
675 }
676
IsRemote(struct libinput_device * inputDevice) const677 bool InputDeviceManager::IsRemote(struct libinput_device *inputDevice) const
678 {
679 CHKPF(inputDevice);
680 bool isRemote = false;
681 const char *name = libinput_device_get_name(inputDevice);
682 if (name == nullptr || name[0] == '\0') {
683 MMI_HILOGD("Device name is empty");
684 return false;
685 }
686 std::string strName = name;
687 std::string::size_type pos = strName.find(INPUT_VIRTUAL_DEVICE_NAME);
688 if (pos != std::string::npos) {
689 isRemote = true;
690 }
691 MMI_HILOGD("The isRemote:%{public}s", isRemote ? "true" : "false");
692 return isRemote;
693 }
694
IsRemote(int32_t id) const695 bool InputDeviceManager::IsRemote(int32_t id) const
696 {
697 bool isRemote = false;
698 auto device = inputDevice_.find(id);
699 if (device != inputDevice_.end()) {
700 isRemote = device->second.isRemote;
701 }
702 MMI_HILOGD("The isRemote:%{public}s", isRemote ? "true" : "false");
703 return isRemote;
704 }
705
GetVendorConfig(int32_t deviceId) const706 VendorConfig InputDeviceManager::GetVendorConfig(int32_t deviceId) const
707 {
708 CALL_DEBUG_ENTER;
709 auto it = inputDevice_.find(deviceId);
710 if (it == inputDevice_.end()) {
711 MMI_HILOGE("Device info not find id:%{public}d", deviceId);
712 return {};
713 }
714 return it->second.vendorConfig;
715 }
716
OnEnableInputDevice(bool enable)717 int32_t InputDeviceManager::OnEnableInputDevice(bool enable)
718 {
719 CALL_DEBUG_ENTER;
720 MMI_HILOGD("Enable input device:%{public}s", enable ? "true" : "false");
721 for (auto &item : inputDevice_) {
722 if (item.second.isRemote && item.second.enable != enable) {
723 int32_t keyboardType = KEYBOARD_TYPE_NONE;
724 if (enable) {
725 item.second.enable = enable;
726 GetKeyboardType(item.first, keyboardType);
727 } else {
728 GetKeyboardType(item.first, keyboardType);
729 item.second.enable = enable;
730 }
731 if (keyboardType != KEYBOARD_TYPE_ALPHABETICKEYBOARD) {
732 continue;
733 }
734 for (const auto& listener : devListeners_) {
735 CHKPC(listener);
736 NotifyMessage(listener, item.first, enable ? "add" : "remove");
737 }
738 }
739 }
740 for (const auto &item : inputDevice_) {
741 if (item.second.isPointerDevice && item.second.enable) {
742 NotifyPointerDevice(true, true, false);
743 break;
744 }
745 }
746 return RET_OK;
747 }
748
AddVirtualInputDevice(std::shared_ptr<InputDevice> device,int32_t & deviceId)749 int32_t InputDeviceManager::AddVirtualInputDevice(std::shared_ptr<InputDevice> device, int32_t &deviceId)
750 {
751 CALL_INFO_TRACE;
752 CHKPR(device, RET_ERR);
753 if (CheckDuplicateInputDevice(device)) {
754 return RET_ERR;
755 }
756 // if we have enabled physical/virtual pointer before adding this one.
757 bool existEnabledPointerDevice = HasEnabledPhysicalPointerDevice();
758 #ifdef OHOS_BUILD_ENABLE_POINTER_DRAWING
759 // parse virtual devices for pointer devices.
760 if (HasVirtualPointerDevice()) {
761 existEnabledPointerDevice = true;
762 }
763 #endif // OHOS_BUILD_ENABLE_POINTER_DRAWING
764 if (GenerateVirtualDeviceId(deviceId) != RET_OK) {
765 MMI_HILOGE("GenerateVirtualDeviceId failed");
766 deviceId = INVALID_DEVICE_ID;
767 return RET_ERR;
768 }
769 InputDeviceInfo deviceInfo;
770 if (MakeVirtualDeviceInfo(device, deviceInfo) != RET_OK) {
771 MMI_HILOGE("MakeVirtualDeviceInfo failed");
772 return RET_ERR;
773 }
774 device->SetId(deviceId);
775 AddVirtualInputDeviceInner(deviceId, device);
776 MMI_HILOGI("AddVirtualInputDevice successfully, deviceId:%{public}d, deviceName=%{public}s",
777 deviceId, device->GetName().c_str());
778
779 // in current structure, virtual devices are always enabled.
780 NotifyAddDeviceListeners(deviceId);
781 NotifyDeviceAdded(deviceId);
782 NotifyDevCallback(deviceId, deviceInfo);
783 NotifyAddPointerDevice(deviceInfo.isPointerDevice, existEnabledPointerDevice);
784 #ifdef OHOS_BUILD_ENABLE_DFX_RADAR
785 DfxHisyseventDevice::ReportDeviceBehavior(deviceId, "AddVirtualInputDevice successfully");
786 #endif
787 return RET_OK;
788 }
789
CheckDuplicateInputDevice(struct libinput_device * inputDevice)790 bool InputDeviceManager::CheckDuplicateInputDevice(struct libinput_device *inputDevice)
791 {
792 CHKPF(inputDevice);
793 for (const auto &item : inputDevice_) {
794 if (item.second.inputDeviceOrigin == inputDevice) {
795 MMI_HILOGI("The device is already existent");
796 #ifdef OHOS_BUILD_ENABLE_DFX_RADAR
797 DfxHisyseventDevice::ReportDeviceFault(item.first,
798 DfxHisyseventDevice::DeviceFaultType::DEVICE_FAULT_TYPE_INNER,
799 "The device is already existent");
800 #endif
801 return true;
802 }
803 }
804 return false;
805 }
806
CheckDuplicateInputDevice(std::shared_ptr<InputDevice> inputDevice)807 bool InputDeviceManager::CheckDuplicateInputDevice(std::shared_ptr<InputDevice> inputDevice)
808 {
809 CHKPF(inputDevice);
810 for (const auto &item: virtualInputDevices_) {
811 CHKPC(item.second);
812 if (item.second->GetName() == inputDevice->GetName()) {
813 MMI_HILOGW("The virtual device already exists: %{public}s", inputDevice->GetName().c_str());
814 return true;
815 }
816 }
817 return false;
818 }
819
AddPhysicalInputDeviceInner(int32_t deviceId,const struct InputDeviceInfo & info)820 void InputDeviceManager::AddPhysicalInputDeviceInner(int32_t deviceId, const struct InputDeviceInfo& info)
821 {
822 inputDevice_[deviceId] = info;
823 }
824
AddVirtualInputDeviceInner(int32_t deviceId,std::shared_ptr<InputDevice> inputDevice)825 void InputDeviceManager::AddVirtualInputDeviceInner(int32_t deviceId, std::shared_ptr<InputDevice> inputDevice)
826 {
827 virtualInputDevices_[deviceId] = inputDevice;
828 }
829
RemovePhysicalInputDeviceInner(struct libinput_device * inputDevice,int32_t & deviceId,bool & enable)830 void InputDeviceManager::RemovePhysicalInputDeviceInner(
831 struct libinput_device *inputDevice, int32_t &deviceId, bool &enable)
832 {
833 CHKPV(inputDevice);
834 for (auto it = inputDevice_.begin(); it != inputDevice_.end(); ++it) {
835 if (it->second.inputDeviceOrigin == inputDevice) {
836 deviceId = it->first;
837 enable = it->second.enable;
838 #ifdef OHOS_BUILD_ENABLE_DFX_RADAR
839 DfxHisyseventDevice::ReportDeviceBehavior(deviceId, "Device removed successfully");
840 #endif
841 MMI_HILOGI("Device removed successfully, deviceId:%{public}d, sys uid:%{public}s", deviceId,
842 it->second.sysUid.c_str());
843 inputDevice_.erase(it);
844 break;
845 }
846 }
847 }
848
RemoveVirtualInputDeviceInner(int32_t deviceId,struct InputDeviceInfo & info)849 int32_t InputDeviceManager::RemoveVirtualInputDeviceInner(int32_t deviceId, struct InputDeviceInfo& info)
850 {
851 auto iter = virtualInputDevices_.find(deviceId);
852 if (iter == virtualInputDevices_.end()) {
853 MMI_HILOGE("No virtual deviceId:%{public}d existed", deviceId);
854 return RET_ERR;
855 }
856 if (MakeVirtualDeviceInfo(iter->second, info) != RET_OK) {
857 MMI_HILOGE("MakeVirtualDeviceInfo failed");
858 virtualInputDevices_.erase(iter);
859 return RET_ERR;
860 }
861 virtualInputDevices_.erase(iter);
862 return RET_OK;
863 }
864
HasEnabledPhysicalPointerDevice()865 bool InputDeviceManager::HasEnabledPhysicalPointerDevice()
866 {
867 for (const auto &item : inputDevice_) {
868 if ((!item.second.isRemote && item.second.isPointerDevice) ||
869 (item.second.isRemote && item.second.isPointerDevice && item.second.enable)) {
870 MMI_HILOGI("DeviceId:%{public}d, isRemote:%{public}d, sys uid:%{public}s", item.first,
871 item.second.isRemote, item.second.sysUid.c_str());
872 return true;
873 }
874 }
875 return false;
876 }
877
NotifyAddDeviceListeners(int32_t deviceId)878 void InputDeviceManager::NotifyAddDeviceListeners(int32_t deviceId)
879 {
880 for (const auto& item : devListeners_) {
881 CHKPC(item);
882 NotifyMessage(item, deviceId, "add");
883 }
884 }
885
NotifyRemoveDeviceListeners(int32_t deviceId)886 void InputDeviceManager::NotifyRemoveDeviceListeners(int32_t deviceId)
887 {
888 for (const auto& item : devListeners_) {
889 CHKPV(item);
890 NotifyMessage(item, deviceId, "remove");
891 }
892 }
893
PointerDeviceInit()894 void InputDeviceManager::PointerDeviceInit()
895 {
896 MMI_HILOGI("start");
897 #if defined(OHOS_BUILD_ENABLE_POINTER) && defined(OHOS_BUILD_ENABLE_POINTER_DRAWING)
898 if (!CursorDrawingComponent::GetInstance().Init()) {
899 MMI_HILOGE("Pointer draw init failed");
900 return;
901 }
902 #endif // OHOS_BUILD_ENABLE_POINTER && OHOS_BUILD_ENABLE_POINTER_DRAWING
903
904 #ifdef OHOS_BUILD_ENABLE_POINTER_DRAWING
905 auto proxy = POINTER_DEV_MGR.GetDelegateProxy();
906 if (proxy != nullptr) {
907 CursorDrawingComponent::GetInstance().SetDelegateProxy(proxy);
908 }
909 #endif // OHOS_BUILD_ENABLE_POINTER_DRAWING
910
911 #if defined(OHOS_BUILD_ENABLE_POINTER) && defined(OHOS_BUILD_ENABLE_POINTER_DRAWING)
912 CursorDrawingComponent::GetInstance().RegisterDisplayStatusReceiver();
913 POINTER_DEV_MGR.isFirstAddCommonEventService = false;
914 CursorDrawingComponent::GetInstance().InitPointerCallback();
915 POINTER_DEV_MGR.isFirstAddRenderService = false;
916 CursorDrawingComponent::GetInstance().InitScreenInfo();
917 CursorDrawingComponent::GetInstance().SubscribeScreenModeChange();
918 POINTER_DEV_MGR.isFirstAddDisplayManagerService = false;
919 CursorDrawingComponent::GetInstance().InitPointerObserver();
920 POINTER_DEV_MGR.isFirstAdddistributedKVDataService = false;
921 #endif // OHOS_BUILD_ENABLE_POINTER && OHOS_BUILD_ENABLE_POINTER_DRAWING
922 POINTER_DEV_MGR.isInit = true;
923 }
924
NotifyAddPointerDevice(bool addNewPointerDevice,bool existEnabledPointerDevice)925 void InputDeviceManager::NotifyAddPointerDevice(bool addNewPointerDevice, bool existEnabledPointerDevice)
926 {
927 MMI_HILOGI("AddNewPointerDevice:%{public}d, existEnabledPointerDevice:%{public}d", addNewPointerDevice,
928 existEnabledPointerDevice);
929 if (addNewPointerDevice && !POINTER_DEV_MGR.isInit) {
930 PointerDeviceInit();
931 }
932 if (addNewPointerDevice && !existEnabledPointerDevice) {
933 #if defined(OHOS_BUILD_ENABLE_POINTER) && defined(OHOS_BUILD_ENABLE_POINTER_DRAWING)
934 if (HasTouchDevice()) {
935 CursorDrawingComponent::GetInstance().SetMouseDisplayState(false);
936 }
937 #endif // OHOS_BUILD_ENABLE_POINTER && OHOS_BUILD_ENABLE_POINTER_DRAWING
938 NotifyPointerDevice(true, true, true);
939 OHOS::system::SetParameter(INPUT_POINTER_DEVICES, "true");
940 MMI_HILOGI("Set para input.pointer.device true");
941 }
942 #if defined(OHOS_BUILD_ENABLE_POINTER) && defined(OHOS_BUILD_ENABLE_POINTER_DRAWING)
943 if (addNewPointerDevice) {
944 WIN_MGR->UpdatePointerChangeAreas();
945 }
946 if (addNewPointerDevice && !existEnabledPointerDevice &&
947 CursorDrawingComponent::GetInstance().GetMouseDisplayState()) {
948 WIN_MGR->DispatchPointer(PointerEvent::POINTER_ACTION_ENTER_WINDOW);
949 }
950 #endif // OHOS_BUILD_ENABLE_POINTER && OHOS_BUILD_ENABLE_POINTER_DRAWING
951 }
952
NotifyRemovePointerDevice(bool removePointerDevice)953 void InputDeviceManager::NotifyRemovePointerDevice(bool removePointerDevice)
954 {
955 #if defined(OHOS_BUILD_ENABLE_POINTER) && defined(OHOS_BUILD_ENABLE_POINTER_DRAWING)
956 if (removePointerDevice && !HasPointerDevice() && !HasVirtualPointerDevice() &&
957 CursorDrawingComponent::GetInstance().GetMouseDisplayState()) {
958 WIN_MGR->DispatchPointer(PointerEvent::POINTER_ACTION_LEAVE_WINDOW);
959 }
960 #endif // OHOS_BUILD_ENABLE_POINTER && OHOS_BUILD_ENABLE_POINTER_DRAWING
961 }
962
RemoveVirtualInputDevice(int32_t deviceId)963 int32_t InputDeviceManager::RemoveVirtualInputDevice(int32_t deviceId)
964 {
965 CALL_INFO_TRACE;
966 InputDeviceInfo deviceInfo;
967 if (RemoveVirtualInputDeviceInner(deviceId, deviceInfo) == RET_ERR) {
968 return RET_ERR;
969 }
970 NotifyDevRemoveCallback(deviceId, deviceInfo);
971 MMI_HILOGI("RemoveVirtualInputDevice successfully, deviceId:%{public}d", deviceId);
972 NotifyRemovePointerDevice(deviceInfo.isPointerDevice);
973 NotifyRemoveDeviceListeners(deviceId);
974 NotifyDeviceRemoved(deviceId);
975 ScanPointerDevice();
976 #ifdef OHOS_BUILD_ENABLE_DFX_RADAR
977 DfxHisyseventDevice::ReportDeviceBehavior(deviceId, "RemoveVirtualInputDevice successfully");
978 #endif
979 return RET_OK;
980 }
981
MakeVirtualDeviceInfo(std::shared_ptr<InputDevice> device,InputDeviceInfo & deviceInfo)982 int32_t InputDeviceManager::MakeVirtualDeviceInfo(std::shared_ptr<InputDevice> device, InputDeviceInfo &deviceInfo)
983 {
984 CALL_INFO_TRACE;
985 CHKPR(device, ERROR_NULL_POINTER);
986 deviceInfo = {
987 .isRemote = false,
988 .isPointerDevice = device->HasCapability(InputDeviceCapability::INPUT_DEV_CAP_POINTER),
989 .isTouchableDevice = device->HasCapability(InputDeviceCapability::INPUT_DEV_CAP_TOUCH),
990 .enable = true,
991 };
992 return RET_OK;
993 }
994
GenerateVirtualDeviceId(int32_t & deviceId)995 int32_t InputDeviceManager::GenerateVirtualDeviceId(int32_t &deviceId)
996 {
997 CALL_INFO_TRACE;
998 static int32_t virtualDeviceId { MIN_VIRTUAL_INPUT_DEVICE_ID };
999 if (virtualInputDevices_.size() >= MAX_VIRTUAL_INPUT_DEVICE_NUM) {
1000 MMI_HILOGE("Virtual device num exceeds limit:%{public}d", MAX_VIRTUAL_INPUT_DEVICE_NUM);
1001 return RET_ERR;
1002 }
1003 if (virtualDeviceId == std::numeric_limits<int32_t>::max()) {
1004 MMI_HILOGW("Request id exceeds the maximum");
1005 virtualDeviceId = MIN_VIRTUAL_INPUT_DEVICE_ID;
1006 }
1007 deviceId = virtualDeviceId++;
1008 if (virtualInputDevices_.find(deviceId) != virtualInputDevices_.end()) {
1009 MMI_HILOGE("Repeated deviceId:%{public}d", deviceId);
1010 deviceId = INVALID_DEVICE_ID;
1011 return RET_ERR;
1012 }
1013 return RET_OK;
1014 }
1015
NotifyDevRemoveCallback(int32_t deviceId,const InputDeviceInfo & deviceInfo)1016 void InputDeviceManager::NotifyDevRemoveCallback(int32_t deviceId, const InputDeviceInfo &deviceInfo)
1017 {
1018 CALL_DEBUG_ENTER;
1019 if (auto sysUid = deviceInfo.sysUid; !sysUid.empty()) {
1020 std::string name = "null";
1021 if (deviceInfo.inputDeviceOrigin != nullptr) {
1022 name = libinput_device_get_name(deviceInfo.inputDeviceOrigin);
1023 }
1024 CHKPV(devCallbacks_);
1025 devCallbacks_(deviceId, name, sysUid, "remove");
1026 MMI_HILOGI("Send device info to window manager, deivceId:%{public}d, name:%{private}s, status:remove",
1027 deviceId, name.c_str());
1028 }
1029 }
1030
NotifyMessage(SessionPtr sess,int32_t id,const std::string & type)1031 int32_t InputDeviceManager::NotifyMessage(SessionPtr sess, int32_t id, const std::string &type)
1032 {
1033 CALL_DEBUG_ENTER;
1034 CHKPR(sess, ERROR_NULL_POINTER);
1035 NetPacket pkt(MmiMessageId::ADD_INPUT_DEVICE_LISTENER);
1036 pkt << type << id;
1037 if (pkt.ChkRWError()) {
1038 MMI_HILOGE("Packet write data failed");
1039 return RET_ERR;
1040 }
1041 if (!sess->SendMsg(pkt)) {
1042 MMI_HILOGE("Sending failed");
1043 }
1044 return RET_OK;
1045 }
1046
InitSessionLostCallback()1047 void InputDeviceManager::InitSessionLostCallback()
1048 {
1049 if (sessionLostCallbackInitialized_) {
1050 MMI_HILOGD("Init session is failed");
1051 return;
1052 }
1053 auto udsServerPtr = InputHandler->GetUDSServer();
1054 CHKPV(udsServerPtr);
1055 udsServerPtr->AddSessionDeletedCallback([this] (SessionPtr session) {
1056 return this->OnSessionLost(session);
1057 }
1058 );
1059 sessionLostCallbackInitialized_ = true;
1060 MMI_HILOGI("The callback on session deleted is registered successfully");
1061 }
1062
OnSessionLost(SessionPtr session)1063 void InputDeviceManager::OnSessionLost(SessionPtr session)
1064 {
1065 CALL_DEBUG_ENTER;
1066 RecoverInputDeviceEnabled(session);
1067 devListeners_.remove(session);
1068 }
1069
GetTouchPadIds()1070 std::vector<int32_t> InputDeviceManager::GetTouchPadIds()
1071 {
1072 CALL_DEBUG_ENTER;
1073 std::vector<int32_t> ids;
1074 for (const auto &item : inputDevice_) {
1075 auto inputDevice = item.second.inputDeviceOrigin;
1076 if (inputDevice == nullptr) {
1077 continue;
1078 }
1079 enum evdev_device_udev_tags udevTags = libinput_device_get_tags(inputDevice);
1080 if ((udevTags & EVDEV_UDEV_TAG_TOUCHPAD) != 0) {
1081 ids.push_back(item.first);
1082 }
1083 }
1084 return ids;
1085 }
1086
GetTouchPadDeviceOrigins()1087 std::vector<libinput_device*> InputDeviceManager::GetTouchPadDeviceOrigins()
1088 {
1089 CALL_DEBUG_ENTER;
1090 std::vector<libinput_device*> touchPadDevices;
1091 for (const auto &item : inputDevice_) {
1092 auto inputDevice = item.second.inputDeviceOrigin;
1093 if (inputDevice == nullptr) {
1094 continue;
1095 }
1096 enum evdev_device_udev_tags udevTags = libinput_device_get_tags(inputDevice);
1097 if ((udevTags & EVDEV_UDEV_TAG_TOUCHPAD) != 0) {
1098 touchPadDevices.push_back(inputDevice);
1099 continue;
1100 }
1101 }
1102 return touchPadDevices;
1103 }
1104
IsPointerDevice(std::shared_ptr<InputDevice> inputDevice) const1105 bool InputDeviceManager::IsPointerDevice(std::shared_ptr<InputDevice> inputDevice) const
1106 {
1107 CHKPF(inputDevice);
1108 return inputDevice->HasCapability(InputDeviceCapability::INPUT_DEV_CAP_POINTER);
1109 }
1110
IsTouchableDevice(std::shared_ptr<InputDevice> inputDevice) const1111 bool InputDeviceManager::IsTouchableDevice(std::shared_ptr<InputDevice> inputDevice) const
1112 {
1113 CHKPF(inputDevice);
1114 return inputDevice->HasCapability(InputDeviceCapability::INPUT_DEV_CAP_TOUCH);
1115 }
1116
IsKeyboardDevice(std::shared_ptr<InputDevice> inputDevice) const1117 bool InputDeviceManager::IsKeyboardDevice(std::shared_ptr<InputDevice> inputDevice) const
1118 {
1119 CHKPF(inputDevice);
1120 return inputDevice->HasCapability(InputDeviceCapability::INPUT_DEV_CAP_KEYBOARD);
1121 }
1122
NotifyInputdeviceMessage(SessionPtr session,int32_t index,int32_t result)1123 int32_t InputDeviceManager::NotifyInputdeviceMessage(SessionPtr session, int32_t index, int32_t result)
1124 {
1125 CALL_DEBUG_ENTER;
1126 CHKPR(session, ERROR_NULL_POINTER);
1127 NetPacket pkt(MmiMessageId::SET_INPUT_DEVICE_ENABLED);
1128 pkt << index << result;
1129 if (pkt.ChkRWError()) {
1130 MMI_HILOGE("Packet write data failed");
1131 return RET_ERR;
1132 }
1133 if (!session->SendMsg(pkt)) {
1134 MMI_HILOGE("Sending failed");
1135 return RET_ERR;
1136 }
1137 return RET_OK;
1138 }
1139
SetInputDeviceEnabled(int32_t deviceId,bool enable,int32_t index,int32_t pid,SessionPtr session)1140 int32_t InputDeviceManager::SetInputDeviceEnabled(
1141 int32_t deviceId, bool enable, int32_t index, int32_t pid, SessionPtr session)
1142 {
1143 CALL_DEBUG_ENTER;
1144 MMI_HILOGI("The deviceId:%{public}d, enable:%{public}d, pid:%{public}d", deviceId, enable, pid);
1145 auto item = inputDevice_.find(deviceId);
1146 if (item == inputDevice_.end()) {
1147 NotifyInputdeviceMessage(session, index, ERROR_DEVICE_NOT_EXIST);
1148 MMI_HILOGD("Set inputDevice enabled failed, Invalid deviceId");
1149 return RET_ERR;
1150 }
1151 item->second.enable = enable;
1152 if (!enable) {
1153 MMI_HILOGD("Disable inputdevice, save calling pid:%{public}d to recoverlist", pid);
1154 recoverList_.insert(std::pair<int32_t, int32_t>(deviceId, pid));
1155 InitSessionLostCallback();
1156 }
1157 NotifyInputdeviceMessage(session, index, RET_OK);
1158 return RET_OK;
1159 }
1160
RecoverInputDeviceEnabled(SessionPtr session)1161 void InputDeviceManager::RecoverInputDeviceEnabled(SessionPtr session)
1162 {
1163 CALL_DEBUG_ENTER;
1164 CHKPV(session);
1165 std::lock_guard<std::mutex> lock(mutex_);
1166 for (auto item = recoverList_.begin(); item != recoverList_.end();) {
1167 if (session->GetPid() == item->second) {
1168 auto device = inputDevice_.find(item->first);
1169 if (device != inputDevice_.end()) {
1170 MMI_HILOGI("Recover input device:%{public}d", item->first);
1171 device->second.enable = true;
1172 }
1173 item = recoverList_.erase(item);
1174 } else {
1175 item++;
1176 }
1177 }
1178 }
1179
IsInputDeviceEnable(int32_t deviceId)1180 bool InputDeviceManager::IsInputDeviceEnable(int32_t deviceId)
1181 {
1182 bool enable = false;
1183 CALL_DEBUG_ENTER;
1184 auto item = inputDevice_.find(deviceId);
1185 if (item == inputDevice_.end()) {
1186 MMI_HILOGD("Get inputDevice enabled failed, Invalid deviceId.");
1187 return enable;
1188 }
1189 enable = item->second.enable;
1190 return enable;
1191 }
1192
IsLocalDevice(int32_t deviceId)1193 bool InputDeviceManager::IsLocalDevice(int32_t deviceId)
1194 {
1195 auto iter = inputDevice_.find(deviceId);
1196 return (iter != inputDevice_.end());
1197 }
1198
FillInputDeviceWithVirtualCapability(std::shared_ptr<InputDevice> inputDevice,const InputDeviceInfo & deviceInfo) const1199 void InputDeviceManager::FillInputDeviceWithVirtualCapability(
1200 std::shared_ptr<InputDevice> inputDevice, const InputDeviceInfo &deviceInfo) const
1201 {
1202 CHKPV(inputDevice);
1203 if (!deviceInfo.isTouchableDevice) {
1204 // not adding capability from virtual devices for devices other than the touch screen.
1205 return;
1206 }
1207 for (auto it = virtualInputDevices_.begin(); it != virtualInputDevices_.end(); ++it) {
1208 if (IsKeyboardDevice(it->second)) {
1209 inputDevice->AddCapability(InputDeviceCapability::INPUT_DEV_CAP_KEYBOARD);
1210 MMI_HILOGD("add virtual keyboard capability for touchscreen dev");
1211 } else if (IsPointerDevice(it->second)) {
1212 inputDevice->AddCapability(InputDeviceCapability::INPUT_DEV_CAP_POINTER);
1213 MMI_HILOGD("add virtual trackpad capability for touchscreen dev");
1214 }
1215 }
1216 }
1217
GetTouchscreenKeyboardType(const InputDeviceInfo & deviceInfo,int32_t & keyboardType)1218 int32_t InputDeviceManager::GetTouchscreenKeyboardType(const InputDeviceInfo &deviceInfo, int32_t &keyboardType)
1219 {
1220 if (!deviceInfo.isTouchableDevice) {
1221 return RET_ERR;
1222 }
1223 bool hasVirtualKeyboard = false;
1224 bool hasVirtualTrackpad = false;
1225 for (auto it = virtualInputDevices_.begin(); it != virtualInputDevices_.end(); ++it) {
1226 if (IsKeyboardDevice(it->second)) {
1227 hasVirtualKeyboard = true;
1228 } else if (IsPointerDevice(it->second)) {
1229 hasVirtualTrackpad = true;
1230 }
1231 }
1232 if (hasVirtualKeyboard) {
1233 if (hasVirtualTrackpad) {
1234 keyboardType = KEYBOARD_TYPE_ALPHABETICKEYBOARD;
1235 } else {
1236 keyboardType = KEYBOARD_TYPE_DIGITALKEYBOARD;
1237 }
1238 MMI_HILOGI("Touchscreen used as virtual keyboard, type=%{public}d", keyboardType);
1239 return RET_OK;
1240 }
1241 return RET_ERR;
1242 }
1243
GetVirtualKeyboardType(int32_t deviceId,int32_t & keyboardType)1244 int32_t InputDeviceManager::GetVirtualKeyboardType(int32_t deviceId, int32_t &keyboardType)
1245 {
1246 CALL_DEBUG_ENTER;
1247 auto item = virtualInputDevices_.find(deviceId);
1248 if (item != virtualInputDevices_.end()) {
1249 if (!IsKeyboardDevice(item->second)) {
1250 MMI_HILOGI("Virtual device with id:%{public}d is not keyboard", deviceId);
1251 keyboardType = KEYBOARD_TYPE_NONE;
1252 return RET_OK;
1253 }
1254 keyboardType = KEYBOARD_TYPE_ALPHABETICKEYBOARD;
1255 MMI_HILOGI("Virtual device with id:%{public}d, type:%{public}d", deviceId, keyboardType);
1256 return RET_OK;
1257 }
1258 return RET_ERR;
1259 }
1260
NotifyDeviceAdded(int32_t deviceId) const1261 void InputDeviceManager::NotifyDeviceAdded(int32_t deviceId) const
1262 {
1263 for (auto observer : observers_) {
1264 if (observer != nullptr) {
1265 observer->OnDeviceAdded(deviceId);
1266 }
1267 }
1268 }
1269
NotifyDeviceRemoved(int32_t deviceId) const1270 void InputDeviceManager::NotifyDeviceRemoved(int32_t deviceId) const
1271 {
1272 for (auto observer : observers_) {
1273 if (observer != nullptr) {
1274 observer->OnDeviceRemoved(deviceId);
1275 }
1276 }
1277 }
1278 } // namespace MMI
1279 } // namespace OHOS
1280