• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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_touchscreen_builder.h"
17 
18 #include <fstream>
19 #include <iostream>
20 #include <unordered_map>
21 
22 #include <getopt.h>
23 #include <linux/input.h>
24 
25 #include "input_manager.h"
26 
27 #include "devicestatus_define.h"
28 #include "display_manager.h"
29 #include "fi_log.h"
30 #include "utility.h"
31 #include "virtual_touchscreen.h"
32 
33 #undef LOG_TAG
34 #define LOG_TAG "VirtualTouchScreenBuilder"
35 
36 namespace OHOS {
37 namespace Msdp {
38 namespace DeviceStatus {
39 namespace {
40 constexpr int32_t MAXIMUM_LEVEL_ALLOWED { 3 };
41 int32_t g_absMaxWidth { 720 };
42 int32_t g_absMaxHeight { 1280 };
43 constexpr int32_t ABS_PRESSURE_MAX { 100 };
44 constexpr int32_t ABS_MT_ORIENTATION_MIN { -90 };
45 constexpr int32_t ABS_MT_ORIENTATION_MAX { 90 };
46 constexpr int32_t ABS_MT_BLOB_ID_MAX { 10 };
47 constexpr int32_t ABS_MT_TRACKING_ID_MAX { 9 };
48 constexpr int32_t ABS_TOOL_TYPE_MAX { 15 };
49 constexpr int32_t SY_OFFSET { 1 };
50 constexpr int32_t TX_OFFSET { 2 };
51 constexpr int32_t TY_OFFSET { 3 };
52 constexpr uint32_t IO_FLAG_WIDTH { 6 };
53 constexpr int32_t DEFAULT_VALUE_MINUS_ONE { -1 };
54 constexpr int32_t DEFAULT_VALUE_ZERO { 0 };
55 } // namespace
56 
57 class PointerEventMonitor final : public MMI::IInputEventConsumer {
58 public:
59     PointerEventMonitor() = default;
60     ~PointerEventMonitor() = default;
61 
OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const62     void OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const override {};
63     void OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const override;
OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const64     void OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const override {};
65 };
66 
OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const67 void PointerEventMonitor::OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const
68 {
69     CHKPV(pointerEvent);
70     if (pointerEvent->GetSourceType() != MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN) {
71         return;
72     }
73     MMI::PointerEvent::PointerItem pointerItem;
74     if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
75         return;
76     }
77     std::cout << "\rcurrent touch position - x: " << std::setw(IO_FLAG_WIDTH) << std::left
78         << pointerItem.GetDisplayX() << "y: " << pointerItem.GetDisplayY() << "            ";
79     std::cout.flush();
80 }
81 
VirtualTouchScreenBuilder()82 VirtualTouchScreenBuilder::VirtualTouchScreenBuilder() : VirtualDeviceBuilder(GetDeviceName(), BUS_USB, 0x6006, 0x6006)
83 {
84 #ifndef OHOS_BUILD_PC_PRODUCT
85     sptr<Rosen::Display> display = Rosen::DisplayManager::GetInstance().GetDisplayById(0);
86 #else
87     sptr<Rosen::DisplayInfo> display = Rosen::DisplayManager::GetInstance().GetVisibleAreaDisplayInfoById(0);
88 #endif // OHOS_BUILD_PC_PRODUCT
89     CHKPV(display);
90     g_absMaxWidth = display->GetWidth();
91     g_absMaxHeight = display->GetHeight();
92     AbsInfo absInfos[] { { ABS_X, 0, g_absMaxWidth, 0, 0 },
93     { ABS_Y, 0, g_absMaxHeight, 0, 0 },
94     { ABS_PRESSURE, 0, ABS_PRESSURE_MAX, 0, 0 },
95     { ABS_MT_TOUCH_MAJOR, 0, 1, 0, 0 },
96     { ABS_MT_TOUCH_MINOR, 0, 1, 0, 0 },
97     { ABS_MT_ORIENTATION, ABS_MT_ORIENTATION_MIN, ABS_MT_ORIENTATION_MAX, 0, 0 },
98     { ABS_MT_POSITION_X, 0, g_absMaxWidth, 0, 0 },
99     { ABS_MT_POSITION_Y, 0, g_absMaxHeight, 0, 0 },
100     { ABS_MT_BLOB_ID, 0, ABS_MT_BLOB_ID_MAX, 0, 0 },
101     { ABS_MT_TRACKING_ID, 0, ABS_MT_TRACKING_ID_MAX, 0, 0 },
102     { ABS_MT_PRESSURE, 0, ABS_PRESSURE_MAX, 0, 0 },
103     { ABS_MT_TOOL_TYPE, 0, ABS_TOOL_TYPE_MAX, 0, 0 },
104     { ABS_MT_WIDTH_MAJOR, 0, 1, 0, 0 },
105     { ABS_MT_WIDTH_MINOR, 0, 1, 0, 0 },
106     { ABS_MT_TOOL_X, 0, g_absMaxWidth, 0, 0 },
107     { ABS_MT_TOOL_Y, 0, 1, 0, 0 } };
108 
109     eventTypes_ = { EV_ABS, EV_KEY };
110     properties_ = { INPUT_PROP_DIRECT };
111     keys_ = { BTN_TOUCH, BTN_TOOL_RUBBER, BTN_TOOL_BRUSH, BTN_TOOL_PENCIL, BTN_TOOL_AIRBRUSH,
112             BTN_TOOL_FINGER, BTN_TOOL_MOUSE, BTN_TOOL_LENS };
113     abs_ = { ABS_X, ABS_Y, ABS_PRESSURE, ABS_MT_TOUCH_MAJOR, ABS_MT_TOUCH_MINOR, ABS_MT_ORIENTATION,
114             ABS_MT_POSITION_X, ABS_MT_POSITION_Y, ABS_MT_BLOB_ID, ABS_MT_TRACKING_ID, ABS_MT_PRESSURE,
115             ABS_MT_WIDTH_MAJOR, ABS_MT_WIDTH_MINOR, ABS_MT_TOOL_X, ABS_MT_TOOL_Y, ABS_MT_TOOL_TYPE };
116     for (const auto &item : absInfos) {
117         SetAbsValue(item);
118     }
119 }
120 
GetDeviceName()121 std::string VirtualTouchScreenBuilder::GetDeviceName()
122 {
123     return std::string("Virtual TouchScreen");
124 }
125 
ShowUsage()126 void VirtualTouchScreenBuilder::ShowUsage()
127 {
128     std::cout << "Usage: vdevadm act -t T [-d<SLOT>  <x> <y>] [-u<SLOT>] [-m<SLOT> <dx> [<dy>]]" << std::endl;
129     std::cout << "                        [-M<SLOT> <x> <y>] [-w <ms>] [-f <FILE>] [-r <FILE>] [-c]" << std::endl;
130     std::cout << "      -d <SLOT> <x> <y>" << std::endl;
131     std::cout << "                  Press donw on touch screen." << std::endl;
132     std::cout << "                  The <SLOT> identify one touch and is in the range [0-9]." << std::endl;
133     std::cout << "      -u <SLOT>   Lift up the touch <SLOT>." << std::endl;
134     std::cout << "      -m <SLOT> <dx> [<dy>]" << std::endl;
135     std::cout << "                  Move the touch <SLOT> along (dx, dy) for one step." << std::endl;
136     std::cout << "      -M <SLOT> <x> <y>" << std::endl;
137     std::cout << "                  Move the touch <SLOT> to (x, y)." << std::endl;
138     std::cout << "      -D <SLOT> <sx> <sy> <tx> <ty> Drag the touch <SLOT> to (tx, ty)" << std::endl;
139     std::cout << "      -w <ms>     Wait for <ms> milliseconds." << std::endl;
140     std::cout << "      -f <FILE>   Read actions from <FILE>." << std::endl;
141     std::cout << "      -r <FILE>   Read raw input data from <FILE>." << std::endl;
142 }
143 
Mount()144 void VirtualTouchScreenBuilder::Mount()
145 {
146     CALL_DEBUG_ENTER;
147     std::cout << "Start to mount virtual touchscreen." << std::endl;
148     if (VirtualTouchScreen::GetDevice() != nullptr) {
149         std::cout << "Virtual touchscreen has been mounted." << std::endl;
150         return;
151     }
152     VirtualTouchScreenBuilder vTouch;
153     if (!vTouch.SetUp()) {
154         std::cout << "Failed to mount virtual touchscreen." << std::endl;
155         return;
156     }
157 
158     int32_t nTries = 3;
159     do {
160         std::this_thread::sleep_for(std::chrono::seconds(1));
161     } while ((nTries-- > 0) && (VirtualTouchScreen::GetDevice() == nullptr));
162     if (VirtualTouchScreen::GetDevice() == nullptr) {
163         std::cout << "Failed to mount virtual touchscreen." << std::endl;
164         return;
165     }
166 
167     std::cout << "Mount virtual touchscreen successfully." << std::endl;
168     VirtualDeviceBuilder::Daemonize();
169     for (;;) {
170         std::this_thread::sleep_for(std::chrono::minutes(1));
171     }
172 }
173 
Unmount()174 void VirtualTouchScreenBuilder::Unmount()
175 {
176     CALL_DEBUG_ENTER;
177     VirtualDeviceBuilder::Unmount("touchscreen", "T");
178 }
179 
Clone()180 void VirtualTouchScreenBuilder::Clone()
181 {
182     CALL_DEBUG_ENTER;
183     if (VirtualTouchScreen::GetDevice() != nullptr) {
184         std::cout << "Virtual touchscreen has been mounted" << std::endl;
185         return;
186     }
187 
188     std::vector<std::shared_ptr<VirtualDevice>> vDevs;
189     int32_t ret = VirtualDeviceBuilder::ScanFor(
190         [](std::shared_ptr<VirtualDevice> vDev) { return ((vDev != nullptr) && vDev->IsTouchscreen()); }, vDevs);
191     if (ret != RET_OK) {
192         std::cout << "Failed while scanning for touchscreen" << std::endl;
193         return;
194     }
195     auto vDev = VirtualDeviceBuilder::Select(vDevs, "touchscreen");
196     CHKPV(vDev);
197 
198     std::cout << "Cloning \'" << vDev->GetName() << "\'." << std::endl;
199     VirtualDeviceBuilder vBuilder(GetDeviceName(), vDev);
200     if (!vBuilder.SetUp()) {
201         std::cout << "Failed to clone \' " << vDev->GetName() << " \'." << std::endl;
202         return;
203     }
204 
205     int32_t nTries = 3;
206     do {
207         std::this_thread::sleep_for(std::chrono::seconds(1));
208     } while ((nTries-- > 0) && (VirtualTouchScreen::GetDevice() == nullptr));
209     if (VirtualTouchScreen::GetDevice() == nullptr) {
210         std::cout << "Clone \' " << vDev->GetName() << " \' is unsuccessful." << std::endl;
211         return;
212     }
213 
214     std::cout << "Clone \'" << vDev->GetName() << "\' successfully" << std::endl;
215     VirtualDeviceBuilder::Daemonize();
216     for (;;) {
217         std::this_thread::sleep_for(std::chrono::minutes(1));
218     }
219 }
220 
Monitor()221 void VirtualTouchScreenBuilder::Monitor()
222 {
223     CALL_DEBUG_ENTER;
224     MMI::InputManager* inputMgr = MMI::InputManager::GetInstance();
225     CHKPV(inputMgr);
226     auto monitor = std::make_shared<PointerEventMonitor>();
227     int32_t monitorId = inputMgr->AddMonitor(monitor);
228     if (monitorId < 0) {
229         std::cout << "Failed to add monitor." << std::endl;
230         return;
231     }
232     for (;;) {
233         std::this_thread::sleep_for(std::chrono::minutes(1));
234     }
235 }
236 
Act(int32_t argc,char * argv[])237 void VirtualTouchScreenBuilder::Act(int32_t argc, char *argv[])
238 {
239     CALL_DEBUG_ENTER;
240     int32_t opt = getopt(argc, argv, "d:u:m:M:f:r:w:D:");
241     if (opt < 0) {
242         std::cout << "Vdevadm act: required option is missing" << std::endl;
243         ShowUsage();
244         return;
245     }
246     if (VirtualTouchScreen::GetDevice() == nullptr) {
247         std::cout << "No virtual touchscreen." << std::endl;
248         return;
249     }
250     do {
251         {
252             auto action = ruleTscrnActions_.find(opt);
253             if (action != ruleTscrnActions_.end()) {
254                 action->second();
255                 continue;
256             }
257         }
258         {
259             auto action = readTscrnActions_.find(opt);
260             if (action != readTscrnActions_.end()) {
261                 action->second(optarg);
262                 continue;
263             }
264         }
265         {
266             auto action = moveTscrnActions_.find(opt);
267             if (action != moveTscrnActions_.end()) {
268                 action->second(argc, argv);
269                 continue;
270             }
271         }
272         if (opt == 'w') {
273             VirtualDeviceBuilder::WaitFor(optarg, "touchscreen");
274         } else {
275             ShowUsage();
276         }
277     } while ((opt = getopt(argc, argv, "d:u:m:M:f:r:w:D:")) >= 0);
278 }
279 
ReadDownAction(int32_t argc,char * argv[])280 void VirtualTouchScreenBuilder::ReadDownAction(int32_t argc, char *argv[])
281 {
282     CALL_DEBUG_ENTER;
283     CHKPV(optarg);
284 
285     if (!Utility::IsInteger(optarg) || (optind < 0) || (optind + 1 >= argc) ||
286         !Utility::IsInteger(argv[optind]) || !Utility::IsInteger(argv[optind + 1])) {
287         std::cout << "Require arguments for Option \'-d\'." << std::endl;
288         ShowUsage();
289         return;
290     }
291     int32_t slot = std::atoi(optarg);
292     int32_t x = std::atoi(argv[optind]);
293     int32_t y = std::atoi(argv[optind + 1]);
294     std::cout << "[touchscreen] down: [" << slot << ", (" << x << "," << y << ")]" << std::endl;
295     VirtualTouchScreen::GetDevice()->DownButton(slot, x, y);
296     while ((optind < argc) && Utility::IsInteger(argv[optind])) {
297         optind++;
298     }
299 }
300 
ReadMoveAction(int32_t argc,char * argv[])301 void VirtualTouchScreenBuilder::ReadMoveAction(int32_t argc, char *argv[])
302 {
303     CALL_DEBUG_ENTER;
304     CHKPV(optarg);
305 
306     if (!Utility::IsInteger(optarg) || (optind < 0) || (optind + 1 >= argc) || !Utility::IsInteger(argv[optind])) {
307         std::cout << "Invalid arguments for Option \'-m\'." << std::endl;
308         ShowUsage();
309         return;
310     }
311     int32_t slot = std::atoi(optarg);
312     int32_t dx = std::atoi(argv[optind]);
313     int32_t dy = 0;
314     if ((optind + 1 < argc) && Utility::IsInteger(argv[optind + 1])) {
315         dy = std::atoi(argv[optind + 1]);
316     }
317     std::cout << "[touchscreen] move: [" << slot << ", (" << dx << "," << dy << ")]" << std::endl;
318     VirtualTouchScreen::GetDevice()->Move(slot, dx, dy);
319     while ((optind < argc) && Utility::IsInteger(argv[optind])) {
320         optind++;
321     }
322 }
323 
ReadUpAction()324 void VirtualTouchScreenBuilder::ReadUpAction()
325 {
326     CALL_DEBUG_ENTER;
327     CHKPV(optarg);
328     if (!Utility::IsInteger(optarg)) {
329         std::cout << "Invalid arguments for Option \'-u\'." << std::endl;
330         ShowUsage();
331         return;
332     }
333     int32_t slot = std::atoi(optarg);
334     std::cout << "[touchscreen] release: [" << slot << "]" << std::endl;
335     VirtualTouchScreen::GetDevice()->UpButton(slot);
336 }
337 
ReadMoveToAction(int32_t argc,char * argv[])338 void VirtualTouchScreenBuilder::ReadMoveToAction(int32_t argc, char *argv[])
339 {
340     CALL_DEBUG_ENTER;
341     CHKPV(optarg);
342 
343     if (!Utility::IsInteger(optarg) || (optind < 0) || (optind + 1 >= argc) || !Utility::IsInteger(argv[optind]) ||
344         !Utility::IsInteger(argv[optind + 1])) {
345         std::cout << "Invalid arguments for Option \'-M\'." << std::endl;
346         ShowUsage();
347         return;
348     }
349     int32_t slot = std::atoi(optarg);
350     int32_t x = std::atoi(argv[optind]);
351     int32_t y = std::atoi(argv[optind + 1]);
352     std::cout << "[touchscreen] move-to: [" << slot << ", (" << x << "," << y << ")]" << std::endl;
353     VirtualTouchScreen::GetDevice()->MoveTo(slot, x, y);
354     while ((optind < argc) && Utility::IsInteger(argv[optind])) {
355         optind++;
356     }
357 }
358 
ReadDragToAction(int32_t argc,char * argv[])359 void VirtualTouchScreenBuilder::ReadDragToAction(int32_t argc, char *argv[])
360 {
361     CALL_DEBUG_ENTER;
362     CHKPV(optarg);
363     if (!Utility::IsInteger(optarg) || (optind < 0) || (optind + TY_OFFSET >= argc) ||
364         !Utility::IsInteger(argv[optind]) || !Utility::IsInteger(argv[optind + SY_OFFSET]) ||
365         !Utility::IsInteger(argv[optind + TX_OFFSET]) || !Utility::IsInteger(argv[optind + TY_OFFSET])) {
366         std::cout << "Invalid arguments for Option \'-D\'." << std::endl;
367         ShowUsage();
368         return;
369     }
370 
371     int32_t slot = std::atoi(optarg);
372     int32_t sx = std::atoi(argv[optind]);
373     int32_t sy = std::atoi(argv[optind + SY_OFFSET]);
374     int32_t tx = std::atoi(argv[optind + TX_OFFSET]);
375     int32_t ty = std::atoi(argv[optind + TY_OFFSET]);
376 
377     std::cout << "[touchscreen] drag-to: [" << slot << ", (" << tx << "," << ty << ")]" << std::endl;
378     auto vTouch = VirtualTouchScreen::GetDevice();
379     vTouch->DownButton(slot, sx, sy);
380     VirtualDeviceBuilder::WaitFor("touchscreen", SLEEP_TIME);
381     vTouch->MoveTo(slot, tx, ty);
382     vTouch->UpButton(slot);
383     while ((optind < argc) && Utility::IsInteger(argv[optind])) {
384         optind++;
385     }
386 }
387 
ReadActions(const char * path)388 void VirtualTouchScreenBuilder::ReadActions(const char *path)
389 {
390     CALL_DEBUG_ENTER;
391     json model;
392     int32_t ret = VirtualDeviceBuilder::ReadFile(path, model);
393     if (ret == RET_ERR) {
394         FI_HILOGE("Failed to read touchscreen data from the files");
395         return;
396     }
397     ReadModel(model, MAXIMUM_LEVEL_ALLOWED);
398 }
399 
ReadModel(const nlohmann::json & model,int32_t level)400 void VirtualTouchScreenBuilder::ReadModel(const nlohmann::json &model, int32_t level)
401 {
402     CALL_DEBUG_ENTER;
403     if (model.is_object()) {
404         auto it = model.find("actions");
405         if (it != model.cend() && it->is_array()) {
406             std::for_each(it->cbegin(), it->cend(), [](const auto &item) { ReadAction(item); });
407         }
408     } else if (model.is_array() && level > 0) {
409         for (const auto &m : model) {
410             ReadModel(m, level - 1);
411         }
412     }
413 }
414 
ReadAction(const nlohmann::json & model)415 void VirtualTouchScreenBuilder::ReadAction(const nlohmann::json &model)
416 {
417     CALL_DEBUG_ENTER;
418     if (!model.is_object()) {
419         FI_HILOGD("Not an object");
420         return;
421     }
422     auto it = model.find("action");
423     if (it != model.cend()) {
424         static const std::unordered_map<std::string, std::function<void(const nlohmann::json &model)>> actions {
425             { "down", &HandleDown },
426             { "move", &HandleMove },
427             { "up", &HandleUp },
428             { "move-to", &HandleMoveTo },
429             { "wait", &HandleWait }
430         };
431         auto actionItr = actions.find(it.value());
432         if (actionItr != actions.cend()) {
433             actionItr->second(model);
434         }
435     }
436 }
437 
GetModelValue(const nlohmann::json & model,const std::string & targetName,int32_t defaultValue)438 int32_t VirtualTouchScreenBuilder::GetModelValue(const nlohmann::json &model, const std::string &targetName,
439     int32_t defaultValue)
440 {
441     auto it = model.find(targetName);
442     if (it != model.cend() && it->is_number_integer()) {
443         return it.value();
444     }
445     return defaultValue;
446 }
447 
HandleDown(const nlohmann::json & model)448 void VirtualTouchScreenBuilder::HandleDown(const nlohmann::json &model)
449 {
450     int32_t slot = VirtualTouchScreenBuilder::GetModelValue(model, "slot", DEFAULT_VALUE_MINUS_ONE);
451 
452     int32_t x = VirtualTouchScreenBuilder::GetModelValue(model, "x", DEFAULT_VALUE_MINUS_ONE);
453 
454     int32_t y = VirtualTouchScreenBuilder::GetModelValue(model, "y", DEFAULT_VALUE_MINUS_ONE);
455 
456     std::cout << "[touchscreen] down: [" << slot << ", (" << x << "," << y << ")]" << std::endl;
457     VirtualTouchScreen::GetDevice()->DownButton(slot, x, y);
458 }
459 
HandleMove(const nlohmann::json & model)460 void VirtualTouchScreenBuilder::HandleMove(const nlohmann::json &model)
461 {
462     int32_t slot = VirtualTouchScreenBuilder::GetModelValue(model, "slot", DEFAULT_VALUE_MINUS_ONE);
463 
464     int32_t dx = VirtualTouchScreenBuilder::GetModelValue(model, "dx", DEFAULT_VALUE_ZERO);
465 
466     int32_t dy = VirtualTouchScreenBuilder::GetModelValue(model, "dy", DEFAULT_VALUE_ZERO);
467 
468     std::cout << "[touchscreen] move: [" << slot << ", (" << dx << "," << dy << ")]" << std::endl;
469     VirtualTouchScreen::GetDevice()->Move(slot, dx, dy);
470 }
471 
HandleUp(const nlohmann::json & model)472 void VirtualTouchScreenBuilder::HandleUp(const nlohmann::json &model)
473 {
474     int32_t slot = VirtualTouchScreenBuilder::GetModelValue(model, "slot", DEFAULT_VALUE_MINUS_ONE);
475 
476     std::cout << "[touchscreen] release: [" << slot << "]" << std::endl;
477     VirtualTouchScreen::GetDevice()->UpButton(slot);
478 }
479 
HandleMoveTo(const nlohmann::json & model)480 void VirtualTouchScreenBuilder::HandleMoveTo(const nlohmann::json &model)
481 {
482     int32_t slot = VirtualTouchScreenBuilder::GetModelValue(model, "slot", DEFAULT_VALUE_MINUS_ONE);
483 
484     int32_t x = VirtualTouchScreenBuilder::GetModelValue(model, "x", DEFAULT_VALUE_MINUS_ONE);
485 
486     int32_t y = VirtualTouchScreenBuilder::GetModelValue(model, "y", DEFAULT_VALUE_MINUS_ONE);
487 
488     std::cout << "[touchscreen] move-to: [" << slot << ", (" << x << "," << y << ")]" << std::endl;
489     VirtualTouchScreen::GetDevice()->MoveTo(slot, x, y);
490 }
491 
HandleWait(const nlohmann::json & model)492 void VirtualTouchScreenBuilder::HandleWait(const nlohmann::json &model)
493 {
494     CALL_DEBUG_ENTER;
495     auto it = model.find("duration");
496     if (it != model.cend() && it->is_number_integer()) {
497         int32_t waitTime = it.value();
498         VirtualDeviceBuilder::WaitFor("touchscreen", waitTime);
499     }
500 }
501 
ReadRawInput(const char * path)502 void VirtualTouchScreenBuilder::ReadRawInput(const char *path)
503 {
504     CALL_DEBUG_ENTER;
505     json model;
506     int32_t ret = VirtualDeviceBuilder::ReadFile(path, model);
507     if (ret == RET_ERR) {
508         FI_HILOGE("Failed to read the raw touchscreen data");
509         return;
510     }
511     ReadRawModel(model, MAXIMUM_LEVEL_ALLOWED);
512 }
513 
ReadRawModel(const nlohmann::json & model,int32_t level)514 void VirtualTouchScreenBuilder::ReadRawModel(const nlohmann::json &model, int32_t level)
515 {
516     CALL_DEBUG_ENTER;
517     if (model.is_object()) {
518         auto it = model.find("type");
519         if (it == model.cend() || !it->is_string() || (std::string(it.value()).compare("raw") != 0)) {
520             std::cout << "Expect raw input data." << std::endl;
521             return;
522         }
523         it = model.find("actions");
524         if (it != model.cend() && it->is_array()) {
525             std::for_each(it->cbegin(), it->cend(), [](const auto &item) { ReadRawData(item); });
526         }
527     } else if (model.is_array() && level > 0) {
528         for (const auto &m : model) {
529             ReadRawModel(m, level - 1);
530         }
531     }
532 }
533 
ReadRawData(const nlohmann::json & model)534 void VirtualTouchScreenBuilder::ReadRawData(const nlohmann::json &model)
535 {
536     CALL_DEBUG_ENTER;
537     if (!model.is_object()) {
538         FI_HILOGD("Not an object");
539         return;
540     }
541     auto typeIter = model.find("type");
542     if (typeIter == model.cend() || !typeIter->is_number_integer()) {
543         return;
544     }
545     auto codeIter = model.find("code");
546     if (codeIter == model.cend() || !codeIter->is_number_integer()) {
547         return;
548     }
549     auto valueIter = model.find("value");
550     if (valueIter == model.cend() || !valueIter->is_number_integer()) {
551         return;
552     }
553     std::cout << "[touchscreen] raw input: [" << typeIter.value() << ", " << codeIter.value() << ", " <<
554         valueIter.value() << "]" << std::endl;
555     VirtualTouchScreen::GetDevice()->SendEvent(typeIter.value(), codeIter.value(), valueIter.value());
556 }
557 } // namespace DeviceStatus
558 } // namespace Msdp
559 } // namespace OHOS