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