1/*
2 * Copyright (c) 2022 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#include "multimode_manager.h"
16
17namespace OHOS {
18namespace WuKong {
19namespace {
20const int SHORTEST_LEN = 2;
21const int LONGEST_LEN = 20;
22const int DEFAULT_PRESSURE = 5;
23const int SLEEP_TIME = 16000;
24}  // namespace
25MultimodeManager::MultimodeManager()
26{
27    for (int i = OHOS::MMI::KeyEvent::KEYCODE_CALL; i <= OHOS::MMI::KeyEvent::KEYCODE_ENDCALL; i++) {
28        keycodelist_.push_back(i);
29    }
30
31    for (int j = OHOS::MMI::KeyEvent::KEYCODE_0; j <= OHOS::MMI::KeyEvent::KEYCODE_NUMPAD_RIGHT_PAREN; j++) {
32        keycodelist_.push_back(j);
33    }
34}
35
36MultimodeManager::~MultimodeManager()
37{
38}
39
40ErrCode MultimodeManager::SingleKeyCodeInput(int keycode, int downtime)
41{
42    ErrCode result = ERR_OK;
43    std::string keycodeType = OHOS::MMI::KeyEvent::KeyCodeToString(keycode);
44    INFO_LOG_STR("keycodeType: %s", keycodeType.c_str());
45    auto keyKeyboardEvent = OHOS::MMI::KeyEvent::Create();
46    if (!keyKeyboardEvent) {
47        WARN_LOG("keyKeyboardEvent is nullptr");
48        return OHOS::ERR_NO_INIT;
49    }
50    MMI::KeyEvent::KeyItem item;
51    item.SetKeyCode(keycode);
52    item.SetPressed(true);
53    item.SetDownTime(downtime);
54    keyKeyboardEvent->SetKeyCode(keycode);
55    keyKeyboardEvent->SetKeyAction(MMI::KeyEvent::KEY_ACTION_DOWN);
56    keyKeyboardEvent->AddPressedKeyItems(item);
57    // check if KeyEvent is valid
58    if (keyKeyboardEvent->IsValid()) {
59        MMI::InputManager::GetInstance()->SimulateInputEvent(keyKeyboardEvent);
60    } else {
61        WARN_LOG("keyevent down is invalid");
62        return OHOS::ERR_NO_INIT;
63    }
64    keyKeyboardEvent->RemoveReleasedKeyItems(item);
65    item.SetKeyCode(keycode);
66    item.SetPressed(false);
67    item.SetDownTime(downtime);
68    keyKeyboardEvent->SetKeyCode(keycode);
69    keyKeyboardEvent->SetKeyAction(MMI::KeyEvent::KEY_ACTION_UP);
70    keyKeyboardEvent->AddPressedKeyItems(item);
71    // check if KeyEvent is valid
72    if (keyKeyboardEvent->IsValid()) {
73        MMI::InputManager::GetInstance()->SimulateInputEvent(keyKeyboardEvent);
74    } else {
75        WARN_LOG("keyevent up is invalid");
76        return OHOS::ERR_NO_INIT;
77    }
78    keyKeyboardEvent->RemoveReleasedKeyItems(item);
79
80    return result;
81}
82
83ErrCode MultimodeManager::MultiKeyCodeInput(int downtime)
84{
85    ErrCode result = OHOS::ERR_OK;
86    // generate the length of string randomly
87    int stringLen = SHORTEST_LEN + random() % (LONGEST_LEN - 1);
88    if (keycodelist_.size() > 0) {
89        for (int i = 0; i < stringLen; i++) {
90            int keycode = keycodelist_[(uint32_t)(rand()) % keycodelist_.size()];
91            result = MultimodeManager::GetInstance()->SingleKeyCodeInput(keycode, downtime);
92        }
93    } else {
94        return OHOS::ERR_NO_INIT;
95    }
96    return result;
97}
98
99void MultimodeManager::GetKeycodeList(std::vector<int> &keycodelist)
100{
101    keycodelist = keycodelist_;
102}
103
104ErrCode MultimodeManager::PointerInput(int x, int y, int pointertype, int actiontype)
105{
106    ErrCode result = OHOS::ERR_OK;
107    auto pointerEvent = MMI::PointerEvent::Create();
108    if (!pointerEvent) {
109        WARN_LOG("pointerEvent is nullptr");
110        return OHOS::ERR_NO_INIT;
111    }
112    MMI::PointerEvent::PointerItem item;
113
114    item.SetPointerId(0);
115    item.SetDisplayX(x);
116    item.SetDisplayY(y);
117    item.SetPressure(DEFAULT_PRESSURE);
118    pointerEvent->AddPointerItem(item);
119
120    pointerEvent->SetPointerAction(actiontype);
121    pointerEvent->SetSourceType(pointertype);
122    pointerEvent->SetPointerId(0);
123
124    MMI::InputManager::GetInstance()->SimulateInputEvent(pointerEvent);
125
126    return result;
127}
128
129ErrCode MultimodeManager::IntervalSwap(int xSrcPosition, int ySrcPosition, int xDstPosition, int yDstPosition)
130{
131    auto multiinput = MultimodeManager::GetInstance();
132    ErrCode result = multiinput->PointerInput(xSrcPosition, ySrcPosition, MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN,
133                                              MMI::PointerEvent::POINTER_ACTION_DOWN);
134    if (result != OHOS::ERR_OK) {
135        return result;
136    }
137    usleep(SLEEP_TIME);
138    int segment = 50;
139    float secX = (xDstPosition - xSrcPosition) / (float)segment;
140    float secY = (yDstPosition - ySrcPosition) / (float)segment;
141
142    for (int i = 1; i < segment; ++i) {
143        int mPosX = int(xSrcPosition + secX * i);
144        int mPosY = int(ySrcPosition + secY * i);
145        result = multiinput->PointerInput(mPosX, mPosY, MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN,
146                                          MMI::PointerEvent::POINTER_ACTION_MOVE);
147        if (result != OHOS::ERR_OK) {
148            return result;
149        }
150        usleep(SLEEP_TIME);
151    }
152    result = multiinput->PointerInput(xDstPosition, yDstPosition, MMI::PointerEvent::SOURCE_TYPE_TOUCHSCREEN,
153                                      MMI::PointerEvent::POINTER_ACTION_UP);
154    return result;
155}
156}  // namespace WuKong
157}  // namespace OHOS
158