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 36namespace OHOS { 37namespace Msdp { 38namespace DeviceStatus { 39namespace { 40constexpr int32_t MAXIMUM_LEVEL_ALLOWED { 3 }; 41int32_t g_absMaxWidth { 720 }; 42int32_t g_absMaxHeight { 1280 }; 43constexpr int32_t ABS_PRESSURE_MAX { 100 }; 44constexpr int32_t ABS_MT_ORIENTATION_MIN { -90 }; 45constexpr int32_t ABS_MT_ORIENTATION_MAX { 90 }; 46constexpr int32_t ABS_MT_BLOB_ID_MAX { 10 }; 47constexpr int32_t ABS_MT_TRACKING_ID_MAX { 9 }; 48constexpr int32_t ABS_TOOL_TYPE_MAX { 15 }; 49constexpr int32_t SY_OFFSET { 1 }; 50constexpr int32_t TX_OFFSET { 2 }; 51constexpr int32_t TY_OFFSET { 3 }; 52constexpr uint32_t IO_FLAG_WIDTH { 6 }; 53constexpr int32_t DEFAULT_VALUE_MINUS_ONE { -1 }; 54constexpr int32_t DEFAULT_VALUE_ZERO { 0 }; 55} // namespace 56 57class PointerEventMonitor final : public MMI::IInputEventConsumer { 58public: 59 PointerEventMonitor() = default; 60 ~PointerEventMonitor() = default; 61 62 void OnInputEvent(std::shared_ptr<MMI::KeyEvent> keyEvent) const override {}; 63 void OnInputEvent(std::shared_ptr<MMI::PointerEvent> pointerEvent) const override; 64 void OnInputEvent(std::shared_ptr<MMI::AxisEvent> axisEvent) const override {}; 65}; 66 67void 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 82VirtualTouchScreenBuilder::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 117std::string VirtualTouchScreenBuilder::GetDeviceName() 118{ 119 return std::string("Virtual TouchScreen"); 120} 121 122void 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 140void 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 170void VirtualTouchScreenBuilder::Unmount() 171{ 172 CALL_DEBUG_ENTER; 173 VirtualDeviceBuilder::Unmount("touchscreen", "T"); 174} 175 176void 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 217void 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 233void 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 276void 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 297void 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 320void 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 334void 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 355void 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 384void 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 396void 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 411void 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 434int32_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 444void 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 456void 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 468void 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 476void 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 488void 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 498void 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 510void 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 530void 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