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