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 "key_event_util.h"
17
18 #include <algorithm>
19
20 #include "global.h"
21 #include "input_manager.h"
22
23 namespace OHOS {
24 namespace MiscServices {
25 constexpr int32_t SEC_TO_NANOSEC = 1000000000;
26 constexpr int32_t NANOSECOND_TO_MILLISECOND = 1000000;
27 constexpr int32_t DEFAULT_DEVICE_ID = -1;
28 constexpr int32_t DEFAULT_UNICODE = 0x0000;
SimulateKeyEvent(int32_t keyCode)29 bool KeyEventUtil::SimulateKeyEvent(int32_t keyCode)
30 {
31 auto keyDown = CreateKeyEvent(keyCode, MMI::KeyEvent::KEY_ACTION_DOWN);
32 auto keyUp = CreateKeyEvent(keyCode, MMI::KeyEvent::KEY_ACTION_UP);
33 if (keyDown == nullptr || keyUp == nullptr) {
34 IMSA_HILOGE("failed to create key event: %{public}d", keyCode);
35 return false;
36 }
37 MMI::InputManager::GetInstance()->SimulateInputEvent(keyDown);
38 MMI::InputManager::GetInstance()->SimulateInputEvent(keyUp);
39 return true;
40 }
41
SimulateKeyEvents(const std::vector<int32_t> & keys)42 bool KeyEventUtil::SimulateKeyEvents(const std::vector<int32_t> &keys)
43 {
44 if (keys.empty()) {
45 IMSA_HILOGE("keys is empty");
46 return false;
47 }
48 std::vector<std::shared_ptr<MMI::KeyEvent>> downKeys_;
49 std::vector<std::shared_ptr<MMI::KeyEvent>> upKeys_;
50 for (auto &key : keys) {
51 auto keyDown = CreateKeyEvent(key, MMI::KeyEvent::KEY_ACTION_DOWN);
52 auto keyUp = CreateKeyEvent(key, MMI::KeyEvent::KEY_ACTION_UP);
53 if (keyDown == nullptr || keyUp == nullptr) {
54 IMSA_HILOGE("failed to create key event: %{public}d", key);
55 return false;
56 }
57 downKeys_.push_back(keyDown);
58 upKeys_.push_back(keyUp);
59 }
60 // first pressed last lift.
61 std::reverse(upKeys_.begin(), upKeys_.end());
62 for (auto &downKey : downKeys_) {
63 MMI::InputManager::GetInstance()->SimulateInputEvent(downKey);
64 }
65 for (auto &upkey : upKeys_) {
66 MMI::InputManager::GetInstance()->SimulateInputEvent(upkey);
67 }
68 return true;
69 }
70
CreateKeyEvent(int32_t keyCode,int32_t keyAction)71 std::shared_ptr<MMI::KeyEvent> KeyEventUtil::CreateKeyEvent(int32_t keyCode, int32_t keyAction)
72 {
73 std::shared_ptr<MMI::KeyEvent> keyEvent = MMI::KeyEvent::Create();
74 int64_t downTime = GetNanoTime() / NANOSECOND_TO_MILLISECOND;
75 MMI::KeyEvent::KeyItem keyItem;
76 keyItem.SetKeyCode(keyCode);
77 keyItem.SetPressed(keyAction == MMI::KeyEvent::KEY_ACTION_DOWN);
78 keyItem.SetDownTime(downTime);
79 keyItem.SetDeviceId(DEFAULT_DEVICE_ID);
80 keyItem.SetUnicode(DEFAULT_UNICODE);
81 if (keyEvent != nullptr) {
82 keyEvent->SetKeyCode(keyCode);
83 keyEvent->SetKeyAction(keyAction);
84 keyEvent->AddPressedKeyItems(keyItem);
85 }
86 return keyEvent;
87 }
88
GetNanoTime()89 int64_t KeyEventUtil::GetNanoTime()
90 {
91 struct timespec time = { 0 };
92 clock_gettime(CLOCK_MONOTONIC, &time);
93 return static_cast<int64_t>(time.tv_sec) * SEC_TO_NANOSEC + time.tv_nsec;
94 }
95 } // namespace MiscServices
96 } // namespace OHOS
97