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