1 /*
2 * Copyright (c) 2021-2024 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 "virtual_device.h"
17
18 #include <getopt.h>
19 #include <sys/stat.h>
20
21 #include "virtual_finger.h"
22 #include "virtual_gamepad.h"
23 #include "virtual_joystick.h"
24 #include "virtual_keyboard.h"
25 #include "virtual_keyboard_sys_ctrl.h"
26 #include "virtual_keyboard_consumer_ctrl.h"
27 #include "virtual_keyboard_ext.h"
28 #include "virtual_knob.h"
29 #include "virtual_knob_sys_ctrl.h"
30 #include "virtual_knob_consumer_ctrl.h"
31 #include "virtual_knob_mouse.h"
32 #include "virtual_mouse.h"
33 #include "virtual_pen.h"
34 #include "virtual_pen_mouse.h"
35 #include "virtual_pen_keyboard.h"
36 #include "virtual_remote_control.h"
37 #include "virtual_single_finger.h"
38 #include "virtual_single_touchscreen.h"
39 #include "virtual_stylus.h"
40 #include "virtual_trackball.h"
41 #include "virtual_trackpad.h"
42 #include "virtual_trackpad_sys_ctrl.h"
43 #include "virtual_touchpad.h"
44 #include "virtual_pc_switch.h"
45 #include "virtual_pc_touchpad.h"
46 #include "virtual_touchscreen.h"
47 #include "virtual_trackpad_mouse.h"
48 #include "virtual_fingerprint_key.h"
49 #include "virtual_fingerprint_mouse.h"
50 #include "virtual_crown.h"
51 #include "virtual_uwb_remote_control.h"
52
53 namespace OHOS {
54 namespace MMI {
55 namespace {
56 constexpr int32_t FILE_SIZE_MAX = 0x5000;
57 constexpr int32_t INVALID_FILE_SIZE = -1;
58 constexpr int32_t FILE_POWER = 0777;
59 constexpr int32_t SLEEP_TIME = 1500000;
60 const std::string PROC_PATH = "/proc";
61 const std::string VIRTUAL_DEVICE_NAME = "vuinput";
62 const std::string g_pid = std::to_string(getpid());
63
IsNum(const std::string& str)64 static inline bool IsNum(const std::string& str)
65 {
66 std::istringstream sin(str);
67 double num;
68 return (sin >> num) && sin.eof();
69 }
70
IsValidPath(const std::string& rootDir, const std::string& filePath)71 static inline bool IsValidPath(const std::string& rootDir, const std::string& filePath)
72 {
73 return (filePath.compare(0, rootDir.size(), rootDir) == 0);
74 }
75
IsValidUinputPath(const std::string& filePath)76 static inline bool IsValidUinputPath(const std::string& filePath)
77 {
78 return IsValidPath(PROC_PATH, filePath);
79 }
80
IsFileExists(const std::string& fileName)81 static inline bool IsFileExists(const std::string& fileName)
82 {
83 return (access(fileName.c_str(), F_OK) == 0);
84 }
85
CheckFileName(const std::string& fileName)86 static bool CheckFileName(const std::string& fileName)
87 {
88 std::string::size_type pos = fileName.find("_");
89 if (pos == std::string::npos) {
90 std::cout << "Failed to create file" << std::endl;
91 return false;
92 }
93 if (!IsNum(fileName.substr(0, pos))) {
94 std::cout << "File name check error" << std::endl;
95 return false;
96 }
97 std::vector<std::string> validFileNames = {
98 "mouse", "keyboard", "joystick", "trackball", "remotecontrol",
99 "trackpad", "knob", "gamepad", "touchpad", "touchscreen",
100 "pen", "pc", "all"
101 };
102 std::string deviceName = fileName.substr(pos + 1);
103 bool result = std::any_of(validFileNames.begin(), validFileNames.end(), [deviceName](const std::string& str) {
104 return str == deviceName;
105 });
106 if (!result) {
107 std::cout << "Check device file name:" << fileName << std::endl;
108 }
109 return result;
110 }
111
RemoveDir(const std::string& filePath)112 static void RemoveDir(const std::string& filePath)
113 {
114 if (filePath.empty()) {
115 std::cout << "File path is empty" << std::endl;
116 return;
117 }
118 DIR* dir = opendir(filePath.c_str());
119 if (dir == nullptr) {
120 std::cout << "Failed to open folder:" << filePath << std::endl;
121 return;
122 }
123 dirent* ptr = nullptr;
124 while ((ptr = readdir(dir)) != nullptr) {
125 std::string tmpDirName(ptr->d_name);
126 if ((tmpDirName == ".") || (tmpDirName == "..")) {
127 continue;
128 }
129 if (ptr->d_type == DT_REG) {
130 std::string rmFile = filePath + ptr->d_name;
131 if (remove(rmFile.c_str()) != 0) {
132 std::cout << "Remove file:" << rmFile << " failed" << std::endl;
133 }
134 } else if (ptr->d_type == DT_DIR) {
135 RemoveDir((filePath + ptr->d_name + "/"));
136 } else {
137 std::cout << "File name:" << ptr << " type is error" << std::endl;
138 }
139 }
140 if (closedir(dir) != 0) {
141 std::cout << "Close dir:" << filePath << " failed" << std::endl;
142 }
143 if (std::remove(filePath.c_str()) != 0) {
144 std::cout << "Remove dir:" << filePath <<" failed" << std::endl;
145 }
146 }
147
StartMouse()148 static void StartMouse()
149 {
150 static VirtualMouse virtualMouse;
151 virtualMouse.SetUp();
152 }
153
StartKeyboard()154 static void StartKeyboard()
155 {
156 static VirtualKeyboard virtualKey;
157 virtualKey.SetUp();
158 static VirtualKeyboardSysCtrl virtualKeyboardSysCtrl;
159 virtualKeyboardSysCtrl.SetUp();
160 static VirtualKeyboardConsumerCtrl virtualKeyboardConsumerCtrl;
161 virtualKeyboardConsumerCtrl.SetUp();
162 static VirtualKeyboardExt virtualKeyext;
163 virtualKeyext.SetUp();
164 }
165
StartJoystick()166 static void StartJoystick()
167 {
168 static VirtualJoystick virtualJoystick;
169 virtualJoystick.SetUp();
170 }
171
StartTrackball()172 static void StartTrackball()
173 {
174 static VirtualTrackball virtualTrackball;
175 virtualTrackball.SetUp();
176 }
177
StartRemoteControl()178 static void StartRemoteControl()
179 {
180 static VirtualRemoteControl virtualRemoteControl;
181 virtualRemoteControl.SetUp();
182 }
183
StartTrackpad()184 static void StartTrackpad()
185 {
186 static VirtualTrackpad virtualTrackpad;
187 virtualTrackpad.SetUp();
188 static VirtualTrackpadMouse virtualMousepadMouse;
189 virtualMousepadMouse.SetUp();
190 static VirtualTrackpadSysCtrl virtualTrackpadSysCtrl;
191 virtualTrackpadSysCtrl.SetUp();
192 }
193
StartPc()194 static void StartPc()
195 {
196 static VirtualPcTouchpad virtualPcTouchpad;
197 virtualPcTouchpad.SetUp();
198 static VirtualPcSwitch virtualPcSwitch;
199 virtualPcSwitch.SetUp();
200 }
201
StartKnob()202 static void StartKnob()
203 {
204 static VirtualKnob virtualKnob;
205 virtualKnob.SetUp();
206 static VirtualKnobConsumerCtrl virtualKnobConsumerCtrl;
207 virtualKnobConsumerCtrl.SetUp();
208 static VirtualKnobMouse virtualKnobMouse;
209 virtualKnobMouse.SetUp();
210 static VirtualKnobSysCtrl virtualKnobSysCtrl;
211 virtualKnobSysCtrl.SetUp();
212 }
213
StartGamePad()214 static void StartGamePad()
215 {
216 static VirtualGamePad virtualGamePad;
217 virtualGamePad.SetUp();
218 }
219
StartTouchPad()220 static void StartTouchPad()
221 {
222 static VirtualStylus virtualStylus;
223 virtualStylus.SetUp();
224 static VirtualTouchpad virtualTouchpad;
225 virtualTouchpad.SetUp();
226 static VirtualFinger virtualFinger;
227 virtualFinger.SetUp();
228 static VirtualSingleFinger virtualSingleFinger;
229 virtualSingleFinger.SetUp();
230 }
231
StartTouchScreen()232 static void StartTouchScreen()
233 {
234 static VirtualTouchScreen virtualTouchScreen;
235 virtualTouchScreen.SetUp();
236 static VirtualSingleTouchScreen virtualSingleTouchScreen;
237 virtualSingleTouchScreen.SetUp();
238 }
239
StartPen()240 static void StartPen()
241 {
242 static VirtualPen virtualPen;
243 virtualPen.SetUp();
244 static VirtualPenMouse virtualPenMouse;
245 virtualPenMouse.SetUp();
246 static VirtualPenKeyboard virtualPenKeyboard;
247 virtualPenKeyboard.SetUp();
248 }
249
StartFingerprint()250 static void StartFingerprint()
251 {
252 static VirtualFingerprintKey fingerprintKey;
253 fingerprintKey.SetUp();
254 static VirtualFingerprintMouse fingerprintMouse;
255 fingerprintMouse.SetUp();
256 }
257
StartCrown()258 static void StartCrown()
259 {
260 static VirtualCrown virtualCrown;
261 virtualCrown.SetUp();
262 }
263
StartUwbRemoteControl()264 static void StartUwbRemoteControl()
265 {
266 static VirtualUwbRemoteControl virtualUwbRemoteControl;
267 virtualUwbRemoteControl.SetUp();
268 }
269
270 using VirtualFun = void (*)();
271 std::map<std::string, VirtualFun> mapFun = {
272 {"mouse", &StartMouse},
273 {"keyboard", &StartKeyboard},
274 {"joystick", &StartJoystick},
275 {"trackball", &StartTrackball},
276 {"remotecontrol", &StartRemoteControl},
277 {"trackpad", &StartTrackpad},
278 {"knob", &StartKnob},
279 {"gamepad", &StartGamePad},
280 {"touchpad", &StartTouchPad},
281 {"pc", &StartPc},
282 {"touchscreen", &StartTouchScreen},
283 {"pen", &StartPen},
284 {"fingerprint", &StartFingerprint},
285 {"crown", &StartCrown},
286 {"uwbremotecontrol", &StartUwbRemoteControl}
287 };
288
StartAllDevices()289 static void StartAllDevices()
290 {
291 if (mapFun.empty()) {
292 std::cout << "mapFun is empty" << std::endl;
293 return;
294 }
295 for (const auto &item : mapFun) {
296 (*item.second)();
297 }
298 }
299 } // namespace
300
VirtualDevice(const std::string& deviceName, uint16_t busType, uint16_t vendorId, uint16_t productId)301 VirtualDevice::VirtualDevice(const std::string& deviceName, uint16_t busType,
302 uint16_t vendorId, uint16_t productId)
303 : deviceName_(deviceName),
304 busTtype_(busType),
305 vendorId_(vendorId),
306 productId_(productId),
307 version_(1) {}
308
~VirtualDevice()309 VirtualDevice::~VirtualDevice()
310 {
311 Close();
312 }
313
BrowseDirectory(const std::string& filePath)314 std::vector<std::string> VirtualDevice::BrowseDirectory(const std::string& filePath)
315 {
316 std::vector<std::string> fileList;
317 DIR* dir = opendir(filePath.c_str());
318 if (dir == nullptr) {
319 std::cout << "Failed to open folder" << std::endl;
320 return fileList;
321 }
322 dirent* ptr = nullptr;
323 while ((ptr = readdir(dir)) != nullptr) {
324 if (ptr->d_type == DT_REG) {
325 if (ClearFileResidues(ptr->d_name)) {
326 fileList.push_back(ptr->d_name);
327 }
328 }
329 }
330 if (closedir(dir) != 0) {
331 std::cout << "Close dir:" << filePath << " failed" << std::endl;
332 }
333 return fileList;
334 }
335
ClearFileResidues(const std::string& fileName)336 bool VirtualDevice::ClearFileResidues(const std::string& fileName)
337 {
338 const std::string::size_type pos = fileName.find("_");
339 const std::string processPath = "/proc/" + fileName.substr(0, pos) + "/";
340 const std::string filePath = processPath + "cmdline";
341 std::string temp;
342 std::string processName;
343 DIR *dir = nullptr;
344 if (!CheckFileName(fileName)) {
345 std::cout << "File name check error" << std::endl;
346 goto RELEASE_RES1;
347 }
348 if (pos == std::string::npos) {
349 std::cout << "Failed to create file" << std::endl;
350 goto RELEASE_RES1;
351 }
352 if (!IsFileExists(processPath)) {
353 std::cout << processPath << " folder does not exist" << std::endl;
354 goto RELEASE_RES1;
355 }
356 dir = opendir(processPath.c_str());
357 if (dir == nullptr) {
358 std::cout << "Useless flag file:" << processPath << std::endl;
359 goto RELEASE_RES1;
360 }
361 temp = ReadUinputToolFile(filePath);
362 if (temp.empty()) {
363 std::cout << "Temp is empty" << std::endl;
364 goto RELEASE_RES2;
365 }
366 processName.append(temp);
367 if (processName.find(VIRTUAL_DEVICE_NAME.c_str()) == std::string::npos) {
368 std::cout << "Process name is wrong" << std::endl;
369 goto RELEASE_RES2;
370 }
371 return true;
372 RELEASE_RES1:
373 if (remove((g_folderPath + fileName).c_str()) != 0) {
374 std::cout << "Remove file failed" << std::endl;
375 }
376 return false;
377 RELEASE_RES2:
378 if (closedir(dir) != 0) {
379 std::cout << "Close dir failed" << std::endl;
380 }
381 if (remove((g_folderPath + fileName).c_str()) != 0) {
382 std::cout << "Remove file failed" << std::endl;
383 }
384 return false;
385 }
386
CreateKey()387 bool VirtualDevice::CreateKey()
388 {
389 auto fun = [&](int32_t uiSet, const std::vector<uint32_t>& list) ->bool {
390 for (const auto &item : list) {
391 if (ioctl(fd_, uiSet, item) < 0) {
392 std::cout << __func__ << " not setting event type:" << item
393 << ", deviceName:" << deviceName_ << std::endl;
394 return false;
395 }
396 }
397 return true;
398 };
399 std::map<int32_t, std::vector<uint32_t>> uinputTypes;
400 uinputTypes[UI_SET_EVBIT] = GetEventTypes();
401 uinputTypes[UI_SET_KEYBIT] = GetKeys();
402 uinputTypes[UI_SET_PROPBIT] = GetProperties();
403 uinputTypes[UI_SET_ABSBIT] = GetAbs();
404 uinputTypes[UI_SET_RELBIT] = GetRelBits();
405 uinputTypes[UI_SET_MSCBIT] = GetMiscellaneous();
406 uinputTypes[UI_SET_LEDBIT] = GetLeds();
407 uinputTypes[UI_SET_SWBIT] = GetSwitches();
408 uinputTypes[UI_SET_FFBIT] = GetRepeats();
409
410 for (const auto &item : uinputTypes) {
411 if (!fun(item.first, item.second)) {
412 return false;
413 }
414 }
415 return true;
416 }
417
SetAbsResolution()418 bool VirtualDevice::SetAbsResolution()
419 {
420 for (const auto &item : absInit_) {
421 ioctl(fd_, UI_ABS_SETUP, &item);
422 }
423 return true;
424 }
425
SetPhys(const std::string& deviceName)426 bool VirtualDevice::SetPhys(const std::string& deviceName)
427 {
428 std::string phys;
429 std::map<std::string, std::string> typeDevice = {
430 {"Virtual Mouse", "mouse"},
431 {"Virtual Crown", "mouse"},
432 {"Virtual keyboard", "keyboard"},
433 {"Virtual KeyboardConsumerCtrl", "keyboard"},
434 {"Virtual keyboardExt", "keyboard"},
435 {"Virtual KeyboardSysCtrl", "keyboard"},
436 {"Virtual Knob", "knob"},
437 {"Virtual KnobConsumerCtrl", "knob"},
438 {"Virtual KnobMouse", "knob"},
439 {"Virtual KnobSysCtrl", "knob"},
440 {"Virtual Trackpad", "trackpad"},
441 {"Virtual TrackPadMouse", "trackpad"},
442 {"Virtual TrackpadSysCtrl", "trackpad"},
443 {"Virtual Finger", "touchpad"},
444 {"Virtual SingleFinger", "touchpad"},
445 {"Virtual Stylus", "touchpad"},
446 {"Virtual Touchpad", "touchpad"},
447 {"Virtual PcSwitch", "pc"},
448 {"Virtual PcTouchPad", "pc"},
449 {"Virtual RemoteControl", "remotecontrol"},
450 {"Virtual Joystick", "joystick"},
451 {"Virtual GamePad", "gamepad"},
452 {"Virtual Trackball", "trackball"},
453 {"Virtual TouchScreen", "touchscreen"},
454 {"Virtual SingleTouchScreen", "touchscreen"},
455 {"V-Pencil", "pen"},
456 {"V-Pencil-mouse", "pen"},
457 {"V-Pencil-keyboard", "pen"},
458 {"Virtual UWB RemoteControl", "uwbremotecontrol"}
459 };
460 std::string deviceType = typeDevice.find(deviceName)->second;
461 phys.append(deviceType).append(g_pid).append("/").append(g_pid);
462
463 if (ioctl(fd_, UI_SET_PHYS, phys.c_str()) < 0) {
464 std::cout << "Failed to set uinput phys" << std::endl;
465 return false;
466 }
467 return true;
468 }
469
DoIoctl(int32_t fd, int32_t request, const uint32_t value)470 bool VirtualDevice::DoIoctl(int32_t fd, int32_t request, const uint32_t value)
471 {
472 int32_t rc = ioctl(fd, request, value);
473 if (rc < 0) {
474 std::cout << "Failed to ioctl" << std::endl;
475 return false;
476 }
477 return true;
478 }
479
SetDeviceId()480 void VirtualDevice::SetDeviceId()
481 {
482 uinputDev_.id.bustype = busTtype_;
483 uinputDev_.id.vendor = vendorId_;
484 uinputDev_.id.product = productId_;
485 uinputDev_.id.version = version_;
486 }
487
SetUp()488 bool VirtualDevice::SetUp()
489 {
490 fd_ = open("/dev/uinput", O_WRONLY | O_NONBLOCK);
491 if (fd_ < 0) {
492 std::cout << "Failed to open uinput: " << fd_ << std::endl;
493 return false;
494 }
495
496 if (strncpy_s(uinputDev_.name, sizeof(uinputDev_.name), deviceName_.c_str(), deviceName_.size()) != 0) {
497 std::cout << "Failed to copied device name: " << uinputDev_.name << std::endl;
498 return false;
499 };
500 SetDeviceId();
501 if (!SetAbsResolution()) {
502 std::cout << "Failed to set uinput abs resolution" << std::endl;
503 return false;
504 }
505 if (!SetPhys(deviceName_)) {
506 std::cout << "Failed to set uinput phys" << std::endl;
507 return false;
508 }
509 if (!CreateKey()) {
510 std::cout << "Failed to create uinput KeyValue" << std::endl;
511 return false;
512 }
513 if (write(fd_, &uinputDev_, sizeof(uinputDev_)) < 0) {
514 std::cout << "Unable to write device info to target" << std::endl;
515 return false;
516 }
517 if (ioctl(fd_, UI_DEV_CREATE) < 0) {
518 std::cout << "Try to create uinput device filed in fd: " << fd_ << std::endl;
519 return false;
520 }
521 return true;
522 }
523
Close()524 void VirtualDevice::Close()
525 {
526 if (fd_ >= 0) {
527 ioctl(fd_, UI_DEV_DESTROY);
528 close(fd_);
529 fd_ = -1;
530 }
531 }
532
ReadFile(const std::string& filePath)533 std::string VirtualDevice::ReadFile(const std::string& filePath)
534 {
535 FILE* fp = fopen(filePath.c_str(), "r");
536 if (fp == nullptr) {
537 std::cout << "Failed to open file: " << filePath << std::endl;
538 return "";
539 }
540 std::string dataStr;
541 char buf[256] = {};
542 while (fgets(buf, sizeof(buf), fp) != nullptr) {
543 dataStr += buf;
544 }
545 if (fclose(fp) != 0) {
546 std::cout << "Failed to close file" << std::endl;
547 }
548 return dataStr;
549 }
550
GetFileSize(const std::string& filePath)551 int32_t VirtualDevice::GetFileSize(const std::string& filePath)
552 {
553 struct stat statbuf = { 0 };
554 if (stat(filePath.c_str(), &statbuf) != 0) {
555 std::cout << "Get file size error" << std::endl;
556 return INVALID_FILE_SIZE;
557 }
558 return statbuf.st_size;
559 }
560
ReadUinputToolFile(const std::string& filePath)561 std::string VirtualDevice::ReadUinputToolFile(const std::string& filePath)
562 {
563 if (filePath.empty()) {
564 std::cout << "FilePath is empty" << std::endl;
565 return "";
566 }
567 char realPath[PATH_MAX] = {};
568 if (realpath(filePath.c_str(), realPath) == nullptr) {
569 std::cout << "Path is error" << std::endl;
570 return "";
571 }
572 if (!IsValidUinputPath(realPath)) {
573 std::cout << "File path is error" << std::endl;
574 return "";
575 }
576 if (!IsFileExists(realPath)) {
577 std::cout << "File not exist" << std::endl;
578 return "";
579 }
580 int32_t fileSize = GetFileSize(realPath);
581 if ((fileSize < 0) || (fileSize > FILE_SIZE_MAX)) {
582 std::cout << "File size out of read range" << std::endl;
583 return "";
584 }
585 return ReadFile(filePath);
586 }
587
CreateHandle(const std::string& deviceArgv)588 bool VirtualDevice::CreateHandle(const std::string& deviceArgv)
589 {
590 if (deviceArgv == "all") {
591 StartAllDevices();
592 return true;
593 }
594 if (mapFun.find(deviceArgv) == mapFun.end()) {
595 std::cout << "Please enter the device type correctly" << std::endl;
596 return false;
597 }
598 (*mapFun[deviceArgv])();
599 return true;
600 }
601
AddDevice(const std::string& startDeviceName)602 bool VirtualDevice::AddDevice(const std::string& startDeviceName)
603 {
604 if (startDeviceName.empty()) {
605 std::cout << "StartDeviceName is empty" << std::endl;
606 return false;
607 }
608 if (!CreateHandle(startDeviceName)) {
609 std::cout << "Failed to start device: " << startDeviceName <<std::endl;
610 return false;
611 }
612 std::string symbolFile;
613 symbolFile.append(g_folderPath).append(g_pid).append("_").append(startDeviceName);
614 std::ofstream flagFile;
615 flagFile.open(symbolFile.c_str());
616 if (!flagFile.is_open()) {
617 std::cout << "Failed to create file" <<std::endl;
618 return false;
619 }
620 flagFile.close();
621 return true;
622 }
623
CloseDevice(const std::string& closeDeviceName, const std::vector<std::string>& deviceList)624 bool VirtualDevice::CloseDevice(const std::string& closeDeviceName, const std::vector<std::string>& deviceList)
625 {
626 if (deviceList.empty()) {
627 RemoveDir(g_folderPath);
628 std::cout << "No start device" <<std::endl;
629 return false;
630 }
631 if (closeDeviceName == "all") {
632 for (const auto &it : deviceList) {
633 kill(std::stoi(it), SIGKILL);
634 }
635 RemoveDir(g_folderPath);
636 return true;
637 }
638 for (const auto &it : deviceList) {
639 if (it.find(closeDeviceName) == 0) {
640 kill(std::stoi(it), SIGKILL);
641 remove((g_folderPath + it).c_str());
642 if (BrowseDirectory(g_folderPath).empty()) {
643 RemoveDir(g_folderPath);
644 }
645 return true;
646 }
647 }
648 std::cout << "Device shutdown failed! The PID format is incorrect" <<std::endl;
649 return false;
650 }
651
CheckCommand(int32_t argc, char **argv)652 bool VirtualDevice::CheckCommand(int32_t argc, char **argv)
653 {
654 int32_t c = -1;
655 if (!SelectOptions(argc, argv, c)) {
656 std::cout << "Select option failed" << std::endl;
657 return false;
658 }
659 if (!IsFileExists(g_folderPath)) {
660 mkdir(g_folderPath.c_str(), FILE_POWER);
661 }
662 switch (c) {
663 case 'L': {
664 if (!ListOption(argc, argv)) {
665 std::cout << "Device query failed" << std::endl;
666 return false;
667 }
668 break;
669 }
670 case 'S': {
671 if (!StartOption(argc, argv)) {
672 std::cout << "Device start failed" << std::endl;
673 return false;
674 }
675 break;
676 }
677 case 'C': {
678 if (!CloseOption(argc, argv)) {
679 std::cout << "Device close failed" << std::endl;
680 return false;
681 }
682 break;
683 }
684 case '?': {
685 if (!HelpOption(argc, argv)) {
686 std::cout << "Failed to ask for help" << std::endl;
687 return false;
688 }
689 break;
690 }
691 default: {
692 std::cout << "The command line format is incorrect" << std::endl;
693 return false;
694 }
695 }
696 return true;
697 }
698
SelectOptions(int32_t argc, char **argv, int32_t &opt)699 bool VirtualDevice::SelectOptions(int32_t argc, char **argv, int32_t &opt)
700 {
701 if (argc < PARAMETERS_QUERY_NUMBER) {
702 std::cout << "Please enter options or parameters" << std::endl;
703 return false;
704 }
705 struct option longOptions[] = {
706 {"list", no_argument, nullptr, 'L'},
707 {"start", no_argument, nullptr, 'S'},
708 {"close", no_argument, nullptr, 'C'},
709 {"help", no_argument, nullptr, '?'},
710 {nullptr, 0, nullptr, 0}
711 };
712 std::string inputOptions = argv[optind];
713 if (inputOptions.find('-') == inputOptions.npos) {
714 for (uint32_t i = 0; i < sizeof(longOptions) / sizeof(struct option) - 1; ++i) {
715 if (longOptions[i].name == inputOptions) {
716 opt = longOptions[i].val;
717 optind++;
718 break;
719 }
720 }
721 } else if ((inputOptions.length() != PARAMETERS_QUERY_NUMBER) &&
722 (inputOptions[inputOptions.find('-') + 1] != '-')) {
723 std::cout << "More than one short option is not supported" << std::endl;
724 return false;
725 } else {
726 int32_t optionIndex = 0;
727 opt = getopt_long(argc, argv, "LSC?", longOptions, &optionIndex);
728 }
729 if (opt == -1) {
730 std::cout << "Nonstandard input parameters" << std::endl;
731 return false;
732 }
733 return true;
734 }
735
ListOption(int32_t argc, char **argv)736 bool VirtualDevice::ListOption(int32_t argc, char **argv)
737 {
738 if (argc != PARAMETERS_QUERY_NUMBER) {
739 std::cout << "Invalid Input Param, Please Check the validity of the para" << std::endl;
740 return false;
741 }
742 std::vector<std::string> deviceList = BrowseDirectory(g_folderPath);
743 if (deviceList.empty()) {
744 std::cout << "No device information to query" << std::endl;
745 return true;
746 }
747 std::string::size_type pos;
748 std::cout << "PID\tDEVICE" << std::endl;
749 for (const auto &item : deviceList) {
750 pos = item.find("_");
751 if (pos != std::string::npos) {
752 std::cout << item.substr(0, pos) << "\t" << item.substr(pos + 1, item.size() - pos - 1) << std::endl;
753 }
754 }
755 return true;
756 }
757
StartOption(int32_t argc, char **argv)758 bool VirtualDevice::StartOption(int32_t argc, char **argv)
759 {
760 if (argc != PARAMETERS_NUMBER) {
761 std::cout << "Invalid Input Param, Please Check the validity of the para" << std::endl;
762 return false;
763 }
764 if (!AddDevice(argv[optind])) {
765 std::cout << "Failed to create device" << std::endl;
766 return false;
767 }
768 while (true) {
769 usleep(SLEEP_TIME);
770 }
771 return true;
772 }
773
CloseOption(int32_t argc, char **argv)774 bool VirtualDevice::CloseOption(int32_t argc, char **argv)
775 {
776 std::vector<std::string> deviceList = BrowseDirectory(g_folderPath);
777 if (argc != PARAMETERS_NUMBER) {
778 std::cout << "Invalid Input Param, Please Check the validity of the para" << std::endl;
779 return false;
780 }
781 if (!CloseDevice(argv[optind], deviceList)) {
782 std::cout << "Failed to closed device" << std::endl;
783 return false;
784 }
785 std::cout << "device closed successfully" << std::endl;
786 return true;
787 }
788
HelpOption(int32_t argc, char **argv)789 bool VirtualDevice::HelpOption(int32_t argc, char **argv)
790 {
791 if (argc != PARAMETERS_QUERY_NUMBER) {
792 std::cout << "Invalid Input Param, Please Check the validity of the para" << std::endl;
793 return false;
794 }
795 ShowUsage();
796 return true;
797 }
798
SetResolution(const ResolutionInfo& resolutionInfo)799 void VirtualDevice::SetResolution(const ResolutionInfo& resolutionInfo)
800 {
801 uinputAbs_.code = resolutionInfo.axisCode;
802 uinputAbs_.absinfo.resolution = resolutionInfo.absResolution;
803 absInit_.push_back(uinputAbs_);
804 }
805
SetAbsValue(const AbsInfo& absInfo)806 void VirtualDevice::SetAbsValue(const AbsInfo& absInfo)
807 {
808 uinputDev_.absmin[absInfo.code] = absInfo.minValue;
809 uinputDev_.absmax[absInfo.code] = absInfo.maxValue;
810 uinputDev_.absfuzz[absInfo.code] = absInfo.fuzz;
811 uinputDev_.absflat[absInfo.code] = absInfo.flat;
812 }
813
GetEventTypes() const814 const std::vector<uint32_t>& VirtualDevice::GetEventTypes() const
815 {
816 return eventTypes_;
817 }
818
GetKeys() const819 const std::vector<uint32_t>& VirtualDevice::GetKeys() const
820 {
821 return keys_;
822 }
823
GetProperties() const824 const std::vector<uint32_t>& VirtualDevice::GetProperties() const
825 {
826 return properties_;
827 }
828
GetAbs() const829 const std::vector<uint32_t>& VirtualDevice::GetAbs() const
830 {
831 return abs_;
832 }
833
GetRelBits() const834 const std::vector<uint32_t>& VirtualDevice::GetRelBits() const
835 {
836 return relBits_;
837 }
838
GetLeds() const839 const std::vector<uint32_t>& VirtualDevice::GetLeds() const
840 {
841 return leds_;
842 }
843
GetRepeats() const844 const std::vector<uint32_t>& VirtualDevice::GetRepeats() const
845 {
846 return repeats_;
847 }
848
GetMiscellaneous() const849 const std::vector<uint32_t>& VirtualDevice::GetMiscellaneous() const
850 {
851 return miscellaneous_;
852 }
853
GetSwitches() const854 const std::vector<uint32_t>& VirtualDevice::GetSwitches() const
855 {
856 return switches_;
857 }
858
ShowUsage()859 void VirtualDevice::ShowUsage()
860 {
861 std::cout << "Usage: vuinput <option> <command> <arg>..." << std::endl;
862 std::cout << "The option are: " << std::endl;
863 std::cout << "commands for list: " << std::endl;
864 std::cout << "-L --list list -display virtual devices and pid information" << std::endl;
865 std::cout << "commands for start: " << std::endl;
866 std::cout << "-S <device> & --start <device> & start <device> & -start a device" << std::endl;
867 std::cout << " -start supported <device>-" << std::endl;
868 std::cout << " mouse" << std::endl;
869 std::cout << " keyboard" << std::endl;
870 std::cout << " joystick" << std::endl;
871 std::cout << " trackball" << std::endl;
872 std::cout << " remotecontrol" << std::endl;
873 std::cout << " trackpad" << std::endl;
874 std::cout << " knob" << std::endl;
875 std::cout << " gamepad" << std::endl;
876 std::cout << " touchpad" << std::endl;
877 std::cout << " touchscreen" << std::endl;
878 std::cout << " pen" << std::endl;
879 std::cout << "-S all & --start all & start all & -start devices " << std::endl;
880 std::cout << "commands for close: " << std::endl;
881 std::cout << "-C <pid> --close <pid> close <pid> -close a pid " << std::endl;
882 std::cout << "-C all --close all close all -close pids " << std::endl;
883 std::cout << "-? --help help " << std::endl;
884 }
885 } // namespace MMI
886 } // namespace OHOS
887