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