1f857971dSopenharmony_ci/*
2f857971dSopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3f857971dSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4f857971dSopenharmony_ci * you may not use this file except in compliance with the License.
5f857971dSopenharmony_ci * You may obtain a copy of the License at
6f857971dSopenharmony_ci *
7f857971dSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8f857971dSopenharmony_ci *
9f857971dSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10f857971dSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11f857971dSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12f857971dSopenharmony_ci * See the License for the specific language governing permissions and
13f857971dSopenharmony_ci * limitations under the License.
14f857971dSopenharmony_ci */
15f857971dSopenharmony_ci
16f857971dSopenharmony_ci#include "virtual_mouse_builder.h"
17f857971dSopenharmony_ci
18f857971dSopenharmony_ci#include <getopt.h>
19f857971dSopenharmony_ci#include <fstream>
20f857971dSopenharmony_ci#include <iostream>
21f857971dSopenharmony_ci#include <unordered_map>
22f857971dSopenharmony_ci
23f857971dSopenharmony_ci#include <linux/input.h>
24f857971dSopenharmony_ci
25f857971dSopenharmony_ci#include "input_manager.h"
26f857971dSopenharmony_ci
27f857971dSopenharmony_ci#include "devicestatus_define.h"
28f857971dSopenharmony_ci#include "fi_log.h"
29f857971dSopenharmony_ci#include "utility.h"
30f857971dSopenharmony_ci#include "virtual_mouse.h"
31f857971dSopenharmony_ci
32f857971dSopenharmony_ci#undef LOG_TAG
33f857971dSopenharmony_ci#define LOG_TAG "VirtualMouseBuilder"
34f857971dSopenharmony_ci
35f857971dSopenharmony_cinamespace OHOS {
36f857971dSopenharmony_cinamespace Msdp {
37f857971dSopenharmony_cinamespace DeviceStatus {
38f857971dSopenharmony_cinamespace {
39f857971dSopenharmony_ciconstexpr int32_t MAXIMUM_LEVEL_ALLOWED { 3 };
40f857971dSopenharmony_ciconstexpr uint32_t IO_FLAG_WIDTH { 6 };
41f857971dSopenharmony_ciconst std::unordered_map<std::string, int32_t> mouseBtns {
42f857971dSopenharmony_ci    { "BTN_LEFT", BTN_LEFT }, { "BTN_RIGHT", BTN_RIGHT },
43f857971dSopenharmony_ci    { "BTN_MIDDLE", BTN_MIDDLE }, { "BTN_SIDE", BTN_SIDE },
44f857971dSopenharmony_ci    { "BTN_EXTRA", BTN_EXTRA }, { "BTN_FORWARD", BTN_FORWARD },
45f857971dSopenharmony_ci    { "BTN_BACK", BTN_BACK }, { "BTN_TASK", BTN_TASK } };
46f857971dSopenharmony_ci} // namespace
47f857971dSopenharmony_ci
48f857971dSopenharmony_ciVirtualMouseBuilder::VirtualMouseBuilder() : VirtualDeviceBuilder(GetDeviceName(), BUS_USB, 0x93a, 0x2510)
49f857971dSopenharmony_ci{
50f857971dSopenharmony_ci    eventTypes_ = { EV_KEY, EV_REL, EV_MSC };
51f857971dSopenharmony_ci    keys_ = { BTN_LEFT, BTN_RIGHT, BTN_MIDDLE, BTN_SIDE, BTN_EXTRA, BTN_FORWARD, BTN_BACK, BTN_TASK };
52f857971dSopenharmony_ci    relBits_ = { REL_X, REL_Y, REL_WHEEL, REL_WHEEL_HI_RES };
53f857971dSopenharmony_ci    miscellaneous_ = { MSC_SCAN };
54f857971dSopenharmony_ci}
55f857971dSopenharmony_ci
56f857971dSopenharmony_ciclass MouseEventMonitor final : public MMI::IInputEventConsumer {
57f857971dSopenharmony_cipublic:
58f857971dSopenharmony_ci    MouseEventMonitor() = default;
59f857971dSopenharmony_ci    ~MouseEventMonitor() = default;
60f857971dSopenharmony_ci
61f857971dSopenharmony_ci    void OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const override {};
62f857971dSopenharmony_ci    void OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const override;
63f857971dSopenharmony_ci    void OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const override {};
64f857971dSopenharmony_ci};
65f857971dSopenharmony_ci
66f857971dSopenharmony_civoid MouseEventMonitor::OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const
67f857971dSopenharmony_ci{
68f857971dSopenharmony_ci    CHKPV(pointerEvent);
69f857971dSopenharmony_ci    if (pointerEvent->GetSourceType() != MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
70f857971dSopenharmony_ci        return;
71f857971dSopenharmony_ci    }
72f857971dSopenharmony_ci    MMI::PointerEvent::PointerItem pointerItem;
73f857971dSopenharmony_ci    if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
74f857971dSopenharmony_ci        return;
75f857971dSopenharmony_ci    }
76f857971dSopenharmony_ci    std::cout << "\rcurrent pointer position - x: " << std::setw(IO_FLAG_WIDTH) << std::left <<
77f857971dSopenharmony_ci        pointerItem.GetDisplayX() << "y: " << pointerItem.GetDisplayY() << "            ";
78f857971dSopenharmony_ci    std::cout.flush();
79f857971dSopenharmony_ci}
80f857971dSopenharmony_ci
81f857971dSopenharmony_cistd::string VirtualMouseBuilder::GetDeviceName()
82f857971dSopenharmony_ci{
83f857971dSopenharmony_ci    return std::string("Virtual Mouse");
84f857971dSopenharmony_ci}
85f857971dSopenharmony_ci
86f857971dSopenharmony_civoid VirtualMouseBuilder::ShowUsage()
87f857971dSopenharmony_ci{
88f857971dSopenharmony_ci    std::cout << "Usage: vdevadm act -t M [-d <mouse-button>] [-u <mouse-button>] [-s <dv>]" << std::endl;
89f857971dSopenharmony_ci    std::cout << "          [-m <dx> [<dy>]] [-M <x> <y>] [-w <ms>] [-f <FILE>] [-r <FILE>]" << std::endl;
90f857971dSopenharmony_ci    std::cout << "      -d <mouse-button>" << std::endl;
91f857971dSopenharmony_ci    std::cout << "                  Down the <mouse-button>" << std::endl;
92f857971dSopenharmony_ci    std::cout << "      -u <mouse-button>" << std::endl;
93f857971dSopenharmony_ci    std::cout << "                  Release the <mouse-button>" << std::endl;
94f857971dSopenharmony_ci    std::cout << "      -s <dy>     Scroll the mouse wheel" << std::endl;
95f857971dSopenharmony_ci    std::cout << "      -m <dx> [<dy>]" << std::endl;
96f857971dSopenharmony_ci    std::cout << "                  Move the mouse along <dx, dy>; if <dy> is missing, then set dy=dx" << std::endl;
97f857971dSopenharmony_ci    std::cout << "      -M <x> <y>  Move the pointer to <x, y>" << std::endl;
98f857971dSopenharmony_ci    std::cout << "      -D <SLOT> <sx> <sy> <tx> <ty> Drag the touch <SLOT> to (tx, ty)" << std::endl;
99f857971dSopenharmony_ci    std::cout << "      -w <ms>     Wait for <ms> milliseconds." << std::endl;
100f857971dSopenharmony_ci    std::cout << "      -f <FILE>   Read actions from <FILE>" << std::endl;
101f857971dSopenharmony_ci    std::cout << "      -r <FILE>   Read raw input data from <FILE>." << std::endl;
102f857971dSopenharmony_ci    std::cout << std::endl;
103f857971dSopenharmony_ci    std::cout << "          <mouse-button> can be:" << std::endl;
104f857971dSopenharmony_ci    std::cout << "              L   For left mouse button" << std::endl;
105f857971dSopenharmony_ci    std::cout << "              R   For right mouse button" << std::endl;
106f857971dSopenharmony_ci    std::cout << "              M   For middle mouse button" << std::endl;
107f857971dSopenharmony_ci}
108f857971dSopenharmony_ci
109f857971dSopenharmony_civoid VirtualMouseBuilder::Mount()
110f857971dSopenharmony_ci{
111f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
112f857971dSopenharmony_ci    std::cout << "Start to mount virtual mouse." << std::endl;
113f857971dSopenharmony_ci    if (VirtualMouse::GetDevice() != nullptr) {
114f857971dSopenharmony_ci        std::cout << "Virtual mouse has been mounted." << std::endl;
115f857971dSopenharmony_ci        return;
116f857971dSopenharmony_ci    }
117f857971dSopenharmony_ci    VirtualMouseBuilder vMouse;
118f857971dSopenharmony_ci    if (!vMouse.SetUp()) {
119f857971dSopenharmony_ci        std::cout << "Failed to mount virtual mouse." << std::endl;
120f857971dSopenharmony_ci        return;
121f857971dSopenharmony_ci    }
122f857971dSopenharmony_ci
123f857971dSopenharmony_ci    int32_t nTries = 6;
124f857971dSopenharmony_ci    do {
125f857971dSopenharmony_ci        std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME));
126f857971dSopenharmony_ci    } while ((nTries-- > 0) && (VirtualMouse::GetDevice() == nullptr));
127f857971dSopenharmony_ci    if (VirtualMouse::GetDevice() == nullptr) {
128f857971dSopenharmony_ci        std::cout << "Failed to mount virtual mouse." << std::endl;
129f857971dSopenharmony_ci        return;
130f857971dSopenharmony_ci    }
131f857971dSopenharmony_ci
132f857971dSopenharmony_ci    std::cout << "Mount virtual mouse successfully." << std::endl;
133f857971dSopenharmony_ci    VirtualDeviceBuilder::Daemonize();
134f857971dSopenharmony_ci
135f857971dSopenharmony_ci    for (;;) {
136f857971dSopenharmony_ci        std::this_thread::sleep_for(std::chrono::minutes(1));
137f857971dSopenharmony_ci    }
138f857971dSopenharmony_ci}
139f857971dSopenharmony_ci
140f857971dSopenharmony_civoid VirtualMouseBuilder::Unmount()
141f857971dSopenharmony_ci{
142f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
143f857971dSopenharmony_ci    VirtualDeviceBuilder::Unmount("mouse", "M");
144f857971dSopenharmony_ci}
145f857971dSopenharmony_ci
146f857971dSopenharmony_civoid VirtualMouseBuilder::Clone()
147f857971dSopenharmony_ci{
148f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
149f857971dSopenharmony_ci    if (VirtualMouse::GetDevice() != nullptr) {
150f857971dSopenharmony_ci        std::cout << "Virtual mouse has been mounted." << std::endl;
151f857971dSopenharmony_ci        return;
152f857971dSopenharmony_ci    }
153f857971dSopenharmony_ci
154f857971dSopenharmony_ci    std::vector<std::shared_ptr<VirtualDevice>> vDevs;
155f857971dSopenharmony_ci    int32_t ret = VirtualDeviceBuilder::ScanFor(
156f857971dSopenharmony_ci        [](std::shared_ptr<VirtualDevice> vDev) { return ((vDev != nullptr) && vDev->IsMouse()); }, vDevs);
157f857971dSopenharmony_ci    if (ret != RET_OK) {
158f857971dSopenharmony_ci        std::cout << "Failed while scanning for mouse." << std::endl;
159f857971dSopenharmony_ci        return;
160f857971dSopenharmony_ci    }
161f857971dSopenharmony_ci    auto vDev = VirtualDeviceBuilder::Select(vDevs, "mouse");
162f857971dSopenharmony_ci    CHKPV(vDev);
163f857971dSopenharmony_ci
164f857971dSopenharmony_ci    std::cout << "Cloning \'" << vDev->GetName() << "\'." << std::endl;
165f857971dSopenharmony_ci    VirtualDeviceBuilder vBuilder(GetDeviceName(), vDev);
166f857971dSopenharmony_ci    if (!vBuilder.SetUp()) {
167f857971dSopenharmony_ci        std::cout << "Clone  \' " << vDev->GetName() << " \' is failed." << std::endl;
168f857971dSopenharmony_ci        return;
169f857971dSopenharmony_ci    }
170f857971dSopenharmony_ci    int32_t nTries = 3;
171f857971dSopenharmony_ci    do {
172f857971dSopenharmony_ci        std::this_thread::sleep_for(std::chrono::seconds(1));
173f857971dSopenharmony_ci    } while ((nTries-- > 0) && (VirtualMouse::GetDevice() == nullptr));
174f857971dSopenharmony_ci    if (VirtualMouse::GetDevice() == nullptr) {
175f857971dSopenharmony_ci        std::cout << "Failed to clone \' " << vDev->GetName() << " \'." << std::endl;
176f857971dSopenharmony_ci        return;
177f857971dSopenharmony_ci    }
178f857971dSopenharmony_ci
179f857971dSopenharmony_ci    std::cout << "Clone \'" << vDev->GetName() << "\' successfully." << std::endl;
180f857971dSopenharmony_ci    VirtualDeviceBuilder::Daemonize();
181f857971dSopenharmony_ci    for (;;) {
182f857971dSopenharmony_ci        std::this_thread::sleep_for(std::chrono::minutes(1));
183f857971dSopenharmony_ci    }
184f857971dSopenharmony_ci}
185f857971dSopenharmony_ci
186f857971dSopenharmony_civoid VirtualMouseBuilder::Monitor()
187f857971dSopenharmony_ci{
188f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
189f857971dSopenharmony_ci    MMI::InputManager *inputMgr = MMI::InputManager::GetInstance();
190f857971dSopenharmony_ci    CHKPV(inputMgr);
191f857971dSopenharmony_ci    auto monitor = std::make_shared<MouseEventMonitor>();
192f857971dSopenharmony_ci    int32_t monitorId = inputMgr->AddMonitor(monitor);
193f857971dSopenharmony_ci    if (monitorId < 0) {
194f857971dSopenharmony_ci        std::cout << "Failed to add monitor." << std::endl;
195f857971dSopenharmony_ci        return;
196f857971dSopenharmony_ci    }
197f857971dSopenharmony_ci    for (;;) {
198f857971dSopenharmony_ci        std::this_thread::sleep_for(std::chrono::minutes(1));
199f857971dSopenharmony_ci    }
200f857971dSopenharmony_ci}
201f857971dSopenharmony_ci
202f857971dSopenharmony_civoid VirtualMouseBuilder::Act(int32_t argc, char *argv[])
203f857971dSopenharmony_ci{
204f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
205f857971dSopenharmony_ci    int32_t opt = getopt(argc, argv, "d:u:s:m:M:f:r:w:D:");
206f857971dSopenharmony_ci    if (opt < 0) {
207f857971dSopenharmony_ci        std::cout << "Vdevadm act: required option is missing" << std::endl;
208f857971dSopenharmony_ci        VirtualMouseBuilder::ShowUsage();
209f857971dSopenharmony_ci        return;
210f857971dSopenharmony_ci    }
211f857971dSopenharmony_ci    if (VirtualMouse::GetDevice() == nullptr) {
212f857971dSopenharmony_ci        std::cout << "No virtual mouse." << std::endl;
213f857971dSopenharmony_ci        return;
214f857971dSopenharmony_ci    }
215f857971dSopenharmony_ci    do {
216f857971dSopenharmony_ci        {
217f857971dSopenharmony_ci            auto action = ruleMouseActions_.find(opt);
218f857971dSopenharmony_ci            if (action != ruleMouseActions_.end()) {
219f857971dSopenharmony_ci                action->second();
220f857971dSopenharmony_ci                continue;
221f857971dSopenharmony_ci            }
222f857971dSopenharmony_ci        }
223f857971dSopenharmony_ci        {
224f857971dSopenharmony_ci            auto action = readMouseActions_.find(opt);
225f857971dSopenharmony_ci            if (action != readMouseActions_.end()) {
226f857971dSopenharmony_ci                action->second(optarg);
227f857971dSopenharmony_ci                continue;
228f857971dSopenharmony_ci            }
229f857971dSopenharmony_ci        }
230f857971dSopenharmony_ci        {
231f857971dSopenharmony_ci            auto action = moveMouseActions_.find(opt);
232f857971dSopenharmony_ci            if (action != moveMouseActions_.end()) {
233f857971dSopenharmony_ci                action->second(argc, argv);
234f857971dSopenharmony_ci                continue;
235f857971dSopenharmony_ci            }
236f857971dSopenharmony_ci        }
237f857971dSopenharmony_ci        if (opt == 'w') {
238f857971dSopenharmony_ci            VirtualDeviceBuilder::WaitFor(optarg, "mouse");
239f857971dSopenharmony_ci        } else {
240f857971dSopenharmony_ci            ShowUsage();
241f857971dSopenharmony_ci        }
242f857971dSopenharmony_ci    } while ((opt = getopt(argc, argv, "d:u:s:m:M:f:r:w:D:")) >= 0);
243f857971dSopenharmony_ci}
244f857971dSopenharmony_ci
245f857971dSopenharmony_civoid VirtualMouseBuilder::ReadDownAction()
246f857971dSopenharmony_ci{
247f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
248f857971dSopenharmony_ci    CHKPV(optarg);
249f857971dSopenharmony_ci
250f857971dSopenharmony_ci    if (strcmp(optarg, "L") == 0) {
251f857971dSopenharmony_ci        std::cout << "[mouse] down button: BTN_LEFT" << std::endl;
252f857971dSopenharmony_ci        VirtualMouse::GetDevice()->DownButton(BTN_LEFT);
253f857971dSopenharmony_ci    } else if (strcmp(optarg, "M") == 0) {
254f857971dSopenharmony_ci        std::cout << "[mouse] down button: BTN_MIDDLE" << std::endl;
255f857971dSopenharmony_ci        VirtualMouse::GetDevice()->DownButton(BTN_MIDDLE);
256f857971dSopenharmony_ci    } else if (strcmp(optarg, "R") == 0) {
257f857971dSopenharmony_ci        std::cout << "[mouse] down button: BTN_RIGHT" << std::endl;
258f857971dSopenharmony_ci        VirtualMouse::GetDevice()->DownButton(BTN_RIGHT);
259f857971dSopenharmony_ci    } else {
260f857971dSopenharmony_ci        std::cout << "Invalid argument for option \'-d\'." << std::endl;
261f857971dSopenharmony_ci        ShowUsage();
262f857971dSopenharmony_ci    }
263f857971dSopenharmony_ci}
264f857971dSopenharmony_ci
265f857971dSopenharmony_civoid VirtualMouseBuilder::ReadMoveAction(int32_t argc, char *argv[])
266f857971dSopenharmony_ci{
267f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
268f857971dSopenharmony_ci    CHKPV(optarg);
269f857971dSopenharmony_ci    if (!Utility::IsInteger(std::string(optarg)) || (optind < 0) || (optind >= argc) ||
270f857971dSopenharmony_ci        !Utility::IsInteger(argv[optind])) {
271f857971dSopenharmony_ci        std::cout << "Invalid arguments for Option \'-m\'." << std::endl;
272f857971dSopenharmony_ci        ShowUsage();
273f857971dSopenharmony_ci        return;
274f857971dSopenharmony_ci    }
275f857971dSopenharmony_ci    int32_t dx = std::atoi(optarg);
276f857971dSopenharmony_ci    int32_t dy = dx;
277f857971dSopenharmony_ci
278f857971dSopenharmony_ci    if ((argv[optind] != nullptr) && Utility::IsInteger(std::string(argv[optind]))) {
279f857971dSopenharmony_ci        dy = std::atoi(argv[optind++]);
280f857971dSopenharmony_ci    }
281f857971dSopenharmony_ci    std::cout << "[mouse] move: (" << dx << "," << dy << ")" << std::endl;
282f857971dSopenharmony_ci    VirtualMouse::GetDevice()->MoveProcess(dx, dy);
283f857971dSopenharmony_ci}
284f857971dSopenharmony_ci
285f857971dSopenharmony_civoid VirtualMouseBuilder::ReadMoveToAction(int32_t argc, char *argv[])
286f857971dSopenharmony_ci{
287f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
288f857971dSopenharmony_ci    CHKPV(optarg);
289f857971dSopenharmony_ci
290f857971dSopenharmony_ci    if (!Utility::IsInteger(optarg) || (optind < 0) || (optind >= argc) || !Utility::IsInteger(argv[optind])) {
291f857971dSopenharmony_ci        std::cout << "Invalid arguments for Option \'-M\'." << std::endl;
292f857971dSopenharmony_ci        ShowUsage();
293f857971dSopenharmony_ci        return;
294f857971dSopenharmony_ci    }
295f857971dSopenharmony_ci    int32_t x = std::atoi(optarg);
296f857971dSopenharmony_ci    int32_t y = std::atoi(argv[optind]);
297f857971dSopenharmony_ci    std::cout << "[mouse] move-to (" << x << "," << y << ")" << std::endl;
298f857971dSopenharmony_ci    VirtualMouse::GetDevice()->MoveTo(x, y);
299f857971dSopenharmony_ci    while ((optind < argc) && Utility::IsInteger(argv[optind])) {
300f857971dSopenharmony_ci        optind++;
301f857971dSopenharmony_ci    }
302f857971dSopenharmony_ci}
303f857971dSopenharmony_ci
304f857971dSopenharmony_civoid VirtualMouseBuilder::ReadDragToAction(int32_t argc, char *argv[])
305f857971dSopenharmony_ci{
306f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
307f857971dSopenharmony_ci    CHKPV(optarg);
308f857971dSopenharmony_ci    if (!Utility::IsInteger(optarg) || (optind < 0) || (optind >= argc) || !Utility::IsInteger(argv[optind])) {
309f857971dSopenharmony_ci        std::cout << "Invalid arguments for Option \'-D\'." << std::endl;
310f857971dSopenharmony_ci        ShowUsage();
311f857971dSopenharmony_ci        return;
312f857971dSopenharmony_ci    }
313f857971dSopenharmony_ci    int32_t x = std::atoi(optarg);
314f857971dSopenharmony_ci    int32_t y = std::atoi(argv[optind]);
315f857971dSopenharmony_ci
316f857971dSopenharmony_ci    std::cout << "[mouse] drag-to (" << x << "," << y << ")" << std::endl;
317f857971dSopenharmony_ci    VirtualMouse::GetDevice()->DownButton(BTN_LEFT);
318f857971dSopenharmony_ci    VirtualDeviceBuilder::WaitFor("mouse", SLEEP_TIME);
319f857971dSopenharmony_ci    VirtualMouse::GetDevice()->MoveTo(x, y);
320f857971dSopenharmony_ci    VirtualMouse::GetDevice()->UpButton(BTN_LEFT);
321f857971dSopenharmony_ci    while ((optind < argc) && Utility::IsInteger(argv[optind])) {
322f857971dSopenharmony_ci        optind++;
323f857971dSopenharmony_ci    }
324f857971dSopenharmony_ci}
325f857971dSopenharmony_ci
326f857971dSopenharmony_civoid VirtualMouseBuilder::ReadUpAction()
327f857971dSopenharmony_ci{
328f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
329f857971dSopenharmony_ci    CHKPV(optarg);
330f857971dSopenharmony_ci
331f857971dSopenharmony_ci    if (strcmp(optarg, "L") == 0) {
332f857971dSopenharmony_ci        std::cout << "[mouse] release button: BTN_LEFT" << std::endl;
333f857971dSopenharmony_ci        VirtualMouse::GetDevice()->UpButton(BTN_LEFT);
334f857971dSopenharmony_ci    } else if (strcmp(optarg, "M") == 0) {
335f857971dSopenharmony_ci        std::cout << "[mouse] release button: BTN_MIDDLE" << std::endl;
336f857971dSopenharmony_ci        VirtualMouse::GetDevice()->UpButton(BTN_MIDDLE);
337f857971dSopenharmony_ci    } else if (strcmp(optarg, "R") == 0) {
338f857971dSopenharmony_ci        std::cout << "[mouse] release button: BTN_RIGHT" << std::endl;
339f857971dSopenharmony_ci        VirtualMouse::GetDevice()->UpButton(BTN_RIGHT);
340f857971dSopenharmony_ci    } else {
341f857971dSopenharmony_ci        std::cout << "Invalid argument for option \'-u\'." << std::endl;
342f857971dSopenharmony_ci        ShowUsage();
343f857971dSopenharmony_ci    }
344f857971dSopenharmony_ci}
345f857971dSopenharmony_ci
346f857971dSopenharmony_civoid VirtualMouseBuilder::ReadScrollAction()
347f857971dSopenharmony_ci{
348f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
349f857971dSopenharmony_ci    CHKPV(optarg);
350f857971dSopenharmony_ci    if (!Utility::IsInteger(std::string(optarg))) {
351f857971dSopenharmony_ci        std::cout << "Invalid arguments for Option \'-s\'." << std::endl;
352f857971dSopenharmony_ci        ShowUsage();
353f857971dSopenharmony_ci        return;
354f857971dSopenharmony_ci    }
355f857971dSopenharmony_ci    int32_t dy = std::atoi(optarg);
356f857971dSopenharmony_ci    std::cout << "[mouse] scroll: " << dy << std::endl;
357f857971dSopenharmony_ci    VirtualMouse::GetDevice()->Scroll(dy);
358f857971dSopenharmony_ci}
359f857971dSopenharmony_ci
360f857971dSopenharmony_civoid VirtualMouseBuilder::ReadActions(const char *path)
361f857971dSopenharmony_ci{
362f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
363f857971dSopenharmony_ci    json model;
364f857971dSopenharmony_ci    int32_t result = VirtualDeviceBuilder::ReadFile(path, model);
365f857971dSopenharmony_ci    if (result == RET_ERR) {
366f857971dSopenharmony_ci        FI_HILOGE("Failed to read mouse data from the files");
367f857971dSopenharmony_ci        return;
368f857971dSopenharmony_ci    }
369f857971dSopenharmony_ci    ReadModel(model, MAXIMUM_LEVEL_ALLOWED);
370f857971dSopenharmony_ci}
371f857971dSopenharmony_ci
372f857971dSopenharmony_civoid VirtualMouseBuilder::ReadModel(const nlohmann::json &model, int32_t level)
373f857971dSopenharmony_ci{
374f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
375f857971dSopenharmony_ci    if (model.is_object()) {
376f857971dSopenharmony_ci        auto tIter = model.find("actions");
377f857971dSopenharmony_ci        if (tIter != model.cend() && tIter->is_array()) {
378f857971dSopenharmony_ci            std::for_each(tIter->cbegin(), tIter->cend(), [](const auto &item) { ReadAction(item); });
379f857971dSopenharmony_ci        }
380f857971dSopenharmony_ci    } else if (model.is_array() && level > 0) {
381f857971dSopenharmony_ci        for (const auto &m : model) {
382f857971dSopenharmony_ci            ReadModel(m, level - 1);
383f857971dSopenharmony_ci        }
384f857971dSopenharmony_ci    }
385f857971dSopenharmony_ci}
386f857971dSopenharmony_ci
387f857971dSopenharmony_civoid VirtualMouseBuilder::ReadAction(const nlohmann::json &model)
388f857971dSopenharmony_ci{
389f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
390f857971dSopenharmony_ci    if (!model.is_object()) {
391f857971dSopenharmony_ci        FI_HILOGD("Not an object");
392f857971dSopenharmony_ci        return;
393f857971dSopenharmony_ci    }
394f857971dSopenharmony_ci    auto it = model.find("action");
395f857971dSopenharmony_ci    if (it != model.cend() && it->is_string()) {
396f857971dSopenharmony_ci        static const std::unordered_map<std::string, std::function<void(const nlohmann::json &model)>> actions {
397f857971dSopenharmony_ci            { "down", &HandleDown },
398f857971dSopenharmony_ci            { "move", &HandleMove },
399f857971dSopenharmony_ci            { "up", &HandleUp },
400f857971dSopenharmony_ci            { "scroll", &HandleScroll },
401f857971dSopenharmony_ci            { "wait", &HandleWait }
402f857971dSopenharmony_ci        };
403f857971dSopenharmony_ci        auto actionItr = actions.find(it.value());
404f857971dSopenharmony_ci        if (actionItr != actions.cend()) {
405f857971dSopenharmony_ci            actionItr->second(model);
406f857971dSopenharmony_ci        }
407f857971dSopenharmony_ci    }
408f857971dSopenharmony_ci}
409f857971dSopenharmony_ci
410f857971dSopenharmony_civoid VirtualMouseBuilder::HandleDown(const nlohmann::json &model)
411f857971dSopenharmony_ci{
412f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
413f857971dSopenharmony_ci    auto it = model.find("button");
414f857971dSopenharmony_ci    if (it != model.cend() && it->is_string()) {
415f857971dSopenharmony_ci        auto tIter = mouseBtns.find(it.value());
416f857971dSopenharmony_ci        if (tIter != mouseBtns.cend()) {
417f857971dSopenharmony_ci            std::cout << "[mouse] down button: " << tIter->first << std::endl;
418f857971dSopenharmony_ci            VirtualMouse::GetDevice()->DownButton(tIter->second);
419f857971dSopenharmony_ci        }
420f857971dSopenharmony_ci    }
421f857971dSopenharmony_ci}
422f857971dSopenharmony_ci
423f857971dSopenharmony_civoid VirtualMouseBuilder::HandleMove(const nlohmann::json &model)
424f857971dSopenharmony_ci{
425f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
426f857971dSopenharmony_ci    int32_t dx = 0;
427f857971dSopenharmony_ci    int32_t dy = 0;
428f857971dSopenharmony_ci
429f857971dSopenharmony_ci    auto it = model.find("dx");
430f857971dSopenharmony_ci    if (it != model.cend() && it->is_number_integer()) {
431f857971dSopenharmony_ci        dx = it.value();
432f857971dSopenharmony_ci    }
433f857971dSopenharmony_ci    it = model.find("dy");
434f857971dSopenharmony_ci    if (it != model.cend() && it->is_number_integer()) {
435f857971dSopenharmony_ci        dy = it.value();
436f857971dSopenharmony_ci    }
437f857971dSopenharmony_ci    std::cout << "[mouse] move: (" << dx << "," << dy << ")" << std::endl;
438f857971dSopenharmony_ci    VirtualMouse::GetDevice()->Move(dx, dy);
439f857971dSopenharmony_ci}
440f857971dSopenharmony_ci
441f857971dSopenharmony_civoid VirtualMouseBuilder::HandleUp(const nlohmann::json &model)
442f857971dSopenharmony_ci{
443f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
444f857971dSopenharmony_ci    auto it = model.find("button");
445f857971dSopenharmony_ci    if (it != model.cend() && it->is_string()) {
446f857971dSopenharmony_ci        auto tIter = mouseBtns.find(it.value());
447f857971dSopenharmony_ci        if (tIter != mouseBtns.cend()) {
448f857971dSopenharmony_ci            std::cout << "[mouse] release button: " << tIter->first << std::endl;
449f857971dSopenharmony_ci            VirtualMouse::GetDevice()->UpButton(tIter->second);
450f857971dSopenharmony_ci        }
451f857971dSopenharmony_ci    }
452f857971dSopenharmony_ci}
453f857971dSopenharmony_ci
454f857971dSopenharmony_civoid VirtualMouseBuilder::HandleScroll(const nlohmann::json &model)
455f857971dSopenharmony_ci{
456f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
457f857971dSopenharmony_ci    auto it = model.find("dy");
458f857971dSopenharmony_ci    if (it != model.cend() && it->is_number_integer()) {
459f857971dSopenharmony_ci        int32_t dy = it.value();
460f857971dSopenharmony_ci        std::cout << "[mouse] scroll: " << dy << std::endl;
461f857971dSopenharmony_ci        VirtualMouse::GetDevice()->Scroll(dy);
462f857971dSopenharmony_ci    }
463f857971dSopenharmony_ci}
464f857971dSopenharmony_ci
465f857971dSopenharmony_civoid VirtualMouseBuilder::HandleWait(const nlohmann::json &model)
466f857971dSopenharmony_ci{
467f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
468f857971dSopenharmony_ci    auto it = model.find("duration");
469f857971dSopenharmony_ci    if (it != model.cend() && it->is_number_integer()) {
470f857971dSopenharmony_ci        int32_t waitTime = it.value();
471f857971dSopenharmony_ci        std::cout << "[mouse] wait for " << waitTime << " milliseconds" << std::endl;
472f857971dSopenharmony_ci        VirtualDeviceBuilder::WaitFor("mouse", waitTime);
473f857971dSopenharmony_ci    }
474f857971dSopenharmony_ci}
475f857971dSopenharmony_ci
476f857971dSopenharmony_civoid VirtualMouseBuilder::ReadRawInput(const char *path)
477f857971dSopenharmony_ci{
478f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
479f857971dSopenharmony_ci    json model;
480f857971dSopenharmony_ci    int32_t result = VirtualDeviceBuilder::ReadFile(path, model);
481f857971dSopenharmony_ci    if (result == RET_ERR) {
482f857971dSopenharmony_ci        FI_HILOGE("Failed to read the raw mouse data");
483f857971dSopenharmony_ci        return;
484f857971dSopenharmony_ci    }
485f857971dSopenharmony_ci    ReadRawModel(model, MAXIMUM_LEVEL_ALLOWED);
486f857971dSopenharmony_ci}
487f857971dSopenharmony_ci
488f857971dSopenharmony_civoid VirtualMouseBuilder::ReadRawModel(const nlohmann::json &model, int32_t level)
489f857971dSopenharmony_ci{
490f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
491f857971dSopenharmony_ci    if (model.is_object()) {
492f857971dSopenharmony_ci        auto typeIter = model.find("type");
493f857971dSopenharmony_ci        if (typeIter == model.cend() || !typeIter->is_string() || (std::string(typeIter.value()).compare("raw") != 0)) {
494f857971dSopenharmony_ci            std::cout << "Expect raw input data." << std::endl;
495f857971dSopenharmony_ci            return;
496f857971dSopenharmony_ci        }
497f857971dSopenharmony_ci        auto actionIter = model.find("actions");
498f857971dSopenharmony_ci        if (actionIter != model.cend() && actionIter->is_array()) {
499f857971dSopenharmony_ci            std::for_each(actionIter->cbegin(), actionIter->cend(), [](const auto &item) { ReadRawData(item); });
500f857971dSopenharmony_ci        }
501f857971dSopenharmony_ci    } else if (model.is_array() && level > 0) {
502f857971dSopenharmony_ci        for (const auto &m : model) {
503f857971dSopenharmony_ci            ReadRawModel(m, level - 1);
504f857971dSopenharmony_ci        }
505f857971dSopenharmony_ci    }
506f857971dSopenharmony_ci}
507f857971dSopenharmony_ci
508f857971dSopenharmony_civoid VirtualMouseBuilder::ReadRawData(const nlohmann::json &model)
509f857971dSopenharmony_ci{
510f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
511f857971dSopenharmony_ci    if (!model.is_object()) {
512f857971dSopenharmony_ci        FI_HILOGD("Not an object");
513f857971dSopenharmony_ci        return;
514f857971dSopenharmony_ci    }
515f857971dSopenharmony_ci    auto codeIter = model.find("code");
516f857971dSopenharmony_ci    if (codeIter == model.cend() || !codeIter->is_number_integer()) {
517f857971dSopenharmony_ci        return;
518f857971dSopenharmony_ci    }
519f857971dSopenharmony_ci    auto typeIter = model.find("type");
520f857971dSopenharmony_ci    if (typeIter == model.cend() || !typeIter->is_number_integer()) {
521f857971dSopenharmony_ci        return;
522f857971dSopenharmony_ci    }
523f857971dSopenharmony_ci    auto valueIter = model.find("value");
524f857971dSopenharmony_ci    if (valueIter == model.cend() || !valueIter->is_number_integer()) {
525f857971dSopenharmony_ci        return;
526f857971dSopenharmony_ci    }
527f857971dSopenharmony_ci    std::cout << "[virtual mouse] raw input: [" << typeIter.value() << ", " << codeIter.value() << ", " <<
528f857971dSopenharmony_ci        valueIter.value() << "]" << std::endl;
529f857971dSopenharmony_ci    VirtualMouse::GetDevice()->SendEvent(typeIter.value(), codeIter.value(), valueIter.value());
530f857971dSopenharmony_ci}
531f857971dSopenharmony_ci} // namespace DeviceStatus
532f857971dSopenharmony_ci} // namespace Msdp
533f857971dSopenharmony_ci} // namespace OHOS