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 <cstdint>
17 #include <cstring>
18 #include <vector>
19 #include <algorithm>
20 #include <unordered_map>
21 #include "hid_ddk_api.h"
22 #include "hid_ddk_types.h"
23 #include "v1_0/ihid_ddk.h"
24 #include "hilog_wrapper.h"
25 #include <iproxy_broker.h>
26
27 using namespace OHOS;
28 using namespace OHOS::ExternalDeviceManager;
29 namespace {
30 static OHOS::sptr<OHOS::HDI::Input::Ddk::V1_0::IHidDdk> g_ddk = nullptr;
31 static OHOS::sptr<IRemoteObject::DeathRecipient> recipient_ = nullptr;
32 std::mutex g_mutex;
33 constexpr uint32_t MAX_EMIT_ITEM_NUM = 20;
34 constexpr uint32_t MAX_HID_DEVICE_PROP_LEN = 7;
35 constexpr uint32_t MAX_HID_EVENT_TYPES_LEN = 5;
36 constexpr uint32_t MAX_HID_KEYS_LEN = 100;
37 constexpr uint32_t MAX_HID_ABS_LEN = 26;
38 constexpr uint32_t MAX_HID_REL_BITS_LEN = 13;
39 constexpr uint32_t MAX_HID_MISC_EVENT_LEN = 6;
40 constexpr uint32_t MAX_NAME_LENGTH = 80;
41 }
42 #ifdef __cplusplus
43 extern "C" {
44 #endif /* __cplusplus */
45 static std::unordered_map<int32_t, std::shared_ptr<struct TempDevice>> g_deviceMap;
46
47 struct TempDevice {
48 OHOS::HDI::Input::Ddk::V1_0::Hid_Device tempDevice;
49 OHOS::HDI::Input::Ddk::V1_0::Hid_EventProperties tempProperties;
50 uint32_t realId;
51 };
52
53 class HidDeathRecipient : public IRemoteObject::DeathRecipient {
54 public:
55 void OnRemoteDied(const wptr<IRemoteObject> &object) override;
56 };
57
OnRemoteDied(const wptr<IRemoteObject> & object)58 void HidDeathRecipient::OnRemoteDied(const wptr<IRemoteObject> &object)
59 {
60 std::lock_guard<std::mutex> lock(g_mutex);
61 EDM_LOGI(MODULE_HID_DDK, "hid_ddk remote died");
62 if (g_ddk != nullptr) {
63 sptr<IRemoteObject> remote = OHOS::HDI::hdi_objcast<OHOS::HDI::Input::Ddk::V1_0::IHidDdk>(g_ddk);
64 remote->RemoveDeathRecipient(recipient_);
65 recipient_.clear();
66 g_ddk = nullptr;
67 EDM_LOGI(MODULE_HID_DDK, "remove death recipient success");
68 }
69 }
70
GetRealDeviceId(int32_t deviceId)71 static uint32_t GetRealDeviceId(int32_t deviceId)
72 {
73 if (g_deviceMap.find(deviceId) != g_deviceMap.end()) {
74 if (g_deviceMap[deviceId] != nullptr) {
75 return g_deviceMap[deviceId]->realId;
76 }
77 }
78 return static_cast<uint32_t>(deviceId);
79 }
80
Connect()81 static int32_t Connect()
82 {
83 if (g_ddk == nullptr) {
84 g_ddk = OHOS::HDI::Input::Ddk::V1_0::IHidDdk::Get();
85 if (g_ddk == nullptr) {
86 EDM_LOGE(MODULE_HID_DDK, "get hid ddk faild");
87 return HID_DDK_FAILURE;
88 }
89 if (g_deviceMap.size() > 0) {
90 for (const auto &[_, value] : g_deviceMap) {
91 (void)g_ddk->CreateDevice(value->tempDevice, value->tempProperties, value->realId);
92 }
93 }
94 recipient_ = new HidDeathRecipient();
95 sptr<IRemoteObject> remote = OHOS::HDI::hdi_objcast<OHOS::HDI::Input::Ddk::V1_0::IHidDdk>(g_ddk);
96 if (!remote->AddDeathRecipient(recipient_)) {
97 EDM_LOGE(MODULE_HID_DDK, "add DeathRecipient failed");
98 return HID_DDK_FAILURE;
99 }
100 }
101 return HID_DDK_SUCCESS;
102 }
103
ParseHidDevice(Hid_Device * hidDevice)104 static OHOS::HDI::Input::Ddk::V1_0::Hid_Device ParseHidDevice(Hid_Device *hidDevice)
105 {
106 OHOS::HDI::Input::Ddk::V1_0::Hid_Device tempDevice = {
107 .deviceName = hidDevice->deviceName,
108 .vendorId = hidDevice->vendorId,
109 .productId = hidDevice->productId,
110 .version = hidDevice->version,
111 .bustype = hidDevice->bustype
112 };
113
114 if (hidDevice->properties != nullptr) {
115 std::transform(hidDevice->properties, hidDevice->properties + hidDevice->propLength,
116 std::back_inserter(tempDevice.properties), [](uint32_t n) {
117 return static_cast<OHOS::HDI::Input::Ddk::V1_0::Hid_DeviceProp>(n);
118 });
119 }
120
121 return tempDevice;
122 }
123
ParseHidEventProperties(Hid_EventProperties * hidEventProperties)124 static OHOS::HDI::Input::Ddk::V1_0::Hid_EventProperties ParseHidEventProperties(Hid_EventProperties *hidEventProperties)
125 {
126 const uint16_t absLength = 64;
127 OHOS::HDI::Input::Ddk::V1_0::Hid_EventProperties tempProperties = {
128 .hidAbsMax = std::vector<int32_t>(hidEventProperties->hidAbsMax, hidEventProperties->hidAbsMax + absLength),
129 .hidAbsMin = std::vector<int32_t>(hidEventProperties->hidAbsMin, hidEventProperties->hidAbsMin + absLength),
130 .hidAbsFuzz = std::vector<int32_t>(hidEventProperties->hidAbsFuzz, hidEventProperties->hidAbsFuzz + absLength),
131 .hidAbsFlat = std::vector<int32_t>(hidEventProperties->hidAbsFlat, hidEventProperties->hidAbsFlat + absLength)
132 };
133
134 if (hidEventProperties->hidEventTypes.hidEventType != nullptr) {
135 std::transform(hidEventProperties->hidEventTypes.hidEventType,
136 hidEventProperties->hidEventTypes.hidEventType + hidEventProperties->hidEventTypes.length,
137 std::back_inserter(tempProperties.hidEventTypes), [](uint32_t n) {
138 return static_cast<OHOS::HDI::Input::Ddk::V1_0::Hid_EventType>(n);
139 });
140 }
141
142 if (hidEventProperties->hidKeys.hidKeyCode != nullptr) {
143 std::transform(hidEventProperties->hidKeys.hidKeyCode,
144 hidEventProperties->hidKeys.hidKeyCode + hidEventProperties->hidKeys.length,
145 std::back_inserter(tempProperties.hidKeys), [](uint32_t n) {
146 return static_cast<OHOS::HDI::Input::Ddk::V1_0::Hid_KeyCode>(n);
147 });
148 }
149
150 if (hidEventProperties->hidAbs.hidAbsAxes != nullptr) {
151 std::transform(hidEventProperties->hidAbs.hidAbsAxes,
152 hidEventProperties->hidAbs.hidAbsAxes + hidEventProperties->hidAbs.length,
153 std::back_inserter(tempProperties.hidAbs), [](uint32_t n) {
154 return static_cast<OHOS::HDI::Input::Ddk::V1_0::Hid_AbsAxes>(n);
155 });
156 }
157
158 if (hidEventProperties->hidRelBits.hidRelAxes != nullptr) {
159 std::transform(hidEventProperties->hidRelBits.hidRelAxes,
160 hidEventProperties->hidRelBits.hidRelAxes + hidEventProperties->hidRelBits.length,
161 std::back_inserter(tempProperties.hidRelBits), [](uint32_t n) {
162 return static_cast<OHOS::HDI::Input::Ddk::V1_0::Hid_RelAxes>(n);
163 });
164 }
165
166 if (hidEventProperties->hidMiscellaneous.hidMscEvent != nullptr) {
167 std::transform(hidEventProperties->hidMiscellaneous.hidMscEvent,
168 hidEventProperties->hidMiscellaneous.hidMscEvent + hidEventProperties->hidMiscellaneous.length,
169 std::back_inserter(tempProperties.hidMiscellaneous), [](uint32_t n) {
170 return static_cast<OHOS::HDI::Input::Ddk::V1_0::Hid_MscEvent>(n);
171 });
172 }
173
174 return tempProperties;
175 }
176
CacheDeviceInfor(OHOS::HDI::Input::Ddk::V1_0::Hid_Device tempDevice,OHOS::HDI::Input::Ddk::V1_0::Hid_EventProperties tempProperties,uint32_t deviceId)177 static int32_t CacheDeviceInfor(OHOS::HDI::Input::Ddk::V1_0::Hid_Device tempDevice,
178 OHOS::HDI::Input::Ddk::V1_0::Hid_EventProperties tempProperties, uint32_t deviceId)
179 {
180 EDM_LOGD(MODULE_HID_DDK, "enter CacheDeviceInfor");
181 int32_t id = static_cast<int32_t>(deviceId);
182 std::shared_ptr<struct TempDevice> device = std::make_shared<struct TempDevice>();
183 device->tempDevice = tempDevice;
184 device->tempProperties = tempProperties;
185 device->realId = deviceId;
186
187 g_deviceMap[id] = device;
188 return id;
189 }
190
CheckHidDevice(Hid_Device * hidDevice)191 static bool CheckHidDevice(Hid_Device *hidDevice)
192 {
193 if (hidDevice == nullptr) {
194 EDM_LOGE(MODULE_HID_DDK, "hidDevice is null");
195 return false;
196 }
197
198 if (hidDevice->propLength > MAX_HID_DEVICE_PROP_LEN) {
199 EDM_LOGE(MODULE_HID_DDK, "properties length is out of range");
200 return false;
201 }
202
203 if (hidDevice->deviceName == nullptr) {
204 EDM_LOGE(MODULE_HID_DDK, "hidDevice->deviceName is nullpointer");
205 return false;
206 }
207
208 if (strlen(hidDevice->deviceName) == 0 || strlen(hidDevice->deviceName) > MAX_NAME_LENGTH - 1) {
209 EDM_LOGE(MODULE_HID_DDK, "length of hidDevice->deviceName is out of range");
210 return false;
211 }
212 return true;
213 }
214
OH_Hid_CreateDevice(Hid_Device * hidDevice,Hid_EventProperties * hidEventProperties)215 int32_t OH_Hid_CreateDevice(Hid_Device *hidDevice, Hid_EventProperties *hidEventProperties)
216 {
217 std::lock_guard<std::mutex> lock(g_mutex);
218 if (Connect() != HID_DDK_SUCCESS) {
219 return HID_DDK_INVALID_OPERATION;
220 }
221
222 if (!CheckHidDevice(hidDevice)) {
223 return HID_DDK_INVALID_PARAMETER;
224 }
225
226 if (hidEventProperties == nullptr) {
227 EDM_LOGE(MODULE_HID_DDK, "hidEventProperties is null");
228 return HID_DDK_INVALID_PARAMETER;
229 }
230
231 if (hidEventProperties->hidEventTypes.length > MAX_HID_EVENT_TYPES_LEN) {
232 EDM_LOGE(MODULE_HID_DDK, "hidEventTypes length is out of range");
233 return HID_DDK_INVALID_PARAMETER;
234 }
235
236 if (hidEventProperties->hidKeys.length > MAX_HID_KEYS_LEN) {
237 EDM_LOGE(MODULE_HID_DDK, "hidKeys length is out of range");
238 return HID_DDK_INVALID_PARAMETER;
239 }
240
241 if (hidEventProperties->hidAbs.length > MAX_HID_ABS_LEN) {
242 EDM_LOGE(MODULE_HID_DDK, "hidAbs length is out of range");
243 return HID_DDK_INVALID_PARAMETER;
244 }
245
246 if (hidEventProperties->hidRelBits.length > MAX_HID_REL_BITS_LEN) {
247 EDM_LOGE(MODULE_HID_DDK, "hidRelBits length is out of range");
248 return HID_DDK_INVALID_PARAMETER;
249 }
250
251 if (hidEventProperties->hidMiscellaneous.length > MAX_HID_MISC_EVENT_LEN) {
252 EDM_LOGE(MODULE_HID_DDK, "hidMiscellaneous length is out of range");
253 return HID_DDK_INVALID_PARAMETER;
254 }
255
256 auto tempDevice = ParseHidDevice(hidDevice);
257 auto tempEventProperties = ParseHidEventProperties(hidEventProperties);
258
259 uint32_t deviceId = 0;
260 auto ret = g_ddk->CreateDevice(tempDevice, tempEventProperties, deviceId);
261 if (ret != HID_DDK_SUCCESS) {
262 EDM_LOGE(MODULE_HID_DDK, "create device failed:%{public}d", ret);
263 return ret;
264 }
265 return CacheDeviceInfor(tempDevice, tempEventProperties, deviceId);
266 }
267
OH_Hid_EmitEvent(int32_t deviceId,const Hid_EmitItem items[],uint16_t length)268 int32_t OH_Hid_EmitEvent(int32_t deviceId, const Hid_EmitItem items[], uint16_t length)
269 {
270 std::lock_guard<std::mutex> lock(g_mutex);
271 if (Connect() != HID_DDK_SUCCESS) {
272 return HID_DDK_INVALID_OPERATION;
273 }
274
275 if (deviceId < 0) {
276 EDM_LOGE(MODULE_HID_DDK, "device id is invaild");
277 return HID_DDK_INVALID_PARAMETER;
278 }
279
280 if (length > MAX_EMIT_ITEM_NUM) {
281 EDM_LOGE(MODULE_HID_DDK, "items length is out of range");
282 return HID_DDK_INVALID_PARAMETER;
283 }
284
285 if (items == nullptr) {
286 EDM_LOGE(MODULE_HID_DDK, "items is null");
287 return HID_DDK_INVALID_PARAMETER;
288 }
289
290 std::vector<OHOS::HDI::Input::Ddk::V1_0::Hid_EmitItem> itemsTemp;
291 std::transform(items, items + length, std::back_inserter(itemsTemp), [](Hid_EmitItem item) {
292 return *reinterpret_cast<OHOS::HDI::Input::Ddk::V1_0::Hid_EmitItem *>(&item);
293 });
294
295 auto ret = g_ddk->EmitEvent(GetRealDeviceId(deviceId), itemsTemp);
296 if (ret != HID_DDK_SUCCESS) {
297 EDM_LOGE(MODULE_HID_DDK, "emit event failed:%{public}d", ret);
298 return ret;
299 }
300 return HID_DDK_SUCCESS;
301 }
302
OH_Hid_DestroyDevice(int32_t deviceId)303 int32_t OH_Hid_DestroyDevice(int32_t deviceId)
304 {
305 std::lock_guard<std::mutex> lock(g_mutex);
306 if (Connect() != HID_DDK_SUCCESS) {
307 return HID_DDK_INVALID_OPERATION;
308 }
309
310 auto ret = g_ddk->DestroyDevice(GetRealDeviceId(deviceId));
311 if (ret != HID_DDK_SUCCESS) {
312 EDM_LOGE(MODULE_HID_DDK, "destroy device failed:%{public}d", ret);
313 return ret;
314 }
315
316 g_deviceMap.erase(deviceId);
317 return HID_DDK_SUCCESS;
318 }
319 #ifdef __cplusplus
320 }
321 #endif /* __cplusplus */
322