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 <vector>
17 #include <algorithm>
18 #include "hid_ddk_api.h"
19 #include "v1_0/ihid_ddk.h"
20 #include "hilog_wrapper.h"
21 #include "ext_permission_manager.h"
22
23 using namespace OHOS::ExternalDeviceManager;
24 namespace {
25 static OHOS::sptr<OHOS::HDI::Input::Ddk::V1_0::IHidDdk> g_ddk = nullptr;
26 constexpr uint32_t MAX_EMIT_ITEM_NUM = 20;
27 constexpr uint32_t MAX_HID_DEVICE_PROP_LEN = 7;
28 constexpr uint32_t MAX_HID_EVENT_TYPES_LEN = 5;
29 constexpr uint32_t MAX_HID_KEYS_LEN = 100;
30 constexpr uint32_t MAX_HID_ABS_LEN = 26;
31 constexpr uint32_t MAX_HID_REL_BITS_LEN = 13;
32 constexpr uint32_t MAX_HID_MISC_EVENT_LEN = 6;
33 }
34 #ifdef __cplusplus
35 extern "C" {
36 #endif /* __cplusplus */
37 static const std::string PERMISSION_NAME = "ohos.permission.ACCESS_DDK_HID";
38
Connect()39 static int32_t Connect()
40 {
41 if (g_ddk != nullptr) {
42 return HID_DDK_SUCCESS;
43 }
44
45 g_ddk = OHOS::HDI::Input::Ddk::V1_0::IHidDdk::Get();
46 if (g_ddk == nullptr) {
47 EDM_LOGE(MODULE_HID_DDK, "get hid ddk faild");
48 return HID_DDK_FAILURE;
49 }
50
51 return HID_DDK_SUCCESS;
52 }
53
ParseHidDevice(Hid_Device * hidDevice)54 static OHOS::HDI::Input::Ddk::V1_0::Hid_Device ParseHidDevice(Hid_Device *hidDevice)
55 {
56 OHOS::HDI::Input::Ddk::V1_0::Hid_Device tempDevice = {
57 .deviceName = hidDevice->deviceName,
58 .vendorId = hidDevice->vendorId,
59 .productId = hidDevice->productId,
60 .version = hidDevice->version,
61 .bustype = hidDevice->bustype
62 };
63
64 std::transform(hidDevice->properties, hidDevice->properties + hidDevice->propLength,
65 std::back_inserter(tempDevice.properties), [](uint32_t n) {
66 return static_cast<OHOS::HDI::Input::Ddk::V1_0::Hid_DeviceProp>(n);
67 });
68
69 return tempDevice;
70 }
71
ParseHidEventProperties(Hid_EventProperties * hidEventProperties)72 static OHOS::HDI::Input::Ddk::V1_0::Hid_EventProperties ParseHidEventProperties(Hid_EventProperties *hidEventProperties)
73 {
74 const uint16_t absLength = 64;
75 OHOS::HDI::Input::Ddk::V1_0::Hid_EventProperties tempProperties = {
76 .hidAbsMax = std::vector<int32_t>(hidEventProperties->hidAbsMax, hidEventProperties->hidAbsMax + absLength),
77 .hidAbsMin = std::vector<int32_t>(hidEventProperties->hidAbsMin, hidEventProperties->hidAbsMin + absLength),
78 .hidAbsFuzz = std::vector<int32_t>(hidEventProperties->hidAbsFuzz, hidEventProperties->hidAbsFuzz + absLength),
79 .hidAbsFlat = std::vector<int32_t>(hidEventProperties->hidAbsFlat, hidEventProperties->hidAbsFlat + absLength)
80 };
81
82 std::transform(hidEventProperties->hidEventTypes.hidEventType,
83 hidEventProperties->hidEventTypes.hidEventType + hidEventProperties->hidEventTypes.length,
84 std::back_inserter(tempProperties.hidEventTypes), [](uint32_t n) {
85 return static_cast<OHOS::HDI::Input::Ddk::V1_0::Hid_EventType>(n);
86 });
87
88 std::transform(hidEventProperties->hidKeys.hidKeyCode,
89 hidEventProperties->hidKeys.hidKeyCode + hidEventProperties->hidKeys.length,
90 std::back_inserter(tempProperties.hidKeys), [](uint32_t n) {
91 return static_cast<OHOS::HDI::Input::Ddk::V1_0::Hid_KeyCode>(n);
92 });
93 std::transform(hidEventProperties->hidAbs.hidAbsAxes,
94 hidEventProperties->hidAbs.hidAbsAxes + hidEventProperties->hidAbs.length,
95 std::back_inserter(tempProperties.hidAbs), [](uint32_t n) {
96 return static_cast<OHOS::HDI::Input::Ddk::V1_0::Hid_AbsAxes>(n);
97 });
98 std::transform(hidEventProperties->hidRelBits.hidRelAxes,
99 hidEventProperties->hidRelBits.hidRelAxes + hidEventProperties->hidRelBits.length,
100 std::back_inserter(tempProperties.hidRelBits), [](uint32_t n) {
101 return static_cast<OHOS::HDI::Input::Ddk::V1_0::Hid_RelAxes>(n);
102 });
103 std::transform(hidEventProperties->hidMiscellaneous.hidMscEvent,
104 hidEventProperties->hidMiscellaneous.hidMscEvent + hidEventProperties->hidMiscellaneous.length,
105 std::back_inserter(tempProperties.hidMiscellaneous), [](uint32_t n) {
106 return static_cast<OHOS::HDI::Input::Ddk::V1_0::Hid_MscEvent>(n);
107 });
108
109 return tempProperties;
110 }
111
OH_Hid_CreateDevice(Hid_Device * hidDevice,Hid_EventProperties * hidEventProperties)112 int32_t OH_Hid_CreateDevice(Hid_Device *hidDevice, Hid_EventProperties *hidEventProperties)
113 {
114 if (!ExtPermissionManager::GetInstance().HasPermission(PERMISSION_NAME)) {
115 EDM_LOGE(MODULE_HID_DDK, "no permission");
116 return HID_DDK_FAILURE;
117 }
118
119 if (Connect() != HID_DDK_SUCCESS) {
120 return HID_DDK_INVALID_OPERATION;
121 }
122
123 if (hidDevice == nullptr) {
124 EDM_LOGE(MODULE_HID_DDK, "hidDevice is null");
125 return HID_DDK_INVALID_PARAMETER;
126 }
127
128 if (hidEventProperties == nullptr) {
129 EDM_LOGE(MODULE_HID_DDK, "hidEventProperties is null");
130 return HID_DDK_INVALID_PARAMETER;
131 }
132
133 if (hidDevice->propLength > MAX_HID_DEVICE_PROP_LEN) {
134 EDM_LOGE(MODULE_HID_DDK, "properties length is out of range");
135 return HID_DDK_INVALID_PARAMETER;
136 }
137
138 if (hidEventProperties->hidEventTypes.length > MAX_HID_EVENT_TYPES_LEN) {
139 EDM_LOGE(MODULE_HID_DDK, "hidEventTypes length is out of range");
140 return HID_DDK_INVALID_PARAMETER;
141 }
142
143 if (hidEventProperties->hidKeys.length > MAX_HID_KEYS_LEN) {
144 EDM_LOGE(MODULE_HID_DDK, "hidKeys length is out of range");
145 return HID_DDK_INVALID_PARAMETER;
146 }
147
148 if (hidEventProperties->hidAbs.length > MAX_HID_ABS_LEN) {
149 EDM_LOGE(MODULE_HID_DDK, "hidAbs length is out of range");
150 return HID_DDK_INVALID_PARAMETER;
151 }
152
153 if (hidEventProperties->hidRelBits.length > MAX_HID_REL_BITS_LEN) {
154 EDM_LOGE(MODULE_HID_DDK, "hidRelBits length is out of range");
155 return HID_DDK_INVALID_PARAMETER;
156 }
157
158 if (hidEventProperties->hidMiscellaneous.length > MAX_HID_MISC_EVENT_LEN) {
159 EDM_LOGE(MODULE_HID_DDK, "hidMiscellaneous length is out of range");
160 return HID_DDK_INVALID_PARAMETER;
161 }
162
163 auto tempDevice = ParseHidDevice(hidDevice);
164 auto tempEventProperties = ParseHidEventProperties(hidEventProperties);
165
166 uint32_t deviceId = 0;
167 auto ret = g_ddk->CreateDevice(tempDevice, tempEventProperties, deviceId);
168 if (ret != HID_DDK_SUCCESS) {
169 EDM_LOGE(MODULE_HID_DDK, "create device failed:%{public}d", ret);
170 return ret;
171 }
172 return static_cast<int32_t>(deviceId);
173 }
174
OH_Hid_EmitEvent(int32_t deviceId,const Hid_EmitItem items[],uint16_t length)175 int32_t OH_Hid_EmitEvent(int32_t deviceId, const Hid_EmitItem items[], uint16_t length)
176 {
177 if (!ExtPermissionManager::GetInstance().HasPermission(PERMISSION_NAME)) {
178 EDM_LOGE(MODULE_HID_DDK, "no permission");
179 return HID_DDK_FAILURE;
180 }
181
182 if (Connect() != HID_DDK_SUCCESS) {
183 return HID_DDK_INVALID_OPERATION;
184 }
185
186 if (deviceId < 0) {
187 EDM_LOGE(MODULE_HID_DDK, "device id is invaild");
188 return HID_DDK_INVALID_PARAMETER;
189 }
190
191 if (length > MAX_EMIT_ITEM_NUM) {
192 EDM_LOGE(MODULE_HID_DDK, "items length is out of range");
193 return HID_DDK_INVALID_PARAMETER;
194 }
195
196 if (items == nullptr) {
197 EDM_LOGE(MODULE_HID_DDK, "items is null");
198 return HID_DDK_INVALID_PARAMETER;
199 }
200
201 std::vector<OHOS::HDI::Input::Ddk::V1_0::Hid_EmitItem> itemsTemp;
202 std::transform(items, items + length, std::back_inserter(itemsTemp), [](Hid_EmitItem item) {
203 return *reinterpret_cast<OHOS::HDI::Input::Ddk::V1_0::Hid_EmitItem *>(&item);
204 });
205
206 auto ret = g_ddk->EmitEvent(deviceId, itemsTemp);
207 if (ret != HID_DDK_SUCCESS) {
208 EDM_LOGE(MODULE_HID_DDK, "emit event failed:%{public}d", ret);
209 return ret;
210 }
211 return HID_DDK_SUCCESS;
212 }
213
OH_Hid_DestroyDevice(int32_t deviceId)214 int32_t OH_Hid_DestroyDevice(int32_t deviceId)
215 {
216 if (!ExtPermissionManager::GetInstance().HasPermission(PERMISSION_NAME)) {
217 EDM_LOGE(MODULE_HID_DDK, "no permission");
218 return HID_DDK_FAILURE;
219 }
220
221 if (Connect() != HID_DDK_SUCCESS) {
222 return HID_DDK_INVALID_OPERATION;
223 }
224
225 auto ret = g_ddk->DestroyDevice(deviceId);
226 if (ret != HID_DDK_SUCCESS) {
227 EDM_LOGE(MODULE_HID_DDK, "destroy device failed:%{public}d", ret);
228 return ret;
229 }
230
231 return HID_DDK_SUCCESS;
232 }
233 #ifdef __cplusplus
234 }
235 #endif /* __cplusplus */
236