• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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