1f857971dSopenharmony_ci/*
2f857971dSopenharmony_ci * Copyright (c) 2023 Huawei Device Co., Ltd.
3f857971dSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4f857971dSopenharmony_ci * you may not use this file except in compliance with the License.
5f857971dSopenharmony_ci * You may obtain a copy of the License at
6f857971dSopenharmony_ci *
7f857971dSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8f857971dSopenharmony_ci *
9f857971dSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10f857971dSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11f857971dSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12f857971dSopenharmony_ci * See the License for the specific language governing permissions and
13f857971dSopenharmony_ci * limitations under the License.
14f857971dSopenharmony_ci */
15f857971dSopenharmony_ci
16f857971dSopenharmony_ci#include "virtual_keyboard_builder.h"
17f857971dSopenharmony_ci
18f857971dSopenharmony_ci#include <getopt.h>
19f857971dSopenharmony_ci#include <fstream>
20f857971dSopenharmony_ci#include <iostream>
21f857971dSopenharmony_ci
22f857971dSopenharmony_ci#include "devicestatus_define.h"
23f857971dSopenharmony_ci#include "fi_log.h"
24f857971dSopenharmony_ci#include "utility.h"
25f857971dSopenharmony_ci#include "virtual_keyboard.h"
26f857971dSopenharmony_ci
27f857971dSopenharmony_ci#undef LOG_TAG
28f857971dSopenharmony_ci#define LOG_TAG "VirtualKeyboardBuilder"
29f857971dSopenharmony_ci
30f857971dSopenharmony_cinamespace OHOS {
31f857971dSopenharmony_cinamespace Msdp {
32f857971dSopenharmony_cinamespace DeviceStatus {
33f857971dSopenharmony_cinamespace {
34f857971dSopenharmony_ciconstexpr int32_t MAXIMUM_LEVEL_ALLOWED { 3 };
35f857971dSopenharmony_ciconstexpr ssize_t MAXIMUM_FILESIZE_ALLOWED { 0x100000 };
36f857971dSopenharmony_ci} // namespace
37f857971dSopenharmony_ci
38f857971dSopenharmony_ciVirtualKeyboardBuilder::VirtualKeyboardBuilder() : VirtualDeviceBuilder(GetDeviceName(), BUS_USB, 0x24ae, 0x4035)
39f857971dSopenharmony_ci{
40f857971dSopenharmony_ci    eventTypes_ = { EV_KEY, EV_MSC, EV_LED, EV_REP };
41f857971dSopenharmony_ci    miscellaneous_ = { MSC_SCAN };
42f857971dSopenharmony_ci    leds_ = { LED_NUML, LED_CAPSL, LED_SCROLLL, LED_COMPOSE, LED_KANA };
43f857971dSopenharmony_ci    repeats_ = { REP_DELAY, REP_PERIOD };
44f857971dSopenharmony_ci    keys_ = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
45f857971dSopenharmony_ci        21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
46f857971dSopenharmony_ci        41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
47f857971dSopenharmony_ci        61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
48f857971dSopenharmony_ci        81, 82, 83, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 102,
49f857971dSopenharmony_ci        103, 104, 105, 106, 107, 108, 109, 110, 111, 113, 114, 115, 116, 117, 119, 121, 122, 123, 124, 125,
50f857971dSopenharmony_ci        126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 140, 142, 150, 152, 158, 159, 161,
51f857971dSopenharmony_ci        163, 164, 165, 166, 173, 176, 177, 178, 179, 180, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192,
52f857971dSopenharmony_ci        193, 194, 240, 211, 213, 214, 215, 218, 220, 221, 222, 223, 226, 227, 231, 232, 233, 236, 237, 238,
53f857971dSopenharmony_ci        239, 242, 243, 245, 246, 247, 248, 464, 522, 523, 141, 145, 146, 147, 148, 149, 151, 153, 154, 157,
54f857971dSopenharmony_ci        160, 162, 170, 175, 182, 200, 201, 202, 203, 204, 205, 101, 112, 118, 120 };
55f857971dSopenharmony_ci}
56f857971dSopenharmony_ci
57f857971dSopenharmony_cistd::string VirtualKeyboardBuilder::GetDeviceName()
58f857971dSopenharmony_ci{
59f857971dSopenharmony_ci    return std::string("Virtual Keyboard");
60f857971dSopenharmony_ci}
61f857971dSopenharmony_ci
62f857971dSopenharmony_civoid VirtualKeyboardBuilder::ShowUsage()
63f857971dSopenharmony_ci{
64f857971dSopenharmony_ci    std::cout << "Usage: vdevadm act -t K [-d <key>] [-u <key>] [-w <ms>] [-f <FILE>] [-r <FILE>]" << std::endl;
65f857971dSopenharmony_ci    std::cout << "      -d <key>    Down <key>" << std::endl;
66f857971dSopenharmony_ci    std::cout << "      -u <key>    Release <key>" << std::endl;
67f857971dSopenharmony_ci    std::cout << "      -w <ms>     Wait for <ms> milliseconds." << std::endl;
68f857971dSopenharmony_ci    std::cout << "      -f <FILE>   Read actions from <FILE>" << std::endl;
69f857971dSopenharmony_ci    std::cout << "      -r <FILE>   Read raw input data from <FILE>." << std::endl;
70f857971dSopenharmony_ci    std::cout << std::endl;
71f857971dSopenharmony_ci}
72f857971dSopenharmony_ci
73f857971dSopenharmony_civoid VirtualKeyboardBuilder::Mount()
74f857971dSopenharmony_ci{
75f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
76f857971dSopenharmony_ci    std::cout << "Start to mount virtual keyboard." << std::endl;
77f857971dSopenharmony_ci    if (VirtualKeyboard::GetDevice() != nullptr) {
78f857971dSopenharmony_ci        std::cout << "Virtual keyboard has been mounted." << std::endl;
79f857971dSopenharmony_ci        return;
80f857971dSopenharmony_ci    }
81f857971dSopenharmony_ci    VirtualKeyboardBuilder vKeyboard;
82f857971dSopenharmony_ci    if (!vKeyboard.SetUp()) {
83f857971dSopenharmony_ci        std::cout << "Failed to mount virtual keyboard." << std::endl;
84f857971dSopenharmony_ci        return;
85f857971dSopenharmony_ci    }
86f857971dSopenharmony_ci
87f857971dSopenharmony_ci    int32_t nTries = 6;
88f857971dSopenharmony_ci    do {
89f857971dSopenharmony_ci        std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME));
90f857971dSopenharmony_ci    } while ((nTries-- > 0) && (VirtualKeyboard::GetDevice() == nullptr));
91f857971dSopenharmony_ci    if (VirtualKeyboard::GetDevice() == nullptr) {
92f857971dSopenharmony_ci        std::cout << "Failed to mount virtual keyboard." << std::endl;
93f857971dSopenharmony_ci        return;
94f857971dSopenharmony_ci    }
95f857971dSopenharmony_ci
96f857971dSopenharmony_ci    std::cout << "Mount virtual keyboard successfully." << std::endl;
97f857971dSopenharmony_ci    VirtualDeviceBuilder::Daemonize();
98f857971dSopenharmony_ci
99f857971dSopenharmony_ci    for (;;) {
100f857971dSopenharmony_ci        std::this_thread::sleep_for(std::chrono::minutes(1));
101f857971dSopenharmony_ci    }
102f857971dSopenharmony_ci}
103f857971dSopenharmony_ci
104f857971dSopenharmony_civoid VirtualKeyboardBuilder::Unmount()
105f857971dSopenharmony_ci{
106f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
107f857971dSopenharmony_ci    VirtualDeviceBuilder::Unmount("keyboard", "K");
108f857971dSopenharmony_ci}
109f857971dSopenharmony_ci
110f857971dSopenharmony_civoid VirtualKeyboardBuilder::Clone()
111f857971dSopenharmony_ci{
112f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
113f857971dSopenharmony_ci    if (VirtualKeyboard::GetDevice() != nullptr) {
114f857971dSopenharmony_ci        std::cout << "Virtual keyboard has been mounted" << std::endl;
115f857971dSopenharmony_ci        return;
116f857971dSopenharmony_ci    }
117f857971dSopenharmony_ci
118f857971dSopenharmony_ci    std::vector<std::shared_ptr<VirtualDevice>> vDevs;
119f857971dSopenharmony_ci    int32_t ret = VirtualDeviceBuilder::ScanFor(
120f857971dSopenharmony_ci        [](std::shared_ptr<VirtualDevice> vDev) { return ((vDev != nullptr) && vDev->IsKeyboard()); }, vDevs);
121f857971dSopenharmony_ci    if (ret != RET_OK) {
122f857971dSopenharmony_ci        std::cout << "Failed while scanning for keyboard" << std::endl;
123f857971dSopenharmony_ci        return;
124f857971dSopenharmony_ci    }
125f857971dSopenharmony_ci    auto vDev = VirtualDeviceBuilder::Select(vDevs, "keyboard");
126f857971dSopenharmony_ci    CHKPV(vDev);
127f857971dSopenharmony_ci    std::cout << "Cloning \'" << vDev->GetName() << "\'." << std::endl;
128f857971dSopenharmony_ci    VirtualDeviceBuilder vBuilder(GetDeviceName(), vDev);
129f857971dSopenharmony_ci    if (!vBuilder.SetUp()) {
130f857971dSopenharmony_ci        std::cout << "Failed to clone \' " << vDev->GetName() << " \'." << std::endl;
131f857971dSopenharmony_ci        return;
132f857971dSopenharmony_ci    }
133f857971dSopenharmony_ci
134f857971dSopenharmony_ci    int32_t nTries = 3;
135f857971dSopenharmony_ci    do {
136f857971dSopenharmony_ci        std::this_thread::sleep_for(std::chrono::seconds(1));
137f857971dSopenharmony_ci    } while ((nTries-- > 0) && (VirtualKeyboard::GetDevice() == nullptr));
138f857971dSopenharmony_ci    if (VirtualKeyboard::GetDevice() == nullptr) {
139f857971dSopenharmony_ci        std::cout << "Failed to clone \' " << vDev->GetName() << " \'." << std::endl;
140f857971dSopenharmony_ci        return;
141f857971dSopenharmony_ci    }
142f857971dSopenharmony_ci
143f857971dSopenharmony_ci    std::cout << "Clone \'" << vDev->GetName() << "\' successfully" << std::endl;
144f857971dSopenharmony_ci    VirtualDeviceBuilder::Daemonize();
145f857971dSopenharmony_ci    for (;;) {
146f857971dSopenharmony_ci        std::this_thread::sleep_for(std::chrono::minutes(1));
147f857971dSopenharmony_ci    }
148f857971dSopenharmony_ci}
149f857971dSopenharmony_ci
150f857971dSopenharmony_civoid VirtualKeyboardBuilder::Act(int32_t argc, char *argv[])
151f857971dSopenharmony_ci{
152f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
153f857971dSopenharmony_ci    int32_t opt = getopt(argc, argv, "d:u:f:r:w:");
154f857971dSopenharmony_ci    if (opt < 0) {
155f857971dSopenharmony_ci        std::cout << "Vdevadm act: required option is missing" << std::endl;
156f857971dSopenharmony_ci        ShowUsage();
157f857971dSopenharmony_ci        return;
158f857971dSopenharmony_ci    }
159f857971dSopenharmony_ci    if (VirtualKeyboard::GetDevice() == nullptr) {
160f857971dSopenharmony_ci        std::cout << "No virtual keyboard." << std::endl;
161f857971dSopenharmony_ci        return;
162f857971dSopenharmony_ci    }
163f857971dSopenharmony_ci    do {
164f857971dSopenharmony_ci        switch (opt) {
165f857971dSopenharmony_ci            case 'd': {
166f857971dSopenharmony_ci                ReadDownAction();
167f857971dSopenharmony_ci                break;
168f857971dSopenharmony_ci            }
169f857971dSopenharmony_ci            case 'u': {
170f857971dSopenharmony_ci                ReadUpAction();
171f857971dSopenharmony_ci                break;
172f857971dSopenharmony_ci            }
173f857971dSopenharmony_ci            case 'f': {
174f857971dSopenharmony_ci                ReadActions(optarg);
175f857971dSopenharmony_ci                break;
176f857971dSopenharmony_ci            }
177f857971dSopenharmony_ci            case 'r': {
178f857971dSopenharmony_ci                ReadRawInput(optarg);
179f857971dSopenharmony_ci                break;
180f857971dSopenharmony_ci            }
181f857971dSopenharmony_ci            case 'w': {
182f857971dSopenharmony_ci                VirtualDeviceBuilder::WaitFor(optarg, "keyboard");
183f857971dSopenharmony_ci                break;
184f857971dSopenharmony_ci            }
185f857971dSopenharmony_ci            default: {
186f857971dSopenharmony_ci                ShowUsage();
187f857971dSopenharmony_ci                break;
188f857971dSopenharmony_ci            }
189f857971dSopenharmony_ci        }
190f857971dSopenharmony_ci    } while ((opt = getopt(argc, argv, "d:u:f:r:w:")) >= 0);
191f857971dSopenharmony_ci}
192f857971dSopenharmony_ci
193f857971dSopenharmony_civoid VirtualKeyboardBuilder::ReadDownAction()
194f857971dSopenharmony_ci{
195f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
196f857971dSopenharmony_ci    CHKPV(optarg);
197f857971dSopenharmony_ci    if (!Utility::IsInteger(optarg)) {
198f857971dSopenharmony_ci        std::cout << "Require arguments for Option \'-d\'." << std::endl;
199f857971dSopenharmony_ci        ShowUsage();
200f857971dSopenharmony_ci        return;
201f857971dSopenharmony_ci    }
202f857971dSopenharmony_ci
203f857971dSopenharmony_ci    int32_t key = std::atoi(optarg);
204f857971dSopenharmony_ci    std::cout << "[keyboard] down key: [" << key << "]" << std::endl;
205f857971dSopenharmony_ci    VirtualKeyboard::GetDevice()->Down(key);
206f857971dSopenharmony_ci}
207f857971dSopenharmony_ci
208f857971dSopenharmony_civoid VirtualKeyboardBuilder::ReadUpAction()
209f857971dSopenharmony_ci{
210f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
211f857971dSopenharmony_ci    CHKPV(optarg);
212f857971dSopenharmony_ci    if (!Utility::IsInteger(optarg)) {
213f857971dSopenharmony_ci        std::cout << "Require arguments for Option \'-u\'." << std::endl;
214f857971dSopenharmony_ci        ShowUsage();
215f857971dSopenharmony_ci        return;
216f857971dSopenharmony_ci    }
217f857971dSopenharmony_ci
218f857971dSopenharmony_ci    int32_t key = std::atoi(optarg);
219f857971dSopenharmony_ci    std::cout << "[keyboard] release key: [" << key << "]" << std::endl;
220f857971dSopenharmony_ci    VirtualKeyboard::GetDevice()->Up(key);
221f857971dSopenharmony_ci}
222f857971dSopenharmony_ci
223f857971dSopenharmony_civoid VirtualKeyboardBuilder::ReadActions(const char *path)
224f857971dSopenharmony_ci{
225f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
226f857971dSopenharmony_ci    CHKPV(path);
227f857971dSopenharmony_ci    char realPath[PATH_MAX] {};
228f857971dSopenharmony_ci    if (realpath(path, realPath) == nullptr) {
229f857971dSopenharmony_ci        std::cout << "[keyboard] an invalid path: " << path << std::endl;
230f857971dSopenharmony_ci        return;
231f857971dSopenharmony_ci    }
232f857971dSopenharmony_ci    if (Utility::GetFileSize(realPath) > MAXIMUM_FILESIZE_ALLOWED) {
233f857971dSopenharmony_ci        std::cout << "[keyboard] the file size is too large" << std::endl;
234f857971dSopenharmony_ci        return;
235f857971dSopenharmony_ci    }
236f857971dSopenharmony_ci    json model;
237f857971dSopenharmony_ci    int32_t ret = VirtualDeviceBuilder::ReadFile(realPath, model);
238f857971dSopenharmony_ci    if (ret == RET_ERR) {
239f857971dSopenharmony_ci        FI_HILOGE("Failed to read the file");
240f857971dSopenharmony_ci        return;
241f857971dSopenharmony_ci    }
242f857971dSopenharmony_ci    ReadModel(model, MAXIMUM_LEVEL_ALLOWED);
243f857971dSopenharmony_ci}
244f857971dSopenharmony_ci
245f857971dSopenharmony_civoid VirtualKeyboardBuilder::ReadModel(const nlohmann::json &model, int32_t level)
246f857971dSopenharmony_ci{
247f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
248f857971dSopenharmony_ci    if (!model.is_object() && !model.is_array()) {
249f857971dSopenharmony_ci        FI_HILOGE("model is not an array or object");
250f857971dSopenharmony_ci        return;
251f857971dSopenharmony_ci    }
252f857971dSopenharmony_ci    if (model.is_object()) {
253f857971dSopenharmony_ci        auto tIter = model.find("actions");
254f857971dSopenharmony_ci        if (tIter != model.cend() && tIter->is_array()) {
255f857971dSopenharmony_ci            std::for_each(tIter->cbegin(), tIter->cend(), [](const auto &item) { ReadAction(item); });
256f857971dSopenharmony_ci        }
257f857971dSopenharmony_ci    }
258f857971dSopenharmony_ci    if (model.is_array() && level > 0) {
259f857971dSopenharmony_ci        for (const auto &m : model) {
260f857971dSopenharmony_ci            ReadModel(m, level - 1);
261f857971dSopenharmony_ci        }
262f857971dSopenharmony_ci    }
263f857971dSopenharmony_ci}
264f857971dSopenharmony_ci
265f857971dSopenharmony_civoid VirtualKeyboardBuilder::ReadAction(const nlohmann::json &model)
266f857971dSopenharmony_ci{
267f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
268f857971dSopenharmony_ci    if (!model.is_object()) {
269f857971dSopenharmony_ci        FI_HILOGD("Not an object");
270f857971dSopenharmony_ci        return;
271f857971dSopenharmony_ci    }
272f857971dSopenharmony_ci    auto it = model.find("action");
273f857971dSopenharmony_ci    if (it != model.cend() && it->is_string()) {
274f857971dSopenharmony_ci        static const std::unordered_map<std::string, std::function<void(const nlohmann::json &model)>> actions {
275f857971dSopenharmony_ci            { "down", &VirtualKeyboardBuilder::HandleDown },
276f857971dSopenharmony_ci            { "up", &VirtualKeyboardBuilder::HandleUp },
277f857971dSopenharmony_ci            { "wait", &VirtualKeyboardBuilder::HandleWait }
278f857971dSopenharmony_ci        };
279f857971dSopenharmony_ci        auto actionItr = actions.find(it.value());
280f857971dSopenharmony_ci        if (actionItr != actions.cend()) {
281f857971dSopenharmony_ci            actionItr->second(model);
282f857971dSopenharmony_ci        }
283f857971dSopenharmony_ci    }
284f857971dSopenharmony_ci}
285f857971dSopenharmony_ci
286f857971dSopenharmony_civoid VirtualKeyboardBuilder::HandleDown(const nlohmann::json &model)
287f857971dSopenharmony_ci{
288f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
289f857971dSopenharmony_ci    auto it = model.find("key");
290f857971dSopenharmony_ci    if (it != model.cend() && it->is_number_integer()) {
291f857971dSopenharmony_ci        std::cout << "[virtual keyboard] down key: " << it.value() << std::endl;
292f857971dSopenharmony_ci        VirtualKeyboard::GetDevice()->Down(it.value());
293f857971dSopenharmony_ci    }
294f857971dSopenharmony_ci}
295f857971dSopenharmony_ci
296f857971dSopenharmony_civoid VirtualKeyboardBuilder::HandleUp(const nlohmann::json &model)
297f857971dSopenharmony_ci{
298f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
299f857971dSopenharmony_ci    auto it = model.find("key");
300f857971dSopenharmony_ci    if (it != model.cend() && it->is_number_integer()) {
301f857971dSopenharmony_ci        std::cout << "[virtual keyboard] release key: " << it.value() << std::endl;
302f857971dSopenharmony_ci        VirtualKeyboard::GetDevice()->Up(it.value());
303f857971dSopenharmony_ci    }
304f857971dSopenharmony_ci}
305f857971dSopenharmony_ci
306f857971dSopenharmony_civoid VirtualKeyboardBuilder::HandleWait(const nlohmann::json &model)
307f857971dSopenharmony_ci{
308f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
309f857971dSopenharmony_ci    auto it = model.find("duration");
310f857971dSopenharmony_ci    if (it != model.cend() && it->is_number_integer()) {
311f857971dSopenharmony_ci        int32_t waitTime = it.value();
312f857971dSopenharmony_ci        std::cout << "[virtual keyboard] wait for " << waitTime << " milliseconds" << std::endl;
313f857971dSopenharmony_ci        VirtualDeviceBuilder::WaitFor("virtual keyboard", waitTime);
314f857971dSopenharmony_ci    }
315f857971dSopenharmony_ci}
316f857971dSopenharmony_ci
317f857971dSopenharmony_civoid VirtualKeyboardBuilder::ReadRawInput(const char *path)
318f857971dSopenharmony_ci{
319f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
320f857971dSopenharmony_ci    CHKPV(path);
321f857971dSopenharmony_ci    char realPath[PATH_MAX] {};
322f857971dSopenharmony_ci
323f857971dSopenharmony_ci    if (realpath(path, realPath) == nullptr) {
324f857971dSopenharmony_ci        std::cout << "[keyboard] invalid path: " << path << std::endl;
325f857971dSopenharmony_ci        return;
326f857971dSopenharmony_ci    }
327f857971dSopenharmony_ci    if (Utility::GetFileSize(realPath) > MAXIMUM_FILESIZE_ALLOWED) {
328f857971dSopenharmony_ci        std::cout << "[keyboard] file is too large" << std::endl;
329f857971dSopenharmony_ci        return;
330f857971dSopenharmony_ci    }
331f857971dSopenharmony_ci    json model;
332f857971dSopenharmony_ci
333f857971dSopenharmony_ci    int32_t ret = VirtualDeviceBuilder::ReadFile(realPath, model);
334f857971dSopenharmony_ci    if (ret == RET_ERR) {
335f857971dSopenharmony_ci        FI_HILOGE("Failed to read raw input data");
336f857971dSopenharmony_ci        return;
337f857971dSopenharmony_ci    }
338f857971dSopenharmony_ci    ReadRawModel(model, MAXIMUM_LEVEL_ALLOWED);
339f857971dSopenharmony_ci}
340f857971dSopenharmony_ci
341f857971dSopenharmony_civoid VirtualKeyboardBuilder::ReadRawModel(const nlohmann::json &model, int32_t level)
342f857971dSopenharmony_ci{
343f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
344f857971dSopenharmony_ci    if (!model.is_object() && !model.is_array()) {
345f857971dSopenharmony_ci        FI_HILOGE("model is not an array or object");
346f857971dSopenharmony_ci        return;
347f857971dSopenharmony_ci    }
348f857971dSopenharmony_ci    if (model.is_object()) {
349f857971dSopenharmony_ci        auto typeIter = model.find("type");
350f857971dSopenharmony_ci        if (typeIter == model.cend() || !typeIter->is_string() || (std::string(typeIter.value()).compare("raw") != 0)) {
351f857971dSopenharmony_ci            std::cout << "Expect raw input data" << std::endl;
352f857971dSopenharmony_ci            return;
353f857971dSopenharmony_ci        }
354f857971dSopenharmony_ci        auto actionIter = model.find("actions");
355f857971dSopenharmony_ci        if (actionIter != model.cend() && actionIter->is_array()) {
356f857971dSopenharmony_ci            std::for_each(actionIter->cbegin(), actionIter->cend(), [](const auto &item) { ReadRawData(item); });
357f857971dSopenharmony_ci        }
358f857971dSopenharmony_ci    }
359f857971dSopenharmony_ci    if (model.is_array() && level > 0) {
360f857971dSopenharmony_ci        for (const auto &m : model) {
361f857971dSopenharmony_ci            ReadRawModel(m, level - 1);
362f857971dSopenharmony_ci        }
363f857971dSopenharmony_ci    }
364f857971dSopenharmony_ci}
365f857971dSopenharmony_ci
366f857971dSopenharmony_civoid VirtualKeyboardBuilder::ReadRawData(const nlohmann::json &model)
367f857971dSopenharmony_ci{
368f857971dSopenharmony_ci    CALL_DEBUG_ENTER;
369f857971dSopenharmony_ci    if (!model.is_object()) {
370f857971dSopenharmony_ci        FI_HILOGE("model is not an object");
371f857971dSopenharmony_ci        return;
372f857971dSopenharmony_ci    }
373f857971dSopenharmony_ci    auto valueIter = model.find("value");
374f857971dSopenharmony_ci    if (valueIter == model.cend() || !valueIter->is_number_integer()) {
375f857971dSopenharmony_ci        return;
376f857971dSopenharmony_ci    }
377f857971dSopenharmony_ci    auto codeIter = model.find("code");
378f857971dSopenharmony_ci    if (codeIter == model.cend() || !codeIter->is_number_integer()) {
379f857971dSopenharmony_ci        return;
380f857971dSopenharmony_ci    }
381f857971dSopenharmony_ci    auto typeIter = model.find("type");
382f857971dSopenharmony_ci    if (typeIter == model.cend() || !typeIter->is_number_integer()) {
383f857971dSopenharmony_ci        return;
384f857971dSopenharmony_ci    }
385f857971dSopenharmony_ci    std::cout << "[virtual keyboard] raw input: [" << typeIter.value() << ", " << codeIter.value() << ", " <<
386f857971dSopenharmony_ci        valueIter.value() << "]" << std::endl;
387f857971dSopenharmony_ci    VirtualKeyboard::GetDevice()->SendEvent(typeIter.value(), codeIter.value(), valueIter.value());
388f857971dSopenharmony_ci}
389f857971dSopenharmony_ci} // namespace DeviceStatus
390f857971dSopenharmony_ci} // namespace Msdp
391f857971dSopenharmony_ci} // namespace OHOS