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