• 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 <parameters.h>
20 #ifdef OHOS_BUILD_ENABLE_COOPERATE
21 #include <openssl/sha.h>
22 #endif // OHOS_BUILD_ENABLE_COOPERATE
23 #include <regex>
24 #include <unordered_map>
25 
26 #include "dfx_hisysevent.h"
27 #ifdef OHOS_BUILD_ENABLE_COOPERATE
28 #include "input_device_cooperate_sm.h"
29 #include "input_device_cooperate_util.h"
30 #endif // OHOS_BUILD_ENABLE_COOPERATE
31 #include "input_windows_manager.h"
32 #include "key_event_value_transformation.h"
33 #ifdef OHOS_BUILD_ENABLE_COOPERATE
34 #include "util.h"
35 #endif // OHOS_BUILD_ENABLE_COOPERATE
36 #include "util_ex.h"
37 #include "util_napi_error.h"
38 
39 namespace OHOS {
40 namespace MMI {
41 namespace {
42 constexpr OHOS::HiviewDFX::HiLogLabel LABEL = {LOG_CORE, MMI_LOG_DOMAIN, "InputDeviceManager"};
43 constexpr int32_t INVALID_DEVICE_ID = -1;
44 constexpr int32_t SUPPORT_KEY = 1;
45 
46 const std::string UNKNOWN_SCREEN_ID = "";
47 #ifdef OHOS_BUILD_ENABLE_COOPERATE
48 const char *SPLIT_SYMBOL = "|";
49 const std::string DH_ID_PREFIX = "Input_";
50 #endif // OHOS_BUILD_ENABLE_COOPERATE
51 const std::string INPUT_VIRTUAL_DEVICE_NAME = "Hos Distributed Virtual Device ";
52 std::unordered_map<int32_t, std::string> axisType = {
53     {ABS_MT_TOUCH_MAJOR, "TOUCH_MAJOR"},
54     {ABS_MT_TOUCH_MINOR, "TOUCH_MINOR"},
55     {ABS_MT_ORIENTATION, "ORIENTATION"},
56     {ABS_MT_POSITION_X, "POSITION_X"},
57     {ABS_MT_POSITION_Y, "POSITION_Y"},
58     {ABS_MT_PRESSURE, "PRESSURE"},
59     {ABS_MT_WIDTH_MAJOR, "WIDTH_MAJOR"},
60     {ABS_MT_WIDTH_MINOR, "WIDTH_MINOR"}
61 };
62 
63 constexpr size_t EXPECTED_N_SUBMATCHES { 2 };
64 constexpr size_t EXPECTED_SUBMATCH { 1 };
65 } // namespace
66 
InputDeviceManager()67 InputDeviceManager::InputDeviceManager() {}
~InputDeviceManager()68 InputDeviceManager::~InputDeviceManager() {}
69 
GetInputDevice(int32_t id) const70 std::shared_ptr<InputDevice> InputDeviceManager::GetInputDevice(int32_t id) const
71 {
72     CALL_DEBUG_ENTER;
73     auto iter = inputDevice_.find(id);
74     if (iter == inputDevice_.end()) {
75         MMI_HILOGE("Failed to search for the device");
76         return nullptr;
77     }
78 
79     std::shared_ptr<InputDevice> inputDevice = std::make_shared<InputDevice>();
80     CHKPP(inputDevice);
81     inputDevice->SetId(iter->first);
82     struct libinput_device *inputDeviceOrigin = iter->second.inputDeviceOrigin;
83     inputDevice->SetType(static_cast<int32_t>(libinput_device_get_tags(inputDeviceOrigin)));
84     const char* name = libinput_device_get_name(inputDeviceOrigin);
85     inputDevice->SetName((name == nullptr) ? ("null") : (name));
86     inputDevice->SetBus(libinput_device_get_id_bustype(inputDeviceOrigin));
87     inputDevice->SetVersion(libinput_device_get_id_version(inputDeviceOrigin));
88     inputDevice->SetProduct(libinput_device_get_id_product(inputDeviceOrigin));
89     inputDevice->SetVendor(libinput_device_get_id_vendor(inputDeviceOrigin));
90     const char* phys = libinput_device_get_phys(inputDeviceOrigin);
91     inputDevice->SetPhys((phys == nullptr) ? ("null") : (phys));
92     const char* uniq = libinput_device_get_uniq(inputDeviceOrigin);
93     inputDevice->SetUniq((uniq == nullptr) ? ("null") : (uniq));
94 
95     InputDevice::AxisInfo axis;
96     for (const auto &item : axisType) {
97         int32_t min = libinput_device_get_axis_min(inputDeviceOrigin, item.first);
98         if (min == -1) {
99             MMI_HILOGD("The device does not support this axis");
100             continue;
101         }
102         if (item.first == ABS_MT_PRESSURE) {
103             axis.SetMinimum(0);
104             axis.SetMaximum(1);
105         } else {
106             axis.SetMinimum(min);
107             axis.SetMaximum(libinput_device_get_axis_max(inputDeviceOrigin, item.first));
108         }
109         axis.SetAxisType(item.first);
110         axis.SetFuzz(libinput_device_get_axis_fuzz(inputDeviceOrigin, item.first));
111         axis.SetFlat(libinput_device_get_axis_flat(inputDeviceOrigin, item.first));
112         axis.SetResolution(libinput_device_get_axis_resolution(inputDeviceOrigin, item.first));
113         inputDevice->AddAxisInfo(axis);
114     }
115     return inputDevice;
116 }
117 
GetInputDeviceIds() const118 std::vector<int32_t> InputDeviceManager::GetInputDeviceIds() const
119 {
120     CALL_DEBUG_ENTER;
121     std::vector<int32_t> ids;
122     for (const auto &item : inputDevice_) {
123 #ifdef OHOS_BUILD_ENABLE_COOPERATE
124         if (IsRemote(item.second.inputDeviceOrigin) &&
125             InputDevCooSM->GetCurrentCooperateState() == CooperateState::STATE_FREE) {
126             MMI_HILOGW("Current device is remote and in STATUS_STATE");
127             continue;
128         }
129 #endif // OHOS_BUILD_ENABLE_COOPERATE
130         ids.push_back(item.first);
131     }
132     return ids;
133 }
134 
SupportKeys(int32_t deviceId,std::vector<int32_t> & keyCodes,std::vector<bool> & keystroke)135 int32_t InputDeviceManager::SupportKeys(int32_t deviceId, std::vector<int32_t> &keyCodes, std::vector<bool> &keystroke)
136 {
137     CALL_DEBUG_ENTER;
138     auto iter = inputDevice_.find(deviceId);
139     if (iter == inputDevice_.end()) {
140         return COMMON_PARAMETER_ERROR;
141     }
142     for (const auto &item : keyCodes) {
143         bool ret = false;
144         for (const auto &it : KeyMapMgr->InputTransferKeyValue(deviceId, item)) {
145             ret |= libinput_device_has_key(iter->second.inputDeviceOrigin, it) == SUPPORT_KEY;
146         }
147         keystroke.push_back(ret);
148     }
149     return RET_OK;
150 }
151 
IsMatchKeys(struct libinput_device * device,const std::vector<int32_t> & keyCodes) const152 bool InputDeviceManager::IsMatchKeys(struct libinput_device* device, const std::vector<int32_t> &keyCodes) const
153 {
154     CHKPF(device);
155     for (const auto &key : keyCodes) {
156         int32_t value = InputTransformationKeyValue(key);
157         if (libinput_device_keyboard_has_key(device, value) == SUPPORT_KEY) {
158             return true;
159         }
160     }
161     return false;
162 }
163 
GetDeviceConfig(int32_t deviceId,int32_t & keyboardType)164 bool InputDeviceManager::GetDeviceConfig(int32_t deviceId, int32_t &keyboardType)
165 {
166     CALL_DEBUG_ENTER;
167     if (auto iter = inputDevice_.find(deviceId); iter == inputDevice_.end()) {
168         MMI_HILOGE("Failed to search for the deviceID");
169         return false;
170     }
171     auto deviceConfig = KeyRepeat->GetDeviceConfig();
172     auto it = deviceConfig.find(deviceId);
173     if (it == deviceConfig.end()) {
174         MMI_HILOGE("Failed to obtain the keyboard type of the configuration file");
175         return false;
176     }
177     keyboardType = it->second.keyboardType;
178     MMI_HILOGD("Get keyboard type results from the configuration file:%{public}d", keyboardType);
179     return true;
180 }
181 
GetKeyboardBusMode(int32_t deviceId)182 int32_t InputDeviceManager::GetKeyboardBusMode(int32_t deviceId)
183 {
184     CALL_DEBUG_ENTER;
185     std::shared_ptr dev = GetInputDevice(deviceId);
186     CHKPR(dev, ERROR_NULL_POINTER);
187     return dev->GetBus();
188 }
189 
GetDeviceSupportKey(int32_t deviceId,int32_t & keyboardType)190 int32_t InputDeviceManager::GetDeviceSupportKey(int32_t deviceId, int32_t &keyboardType)
191 {
192     CALL_DEBUG_ENTER;
193     std::vector <int32_t> keyCodes;
194     keyCodes.push_back(KeyEvent::KEYCODE_Q);
195     keyCodes.push_back(KeyEvent::KEYCODE_NUMPAD_1);
196     keyCodes.push_back(KeyEvent::KEYCODE_HOME);
197     keyCodes.push_back(KeyEvent::KEYCODE_CTRL_LEFT);
198     keyCodes.push_back(KeyEvent::KEYCODE_SHIFT_RIGHT);
199     keyCodes.push_back(KeyEvent::KEYCODE_F20);
200     std::vector<bool> supportKey;
201     int32_t ret = SupportKeys(deviceId, keyCodes, supportKey);
202     if (ret != RET_OK) {
203         MMI_HILOGE("SupportKey call failed");
204         return ret;
205     }
206     std::map<int32_t, bool> determineKbType;
207     for (size_t i = 0; i < keyCodes.size(); i++) {
208         determineKbType[keyCodes[i]] = supportKey[i];
209     }
210     if (determineKbType[KeyEvent::KEYCODE_HOME] && GetKeyboardBusMode(deviceId) == BUS_BLUETOOTH) {
211         keyboardType = KEYBOARD_TYPE_REMOTECONTROL;
212         MMI_HILOGD("The keyboard type is remote control:%{public}d", keyboardType);
213     } else if (determineKbType[KeyEvent::KEYCODE_NUMPAD_1] && !determineKbType[KeyEvent::KEYCODE_Q]) {
214         keyboardType = KEYBOARD_TYPE_DIGITALKEYBOARD;
215         MMI_HILOGD("The keyboard type is digital keyboard:%{public}d", keyboardType);
216     } else if (determineKbType[KeyEvent::KEYCODE_Q]) {
217         keyboardType = KEYBOARD_TYPE_ALPHABETICKEYBOARD;
218         MMI_HILOGD("The keyboard type is standard:%{public}d", keyboardType);
219     } else if (determineKbType[KeyEvent::KEYCODE_CTRL_LEFT] && determineKbType[KeyEvent::KEYCODE_SHIFT_RIGHT]
220         && determineKbType[KeyEvent::KEYCODE_F20]) {
221         keyboardType = KEYBOARD_TYPE_HANDWRITINGPEN;
222         MMI_HILOGD("The keyboard type is handwriting pen:%{public}d", keyboardType);
223     } else {
224         keyboardType = KEYBOARD_TYPE_UNKNOWN;
225         MMI_HILOGW("Undefined keyboard type");
226     }
227     MMI_HILOGD("Get keyboard type results by supporting keys:%{public}d", keyboardType);
228     return RET_OK;
229 }
230 
GetKeyboardType(int32_t deviceId,int32_t & keyboardType)231 int32_t InputDeviceManager::GetKeyboardType(int32_t deviceId, int32_t &keyboardType)
232 {
233     CALL_DEBUG_ENTER;
234     int32_t tempKeyboardType = KEYBOARD_TYPE_NONE;
235     if (auto iter = inputDevice_.find(deviceId); iter == inputDevice_.end()) {
236         MMI_HILOGE("Failed to search for the deviceID");
237         return COMMON_PARAMETER_ERROR;
238     }
239     if (GetDeviceConfig(deviceId, tempKeyboardType)) {
240         keyboardType = tempKeyboardType;
241         return RET_OK;
242     }
243     return GetDeviceSupportKey(deviceId, keyboardType);
244 }
245 
AddDevListener(SessionPtr sess,std::function<void (int32_t,const std::string &)> callback)246 void InputDeviceManager::AddDevListener(SessionPtr sess, std::function<void(int32_t, const std::string&)> callback)
247 {
248     CALL_DEBUG_ENTER;
249     auto ret = devListener_.insert({ sess, callback });
250     if (!ret.second) {
251         MMI_HILOGE("Session is duplicated");
252         return;
253     }
254 }
255 
RemoveDevListener(SessionPtr sess)256 void InputDeviceManager::RemoveDevListener(SessionPtr sess)
257 {
258     CALL_DEBUG_ENTER;
259     auto iter = devListener_.find(sess);
260     if (iter == devListener_.end()) {
261         MMI_HILOGE("Session does not exist");
262         return;
263     }
264     devListener_.erase(iter);
265 }
266 
267 #ifdef OHOS_BUILD_ENABLE_POINTER_DRAWING
HasPointerDevice()268 bool InputDeviceManager::HasPointerDevice()
269 {
270     for (auto it = inputDevice_.begin(); it != inputDevice_.end(); ++it) {
271         if (it->second.isPointerDevice) {
272             return true;
273         }
274     }
275     return false;
276 }
277 #endif // OHOS_BUILD_ENABLE_POINTER_DRAWING
278 
HasTouchDevice()279 bool InputDeviceManager::HasTouchDevice()
280 {
281     CALL_DEBUG_ENTER;
282     for (auto it = inputDevice_.begin(); it != inputDevice_.end(); ++it) {
283         if (it->second.isTouchableDevice) {
284             return true;
285         }
286     }
287     return false;
288 }
289 
ParseDeviceId(const std::string & sysName)290 int32_t InputDeviceManager::ParseDeviceId(const std::string &sysName)
291 {
292     CALL_DEBUG_ENTER;
293     std::regex pattern("^event(\\d+)$");
294     std::smatch mr;
295 
296     if (std::regex_match(sysName, mr, pattern)) {
297         if (mr.ready() && mr.size() == EXPECTED_N_SUBMATCHES) {
298             return std::stoi(mr[EXPECTED_SUBMATCH].str());
299         }
300     }
301     return -1;
302 }
303 
OnInputDeviceAdded(struct libinput_device * inputDevice)304 void InputDeviceManager::OnInputDeviceAdded(struct libinput_device *inputDevice)
305 {
306     CALL_DEBUG_ENTER;
307     CHKPV(inputDevice);
308     bool hasLocalPointer = false;
309     bool hasPointer = false;
310     for (const auto &item : inputDevice_) {
311         if (item.second.inputDeviceOrigin == inputDevice) {
312             MMI_HILOGI("The device is already existent");
313             DfxHisysevent::OnDeviceConnect(item.first, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT);
314             return;
315         }
316         if (item.second.isPointerDevice) {
317             hasPointer = true;
318             if (!item.second.isRemote) {
319                 hasLocalPointer = true;
320             }
321         }
322     }
323 
324     const char *sysName = libinput_device_get_sysname(inputDevice);
325     CHKPV(sysName);
326     int32_t deviceId = ParseDeviceId(std::string(sysName));
327     if (deviceId < 0) {
328         MMI_HILOGE("Parsing sysname failed: \'%{public}s\'", sysName);
329         return;
330     }
331 
332     struct InputDeviceInfo info;
333     MakeDeviceInfo(inputDevice, info);
334     inputDevice_[deviceId] = info;
335 #ifdef OHOS_BUILD_ENABLE_COOPERATE
336     if (!IsRemote(inputDevice) || InputDevCooSM->GetCurrentCooperateState() != CooperateState::STATE_FREE) {
337         for (const auto &item : devListener_) {
338             CHKPC(item.first);
339             item.second(deviceId, "add");
340         }
341     }
342 #else
343     for (const auto &item : devListener_) {
344         CHKPC(item.first);
345         item.second(deviceId, "add");
346     }
347 #endif // OHOS_BUILD_ENABLE_COOPERATE
348 
349 #ifdef OHOS_BUILD_ENABLE_COOPERATE
350     if (IsKeyboardDevice(inputDevice)) {
351         if (IsRemote(inputDevice)) {
352             InputDevCooSM->SetVirtualKeyBoardDevId(deviceId);
353         }
354         InputDevCooSM->OnKeyboardOnline(info.dhid);
355     }
356 #endif // OHOS_BUILD_ENABLE_COOPERATE
357 #if defined(OHOS_BUILD_ENABLE_POINTER) && defined(OHOS_BUILD_ENABLE_POINTER_DRAWING)
358     if (!hasPointer && info.isPointerDevice) {
359         bool visible = !info.isRemote || hasLocalPointer;
360         if (HasTouchDevice()) {
361             IPointerDrawingManager::GetInstance()->SetMouseDisplayState(false);
362         }
363         NotifyPointerDevice(true, visible);
364         OHOS::system::SetParameter(INPUT_POINTER_DEVICE, "true");
365         MMI_HILOGI("Set para input.pointer.device true");
366     }
367 #endif // OHOS_BUILD_ENABLE_POINTER && OHOS_BUILD_ENABLE_POINTER_DRAWING
368 #if defined(OHOS_BUILD_ENABLE_POINTER) && defined(OHOS_BUILD_ENABLE_POINTER_DRAWING)
369     if (info.isPointerDevice && !HasPointerDevice() &&
370         IPointerDrawingManager::GetInstance()->GetMouseDisplayState()) {
371 #ifdef OHOS_BUILD_ENABLE_POINTER
372         WinMgr->DispatchPointer(PointerEvent::POINTER_ACTION_ENTER_WINDOW);
373 #endif // OHOS_BUILD_ENABLE_POINTER
374     }
375 #endif // OHOS_BUILD_ENABLE_POINTER && OHOS_BUILD_ENABLE_POINTER_DRAWING
376     DfxHisysevent::OnDeviceConnect(deviceId, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR);
377 }
378 
MakeDeviceInfo(struct libinput_device * inputDevice,struct InputDeviceInfo & info)379 void InputDeviceManager::MakeDeviceInfo(struct libinput_device *inputDevice, struct InputDeviceInfo& info)
380 {
381     info.inputDeviceOrigin = inputDevice;
382     info.isRemote = IsRemote(inputDevice);
383     info.isPointerDevice = IsPointerDevice(inputDevice);
384     info.isTouchableDevice = IsTouchDevice(inputDevice);
385 #ifdef OHOS_BUILD_ENABLE_COOPERATE
386     if (info.isRemote) {
387         info.networkIdOrigin = MakeNetworkId(libinput_device_get_phys(inputDevice));
388     }
389     info.dhid = GenerateDescriptor(inputDevice, info.isRemote);
390 #endif // OHOS_BUILD_ENABLE_COOPERATE
391 }
392 
OnInputDeviceRemoved(struct libinput_device * inputDevice)393 void InputDeviceManager::OnInputDeviceRemoved(struct libinput_device *inputDevice)
394 {
395     CALL_DEBUG_ENTER;
396     CHKPV(inputDevice);
397     int32_t deviceId = INVALID_DEVICE_ID;
398 #ifdef OHOS_BUILD_ENABLE_COOPERATE
399     struct InputDeviceInfo removedInfo;
400     std::vector<std::string> dhids;
401 #endif // OHOS_BUILD_ENABLE_COOPERATE
402     for (auto it = inputDevice_.begin(); it != inputDevice_.end(); ++it) {
403         if (it->second.inputDeviceOrigin == inputDevice) {
404             deviceId = it->first;
405 #ifdef OHOS_BUILD_ENABLE_COOPERATE
406             removedInfo = it->second;
407             dhids = GetCooperateDhids(deviceId);
408 #endif // OHOS_BUILD_ENABLE_COOPERATE
409             DfxHisysevent::OnDeviceDisconnect(deviceId, OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR);
410             inputDevice_.erase(it);
411             break;
412         }
413     }
414 #if defined(OHOS_BUILD_ENABLE_POINTER) && defined(OHOS_BUILD_ENABLE_POINTER_DRAWING)
415     if (IsPointerDevice(inputDevice) && !HasPointerDevice() &&
416         IPointerDrawingManager::GetInstance()->GetMouseDisplayState()) {
417 #ifdef OHOS_BUILD_ENABLE_POINTER
418         WinMgr->DispatchPointer(PointerEvent::POINTER_ACTION_LEAVE_WINDOW);
419 #endif // OHOS_BUILD_ENABLE_POINTER
420     }
421 #endif // OHOS_BUILD_ENABLE_POINTER && OHOS_BUILD_ENABLE_POINTER_DRAWING
422 #ifdef OHOS_BUILD_ENABLE_COOPERATE
423     if (!IsRemote(inputDevice) || InputDevCooSM->GetCurrentCooperateState() != CooperateState::STATE_FREE) {
424         for (const auto &item : devListener_) {
425             CHKPC(item.first);
426             item.second(deviceId, "remove");
427         }
428     }
429 #else
430     for (const auto &item : devListener_) {
431         CHKPC(item.first);
432         item.second(deviceId, "remove");
433     }
434 #endif // OHOS_BUILD_ENABLE_COOPERATE
435     ScanPointerDevice();
436 #ifdef OHOS_BUILD_ENABLE_COOPERATE
437     if (IsPointerDevice(inputDevice)) {
438         InputDevCooSM->OnPointerOffline(removedInfo.dhid, removedInfo.networkIdOrigin, dhids);
439     }
440 #endif // OHOS_BUILD_ENABLE_COOPERATE
441     if (deviceId == INVALID_DEVICE_ID) {
442         DfxHisysevent::OnDeviceDisconnect(INVALID_DEVICE_ID, OHOS::HiviewDFX::HiSysEvent::EventType::FAULT);
443     }
444 }
445 
ScanPointerDevice()446 void InputDeviceManager::ScanPointerDevice()
447 {
448     bool hasPointerDevice = false;
449     for (auto it = inputDevice_.begin(); it != inputDevice_.end(); ++it) {
450         if (it->second.isPointerDevice) {
451             hasPointerDevice = true;
452             break;
453         }
454     }
455     if (!hasPointerDevice) {
456         NotifyPointerDevice(false, false);
457         OHOS::system::SetParameter(INPUT_POINTER_DEVICE, "false");
458         MMI_HILOGI("Set para input.pointer.device false");
459     }
460 }
461 
IsPointerDevice(struct libinput_device * device) const462 bool InputDeviceManager::IsPointerDevice(struct libinput_device* device) const
463 {
464     CHKPF(device);
465     return libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_POINTER);
466 }
467 
IsKeyboardDevice(struct libinput_device * device) const468 bool InputDeviceManager::IsKeyboardDevice(struct libinput_device* device) const
469 {
470     CHKPF(device);
471     return libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_KEYBOARD);
472 }
473 
IsTouchDevice(struct libinput_device * device) const474 bool InputDeviceManager::IsTouchDevice(struct libinput_device* device) const
475 {
476     CHKPF(device);
477     return libinput_device_has_capability(device, LIBINPUT_DEVICE_CAP_TOUCH);
478 }
479 
Attach(std::shared_ptr<IDeviceObserver> observer)480 void InputDeviceManager::Attach(std::shared_ptr<IDeviceObserver> observer)
481 {
482     CALL_DEBUG_ENTER;
483     observers_.push_back(observer);
484 }
485 
Detach(std::shared_ptr<IDeviceObserver> observer)486 void InputDeviceManager::Detach(std::shared_ptr<IDeviceObserver> observer)
487 {
488     CALL_DEBUG_ENTER;
489     observers_.remove(observer);
490 }
491 
NotifyPointerDevice(bool hasPointerDevice,bool isVisible)492 void InputDeviceManager::NotifyPointerDevice(bool hasPointerDevice, bool isVisible)
493 {
494     MMI_HILOGI("observers_ size:%{public}zu", observers_.size());
495     for (auto observer = observers_.begin(); observer != observers_.end(); observer++) {
496         (*observer)->UpdatePointerDevice(hasPointerDevice, isVisible);
497     }
498 }
499 
FindInputDeviceId(struct libinput_device * inputDevice)500 int32_t InputDeviceManager::FindInputDeviceId(struct libinput_device* inputDevice)
501 {
502     CALL_DEBUG_ENTER;
503     CHKPR(inputDevice, INVALID_DEVICE_ID);
504     for (const auto &item : inputDevice_) {
505         if (item.second.inputDeviceOrigin == inputDevice) {
506             MMI_HILOGI("Find input device id success");
507             return item.first;
508         }
509     }
510     MMI_HILOGE("Find input device id failed");
511     return INVALID_DEVICE_ID;
512 }
513 
GetKeyboardDevice() const514 struct libinput_device* InputDeviceManager::GetKeyboardDevice() const
515 {
516     CALL_DEBUG_ENTER;
517     std::vector<int32_t> keyCodes;
518     keyCodes.push_back(KeyEvent::KEYCODE_Q);
519     keyCodes.push_back(KeyEvent::KEYCODE_NUMPAD_1);
520     for (const auto &item : inputDevice_) {
521         const auto &device = item.second.inputDeviceOrigin;
522         if (IsMatchKeys(device, keyCodes)) {
523             MMI_HILOGI("Find keyboard device success");
524             return device;
525         }
526     }
527     MMI_HILOGW("No keyboard device is currently available");
528     return nullptr;
529 }
530 
Dump(int32_t fd,const std::vector<std::string> & args)531 void InputDeviceManager::Dump(int32_t fd, const std::vector<std::string> &args)
532 {
533     CALL_DEBUG_ENTER;
534     mprintf(fd, "Device information:\t");
535     mprintf(fd, "Input devices: count=%d", inputDevice_.size());
536     for (const auto &item : inputDevice_) {
537         std::shared_ptr<InputDevice> inputDevice = GetInputDevice(item.first);
538         CHKPV(inputDevice);
539         mprintf(fd,
540                 "deviceId:%d | deviceName:%s | deviceType:%d | bus:%d | version:%d "
541                 "| product:%d | vendor:%d | phys:%s\t",
542                 inputDevice->GetId(), inputDevice->GetName().c_str(), inputDevice->GetType(),
543                 inputDevice->GetBus(), inputDevice->GetVersion(), inputDevice->GetProduct(),
544                 inputDevice->GetVendor(), inputDevice->GetPhys().c_str());
545         std::vector<InputDevice::AxisInfo> axisinfo = inputDevice->GetAxisInfo();
546         mprintf(fd, "axis: count=%d", axisinfo.size());
547         for (const auto &axis : axisinfo) {
548             auto iter = axisType.find(axis.GetAxisType());
549             if (iter == axisType.end()) {
550                 MMI_HILOGE("The axisType is not found");
551                 return;
552             }
553             mprintf(fd,
554                     "\t axisType:%s | minimum:%d | maximum:%d | fuzz:%d | flat:%d | resolution:%d\t",
555                     iter->second.c_str(), axis.GetMinimum(), axis.GetMaximum(), axis.GetFuzz(),
556                     axis.GetFlat(), axis.GetResolution());
557         }
558     }
559 }
560 
DumpDeviceList(int32_t fd,const std::vector<std::string> & args)561 void InputDeviceManager::DumpDeviceList(int32_t fd, const std::vector<std::string> &args)
562 {
563     CALL_DEBUG_ENTER;
564     std::vector<int32_t> ids = GetInputDeviceIds();
565     mprintf(fd, "Total device:%d, Device list:\t", int32_t { ids.size() });
566     for (const auto &item : inputDevice_) {
567         std::shared_ptr<InputDevice> inputDevice = GetInputDevice(item.first);
568         CHKPV(inputDevice);
569         int32_t deviceId = inputDevice->GetId();
570         mprintf(fd,
571                 "deviceId:%d | deviceName:%s | deviceType:%d | bus:%d | version:%d | product:%d | vendor:%d\t",
572                 deviceId, inputDevice->GetName().c_str(), inputDevice->GetType(), inputDevice->GetBus(),
573                 inputDevice->GetVersion(), inputDevice->GetProduct(), inputDevice->GetVendor());
574     }
575 }
576 
IsRemote(struct libinput_device * inputDevice) const577 bool InputDeviceManager::IsRemote(struct libinput_device *inputDevice) const
578 {
579     CHKPF(inputDevice);
580     bool isRemote = false;
581     const char* name = libinput_device_get_name(inputDevice);
582     if (name == nullptr || name[0] == '\0') {
583         MMI_HILOGD("Device name is empty");
584         return false;
585     }
586     std::string strName = name;
587     std::string::size_type pos = strName.find(INPUT_VIRTUAL_DEVICE_NAME);
588     if (pos != std::string::npos) {
589         isRemote = true;
590     }
591     MMI_HILOGD("isRemote:%{public}s", isRemote ? "true" : "false");
592     return isRemote;
593 }
594 
IsRemote(int32_t id) const595 bool InputDeviceManager::IsRemote(int32_t id) const
596 {
597     bool isRemote = false;
598     auto device = inputDevice_.find(id);
599     if (device != inputDevice_.end()) {
600         isRemote = device->second.isRemote;
601     }
602     MMI_HILOGD("isRemote: %{public}s", isRemote == true ? "true" : "false");
603     return isRemote;
604 }
605 #ifdef OHOS_BUILD_ENABLE_COOPERATE
GetCooperateDhids(int32_t deviceId)606 std::vector<std::string> InputDeviceManager::GetCooperateDhids(int32_t deviceId)
607 {
608     std::vector<std::string> dhids;
609     auto iter = inputDevice_.find(deviceId);
610     if (iter == inputDevice_.end()) {
611         MMI_HILOGI("Find pointer id failed");
612         return dhids;
613     }
614     if (!iter->second.isPointerDevice) {
615         MMI_HILOGI("Not pointer device");
616         return dhids;
617     }
618     dhids.push_back(iter->second.dhid);
619     MMI_HILOGI("unq: %{public}s, type:%{public}s", dhids.back().c_str(), "pointer");
620     auto pointerNetworkId = iter->second.networkIdOrigin;
621     std::string localNetworkId = GetLocalDeviceId();
622     pointerNetworkId = iter->second.isRemote ? iter->second.networkIdOrigin : localNetworkId;
623     for (const auto &item : inputDevice_) {
624         auto networkId = item.second.isRemote ? item.second.networkIdOrigin : localNetworkId;
625         if (networkId != pointerNetworkId) {
626             continue;
627         }
628         int32_t keyboardType = KEYBOARD_TYPE_NONE;
629         if (GetDeviceSupportKey(item.first, keyboardType) != RET_OK) {
630             MMI_HILOGI("Get device support key failed");
631             return dhids;
632         }
633         if (keyboardType == KEYBOARD_TYPE_ALPHABETICKEYBOARD) {
634             dhids.push_back(item.second.dhid);
635             MMI_HILOGI("unq: %{public}s, type:%{public}s", dhids.back().c_str(), "supportkey");
636         }
637     }
638     return dhids;
639 }
640 
GetCooperateDhids(const std::string & dhid)641 std::vector<std::string> InputDeviceManager::GetCooperateDhids(const std::string &dhid)
642 {
643     int32_t inputDeviceId = INVALID_DEVICE_ID;
644     for (const auto &iter : inputDevice_) {
645         if (iter.second.dhid == dhid) {
646             inputDeviceId = iter.first;
647             break;
648         }
649     }
650     return GetCooperateDhids(inputDeviceId);
651 }
652 
GetOriginNetworkId(int32_t id)653 std::string InputDeviceManager::GetOriginNetworkId(int32_t id)
654 {
655     auto iter = inputDevice_.find(id);
656     if (iter == inputDevice_.end()) {
657         MMI_HILOGE("Failed to search for the device: id %{public}d", id);
658         return "";
659     }
660     auto networkId = iter->second.networkIdOrigin;
661     if (networkId.empty()) {
662         networkId = GetLocalDeviceId();
663     }
664     return networkId;
665 }
666 
GetOriginNetworkId(const std::string & dhid)667 std::string InputDeviceManager::GetOriginNetworkId(const std::string &dhid)
668 {
669     if (dhid.empty()) {
670         return "";
671     }
672     std::string networkId;
673     for (const auto &iter : inputDevice_) {
674         if (iter.second.isRemote && iter.second.dhid == dhid) {
675             networkId = iter.second.networkIdOrigin;
676             break;
677         }
678     }
679     return networkId;
680 }
681 
GetDhid(int32_t deviceId) const682 std::string InputDeviceManager::GetDhid(int32_t deviceId) const
683 {
684     auto dev = inputDevice_.find(deviceId);
685     if (dev != inputDevice_.end()) {
686         return dev->second.dhid;
687     }
688     return "";
689 }
690 
HasLocalPointerDevice() const691 bool InputDeviceManager::HasLocalPointerDevice() const
692 {
693     for (auto it = inputDevice_.begin(); it != inputDevice_.end(); ++it) {
694         if (!it->second.isRemote && it->second.isPointerDevice) {
695             return true;
696         }
697     }
698     return false;
699 }
700 
NotifyVirtualKeyBoardStatus(int32_t deviceId,bool isAvailable) const701 void InputDeviceManager::NotifyVirtualKeyBoardStatus(int32_t deviceId, bool isAvailable) const
702 {
703     MMI_HILOGI("virtual keyboard device %{public}s", isAvailable ? "online" : "offline");
704     if (deviceId == -1) {
705         MMI_HILOGE("no virtual keyboard device for this device!");
706         return;
707     }
708 
709     for (const auto &item : devListener_) {
710         CHKPC(item.first);
711         item.second(deviceId, isAvailable ? "add" : "remove");
712     }
713 }
714 
MakeNetworkId(const char * phys) const715 std::string InputDeviceManager::MakeNetworkId(const char *phys) const
716 {
717     std::string networkId;
718     if (phys == nullptr || phys[0] == '\0') {
719         return networkId;
720     }
721     std::string strPhys = phys;
722     std::vector<std::string> strList;
723     StringSplit(strPhys, SPLIT_SYMBOL, strList);
724     if (strList.size() == 3) {
725         networkId = strList[1];
726     }
727     return networkId;
728 }
729 
Sha256(const std::string & in) const730 std::string InputDeviceManager::Sha256(const std::string &in) const
731 {
732     unsigned char out[SHA256_DIGEST_LENGTH * 2 + 1] = {0};
733     SHA256_CTX ctx;
734     SHA256_Init(&ctx);
735     SHA256_Update(&ctx, in.data(), in.size());
736     SHA256_Final(&out[SHA256_DIGEST_LENGTH], &ctx);
737     // here we translate sha256 hash to hexadecimal. each 8-bit char will be presented by two characters([0-9a-f])
738     constexpr int32_t WIDTH = 4;
739     constexpr unsigned char MASK = 0x0F;
740     const char* hexCode = "0123456789abcdef";
741     constexpr int32_t DOUBLE_TIMES = 2;
742     for (int32_t i = 0; i < SHA256_DIGEST_LENGTH; ++i) {
743         unsigned char value = out[SHA256_DIGEST_LENGTH + i];
744         // uint8_t is 2 digits in hexadecimal.
745         out[i * DOUBLE_TIMES] = hexCode[(value >> WIDTH) & MASK];
746         out[i * DOUBLE_TIMES + 1] = hexCode[value & MASK];
747     }
748     out[SHA256_DIGEST_LENGTH * DOUBLE_TIMES] = 0;
749     return reinterpret_cast<char*>(out);
750 }
751 
GenerateDescriptor(struct libinput_device * inputDevice,bool isRemote) const752 std::string InputDeviceManager::GenerateDescriptor(struct libinput_device *inputDevice, bool isRemote) const
753 {
754     const char* physicalPath = libinput_device_get_phys(inputDevice);
755     std::string descriptor;
756     if (isRemote && physicalPath != nullptr) {
757         MMI_HILOGI("physicalPath:%{public}s", physicalPath);
758         std::vector<std::string> strList;
759         StringSplit(physicalPath, SPLIT_SYMBOL, strList);
760         if (strList.size() == 3) {
761             descriptor = strList[2];
762         }
763         return descriptor;
764     }
765 
766     uint16_t vendor = libinput_device_get_id_vendor(inputDevice);
767     const char* name = libinput_device_get_name(inputDevice);
768     const char* uniqueId = libinput_device_get_uniq(inputDevice);
769     uint16_t product = libinput_device_get_id_product(inputDevice);
770     std::string rawDescriptor;
771     rawDescriptor += StringPrintf(":%04x:%04x:", vendor, product);
772     // add handling for USB devices to not uniqueify kbs that show up twice
773     if (uniqueId != nullptr && uniqueId[0] != '\0') {
774         rawDescriptor += "uniqueId:" + std::string(uniqueId);
775     }
776     if (physicalPath != nullptr) {
777         rawDescriptor += "physicalPath:" + std::string(physicalPath);
778     }
779     if (name != nullptr && name[0] != '\0') {
780         rawDescriptor += "name:" + regex_replace(name, std::regex(" "), "");
781     }
782     descriptor = DH_ID_PREFIX + Sha256(rawDescriptor);
783     MMI_HILOGI("Created descriptor raw: %{public}s", rawDescriptor.c_str());
784     return descriptor;
785 }
786 #endif // OHOS_BUILD_ENABLE_COOPERATE
SetInputDevice(const std::string & dhid,const std::string & screenId)787 int32_t InputDeviceManager::SetInputDevice(const std::string& dhid, const std::string& screenId)
788 {
789     CALL_DEBUG_ENTER;
790 #ifdef OHOS_BUILD_ENABLE_COOPERATE
791     if (dhid.empty()) {
792         MMI_HILOGE("hdid is empty");
793         return RET_ERR;
794     }
795     if (screenId.empty()) {
796         MMI_HILOGE("screenId is empty");
797         return RET_ERR;
798     }
799     inputDeviceScreens_[dhid] = screenId;
800 #endif // OHOS_BUILD_ENABLE_COOPERATE
801     return RET_OK;
802 }
803 
GetScreenId(int32_t deviceId) const804 const std::string& InputDeviceManager::GetScreenId(int32_t deviceId) const
805 {
806     CALL_DEBUG_ENTER;
807 #ifdef OHOS_BUILD_ENABLE_COOPERATE
808     auto item = inputDevice_.find(deviceId);
809     if (item != inputDevice_.end()) {
810         auto iter = inputDeviceScreens_.find(item->second.dhid);
811         if (iter != inputDeviceScreens_.end()) {
812             return iter->second;
813         }
814     }
815     MMI_HILOGE("Find input device screen id failed");
816 #endif // OHOS_BUILD_ENABLE_COOPERATE
817     return UNKNOWN_SCREEN_ID;
818 }
819 } // namespace MMI
820 } // namespace OHOS
821