1 /*
2 * Copyright (c) 2021-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 "input_event.h"
16 #include <cstdio>
17 #include <cstdlib>
18 #include <unistd.h>
19 #include "common/input_device_manager.h"
20 #include "events/key_event.h"
21 #include "log/log.h"
22 #include "updater_ui.h"
23 #include "updater_ui_const.h"
24
25 namespace Updater {
26 namespace {
27 constexpr int MAX_INPUT_DEVICES = 32;
28
29 IInputInterface *g_inputInterface;
30 InputEventCb g_callback;
31
32 bool g_touchFingerDown = false;
33
34 // for TouchInputDevice
35 int g_touchX;
36 int g_touchY;
37
38 // for KeysInputDevice
39 uint16_t g_lastKeyId;
40 uint16_t g_keyState = OHOS::INVALID_KEY_STATE;
41
HandleEvAbs(const input_event & ev)42 void HandleEvAbs(const input_event &ev)
43 {
44 const static std::unordered_map<int, std::function<void(int)>> evMap {
45 {ABS_MT_POSITION_Y, [] (int value) {
46 g_touchY = value;
47 g_touchFingerDown = true;
48 }},
49 {ABS_MT_POSITION_X, [] (int value) {
50 g_touchX = value;
51 g_touchFingerDown = true;
52 }},
53 {ABS_MT_TRACKING_ID, [] (int value) {
54 // Protocol B: -1 marks lifting the contact.
55 if (value < 0) {
56 g_touchFingerDown = false;
57 }
58 }}
59 };
60 if (auto it = evMap.find(ev.code); it != evMap.end()) {
61 it->second(ev.value);
62 }
63 }
64 }
65
HandleInputEvent(const struct input_event * iev)66 int HandleInputEvent(const struct input_event *iev)
67 {
68 struct input_event ev {};
69 ev.type = iev->type;
70 ev.code = iev->code;
71 ev.value = iev->value;
72 if (ev.type == EV_ABS) {
73 HandleEvAbs(ev);
74 return 0;
75 }
76 if (ev.type != EV_KEY || ev.code > KEY_MAX) {
77 return 0;
78 }
79 if (ev.code == BTN_TOUCH) {
80 g_touchFingerDown = (ev.value == 1);
81 }
82 if (ev.code == BTN_TOUCH || ev.code == BTN_TOOL_FINGER) {
83 return 0;
84 }
85 // KEY_VOLUMEDOWN = 114, KEY_VOLUMEUP = 115, KEY_POWER = 116
86 if (!(ev.code == KEY_VOLUMEDOWN || ev.code == KEY_VOLUMEUP || ev.code == KEY_POWER)) {
87 return 0;
88 }
89 g_keyState = (ev.value == 1) ? OHOS::InputDevice::STATE_PRESS : OHOS::InputDevice::STATE_RELEASE;
90 g_lastKeyId = ev.code;
91 return 0;
92 }
93
ReportEventPkgCallback(const InputEventPackage ** pkgs,const uint32_t count,uint32_t devIndex)94 void ReportEventPkgCallback(const InputEventPackage **pkgs, const uint32_t count, uint32_t devIndex)
95 {
96 if (pkgs == nullptr || *pkgs == nullptr) {
97 return;
98 }
99 for (uint32_t i = 0; i < count; i++) {
100 struct input_event ev = {
101 .type = static_cast<__u16>(pkgs[i]->type),
102 .code = static_cast<__u16>(pkgs[i]->code),
103 .value = pkgs[i]->value,
104 };
105 HandleInputEvent(&ev);
106 }
107 return;
108 }
109
HdfInit()110 int HdfInit()
111 {
112 int ret = GetInputInterface(&g_inputInterface);
113 if (ret != INPUT_SUCCESS) {
114 LOG(ERROR) << "get input driver interface failed";
115 return ret;
116 }
117
118 sleep(1); // need wait thread running
119
120 InputDevDesc sta[MAX_INPUT_DEVICES] = {{0}};
121 ret = g_inputInterface->iInputManager->ScanInputDevice(sta, MAX_INPUT_DEVICES);
122 if (ret != INPUT_SUCCESS) {
123 LOG(ERROR) << "scan device failed";
124 return ret;
125 }
126
127 for (int i = 0; i < MAX_INPUT_DEVICES; i++) {
128 uint32_t idx = sta[i].devIndex;
129 if ((idx == 0) || (g_inputInterface->iInputManager->OpenInputDevice(idx) == INPUT_FAILURE)) {
130 continue;
131 }
132
133 LOG(INFO) << "hdf devType:" << sta[i].devType << ", devIndex:" << idx;
134 }
135
136 /* first param not necessary, pass default 1 */
137 g_callback.EventPkgCallback = ReportEventPkgCallback;
138 ret = g_inputInterface->iInputReporter->RegisterReportCallback(1, &g_callback);
139 if (ret != INPUT_SUCCESS) {
140 LOG(ERROR) << "register callback failed for device 1";
141 return ret;
142 }
143
144 OHOS::InputDeviceManager::GetInstance()->Add(&TouchInputDevice::GetInstance());
145 OHOS::InputDeviceManager::GetInstance()->Add(&KeysInputDevice::GetInstance());
146 LOG(INFO) << "add InputDevice done";
147
148 return 0;
149 }
150
GetInstance()151 TouchInputDevice &TouchInputDevice::GetInstance()
152 {
153 static TouchInputDevice instance;
154 return instance;
155 }
156
Read(OHOS::DeviceData & data)157 bool TouchInputDevice::Read(OHOS::DeviceData& data)
158 {
159 data.point.x = g_touchX;
160 data.point.y = g_touchY;
161 data.state = g_touchFingerDown ? OHOS::InputDevice::STATE_PRESS : OHOS::InputDevice::STATE_RELEASE;
162 return false;
163 }
164
GetInstance()165 KeysInputDevice &KeysInputDevice::GetInstance()
166 {
167 static KeysInputDevice instance;
168 return instance;
169 }
170
Read(OHOS::DeviceData & data)171 bool KeysInputDevice::Read(OHOS::DeviceData& data)
172 {
173 data.keyId = g_lastKeyId;
174 data.state = g_keyState;
175 g_keyState = OHOS::INVALID_KEY_STATE;
176 return false;
177 }
178 } // namespace Updater
179