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