1 /*
2 * Copyright (c) 2023-2025 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 "bluetooth_manager_addon.h"
17
18 #include "edm_constants.h"
19 #include "edm_log.h"
20 #include "errors.h"
21 #include "js_native_api.h"
22 #include "napi_edm_adapter.h"
23 #include "napi_edm_common.h"
24
25 using namespace OHOS::EDM;
26
Init(napi_env env,napi_value exports)27 napi_value BluetoothManagerAddon::Init(napi_env env, napi_value exports)
28 {
29 napi_value nProtocol = nullptr;
30 NAPI_CALL(env, napi_create_object(env, &nProtocol));
31 CreateProtocolObject(env, nProtocol);
32
33 napi_property_descriptor property[] = {
34 DECLARE_NAPI_FUNCTION("getBluetoothInfo", GetBluetoothInfo),
35 DECLARE_NAPI_FUNCTION("setBluetoothDisabled", SetBluetoothDisabled),
36 DECLARE_NAPI_FUNCTION("isBluetoothDisabled", IsBluetoothDisabled),
37 DECLARE_NAPI_FUNCTION("addAllowedBluetoothDevices", AddAllowedBluetoothDevices),
38 DECLARE_NAPI_FUNCTION("getAllowedBluetoothDevices", GetAllowedBluetoothDevices),
39 DECLARE_NAPI_FUNCTION("removeAllowedBluetoothDevices", RemoveAllowedBluetoothDevices),
40 DECLARE_NAPI_FUNCTION("turnOnBluetooth", TurnOnBluetooth),
41 DECLARE_NAPI_FUNCTION("turnOffBluetooth", TurnOffBluetooth),
42 DECLARE_NAPI_FUNCTION("addDisallowedBluetoothDevices", AddDisallowedBluetoothDevices),
43 DECLARE_NAPI_FUNCTION("getDisallowedBluetoothDevices", GetDisallowedBluetoothDevices),
44 DECLARE_NAPI_FUNCTION("removeDisallowedBluetoothDevices", RemoveDisallowedBluetoothDevices),
45 DECLARE_NAPI_FUNCTION("addDisallowedBluetoothProtocols", AddDisallowedBluetoothProtocols),
46 DECLARE_NAPI_FUNCTION("getDisallowedBluetoothProtocols", GetDisallowedBluetoothProtocols),
47 DECLARE_NAPI_FUNCTION("removeDisallowedBluetoothProtocols", RemoveDisallowedBluetoothProtocols),
48
49 DECLARE_NAPI_PROPERTY("Protocol", nProtocol),
50 };
51 NAPI_CALL(env, napi_define_properties(env, exports, sizeof(property) / sizeof(property[0]), property));
52 return exports;
53 }
54
GetBluetoothInfo(napi_env env,napi_callback_info info)55 napi_value BluetoothManagerAddon::GetBluetoothInfo(napi_env env, napi_callback_info info)
56 {
57 EDMLOGI("NAPI_GetBluetoothInfo called");
58 BluetoothInfo bluetoothInfo;
59 AddonMethodSign addonMethodSign;
60 addonMethodSign.name = "GetBluetoothInfo";
61 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT};
62 addonMethodSign.methodAttribute = MethodAttribute::GET;
63 AdapterAddonData adapterAddonData{};
64 napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
65 if (result == nullptr) {
66 return nullptr;
67 }
68 int32_t ret =
69 BluetoothManagerProxy::GetBluetoothManagerProxy()->GetBluetoothInfo(adapterAddonData.data, bluetoothInfo);
70 if (FAILED(ret)) {
71 napi_throw(env, CreateError(env, ret));
72 return nullptr;
73 }
74 return ConvertBluetoothInfo(env, bluetoothInfo);
75 }
76
ConvertBluetoothInfo(napi_env env,BluetoothInfo & bluetoothInfo)77 napi_value BluetoothManagerAddon::ConvertBluetoothInfo(napi_env env, BluetoothInfo &bluetoothInfo)
78 {
79 napi_value objBluetoothInfo = nullptr;
80 NAPI_CALL(env, napi_create_object(env, &objBluetoothInfo));
81 napi_value napi_name;
82 napi_value napi_state;
83 napi_value napi_connectionState;
84 NAPI_CALL(env, napi_create_string_utf8(env, bluetoothInfo.name.c_str(), bluetoothInfo.name.size(), &napi_name));
85 NAPI_CALL(env, napi_create_int32(env, bluetoothInfo.state, &napi_state));
86 NAPI_CALL(env, napi_create_int32(env, bluetoothInfo.connectionState, &napi_connectionState));
87 NAPI_CALL(env, napi_set_named_property(env, objBluetoothInfo, "name", napi_name));
88 NAPI_CALL(env, napi_set_named_property(env, objBluetoothInfo, "state", napi_state));
89 NAPI_CALL(env, napi_set_named_property(env, objBluetoothInfo, "connectionState", napi_connectionState));
90 return objBluetoothInfo;
91 }
92
SetBluetoothDisabled(napi_env env,napi_callback_info info)93 napi_value BluetoothManagerAddon::SetBluetoothDisabled(napi_env env, napi_callback_info info)
94 {
95 EDMLOGI("NAPI_SetBluetoothDisabled called");
96 AddonMethodSign addonMethodSign;
97 addonMethodSign.name = "SetBluetoothDisabled";
98 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::BOOLEAN};
99 addonMethodSign.methodAttribute = MethodAttribute::HANDLE;
100 addonMethodSign.apiVersionTag = EdmConstants::PERMISSION_TAG_VERSION_11;
101 AdapterAddonData adapterAddonData{};
102 napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
103 if (result == nullptr) {
104 return nullptr;
105 }
106 int32_t retCode =
107 BluetoothManagerProxy::GetBluetoothManagerProxy()->SetBluetoothDisabled(adapterAddonData.data);
108 if (FAILED(retCode)) {
109 napi_throw(env, CreateError(env, retCode));
110 }
111 return nullptr;
112 }
113
IsBluetoothDisabled(napi_env env,napi_callback_info info)114 napi_value BluetoothManagerAddon::IsBluetoothDisabled(napi_env env, napi_callback_info info)
115 {
116 EDMLOGI("NAPI_IsBluetoothDisabled called");
117 AddonMethodSign addonMethodSign;
118 addonMethodSign.name = "IsBluetoothDisabled";
119 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT_NULL};
120 addonMethodSign.methodAttribute = MethodAttribute::GET;
121 addonMethodSign.apiVersionTag = EdmConstants::PERMISSION_TAG_VERSION_11;
122 AdapterAddonData adapterAddonData{};
123 if (JsObjectToData(env, info, addonMethodSign, &adapterAddonData) == nullptr) {
124 return nullptr;
125 }
126 bool isDisabled = false;
127 int32_t ret =
128 BluetoothManagerProxy::GetBluetoothManagerProxy()->IsBluetoothDisabled(adapterAddonData.data, isDisabled);
129 if (FAILED(ret)) {
130 napi_throw(env, CreateError(env, ret));
131 return nullptr;
132 }
133 napi_value result = nullptr;
134 NAPI_CALL(env, napi_get_boolean(env, isDisabled, &result));
135 return result;
136 }
137
GetAllowedBluetoothDevices(napi_env env,napi_callback_info info)138 napi_value BluetoothManagerAddon::GetAllowedBluetoothDevices(napi_env env, napi_callback_info info)
139 {
140 EDMLOGI("NAPI_GetAllowedBluetoothDevices called");
141 return GetBluetoothDevices(env, info, EdmInterfaceCode::ALLOWED_BLUETOOTH_DEVICES);
142 }
143
GetDisallowedBluetoothDevices(napi_env env,napi_callback_info info)144 napi_value BluetoothManagerAddon::GetDisallowedBluetoothDevices(napi_env env, napi_callback_info info)
145 {
146 EDMLOGI("NAPI_GetDisallowedBluetoothDevices called");
147 return GetBluetoothDevices(env, info, EdmInterfaceCode::DISALLOWED_BLUETOOTH_DEVICES);
148 }
149
GetBluetoothDevices(napi_env env,napi_callback_info info,EdmInterfaceCode policyCode)150 napi_value BluetoothManagerAddon::GetBluetoothDevices(napi_env env, napi_callback_info info,
151 EdmInterfaceCode policyCode)
152 {
153 AddonMethodSign addonMethodSign;
154 addonMethodSign.name = "GetBluetoothDevices";
155 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT_NULL};
156 addonMethodSign.methodAttribute = MethodAttribute::GET;
157 AdapterAddonData adapterAddonData{};
158 if (JsObjectToData(env, info, addonMethodSign, &adapterAddonData) == nullptr) {
159 return nullptr;
160 }
161 auto bluetoothManagerProxy = BluetoothManagerProxy::GetBluetoothManagerProxy();
162 if (bluetoothManagerProxy == nullptr) {
163 EDMLOGE("can not get bluetoothManagerProxy");
164 return nullptr;
165 }
166 std::vector<std::string> deviceIds;
167 int32_t retCode = bluetoothManagerProxy->GetBluetoothDevices(adapterAddonData.data, deviceIds, policyCode);
168 if (FAILED(retCode)) {
169 napi_throw(env, CreateError(env, retCode));
170 return nullptr;
171 }
172 napi_value result = nullptr;
173 NAPI_CALL(env, napi_create_array(env, &result));
174 for (size_t i = 0; i < deviceIds.size(); i++) {
175 napi_value allowedDevices = nullptr;
176 NAPI_CALL(env, napi_create_string_utf8(env, deviceIds[i].c_str(), NAPI_AUTO_LENGTH, &allowedDevices));
177 NAPI_CALL(env, napi_set_element(env, result, i, allowedDevices));
178 }
179 return result;
180 }
181
AddAllowedBluetoothDevices(napi_env env,napi_callback_info info)182 napi_value BluetoothManagerAddon::AddAllowedBluetoothDevices(napi_env env, napi_callback_info info)
183 {
184 EDMLOGI("NAPI_AddAllowedBluetoothDevices called");
185 return AddOrRemoveBluetoothDevices(env, info, FuncOperateType::SET, EdmInterfaceCode::ALLOWED_BLUETOOTH_DEVICES);
186 }
187
RemoveAllowedBluetoothDevices(napi_env env,napi_callback_info info)188 napi_value BluetoothManagerAddon::RemoveAllowedBluetoothDevices(napi_env env, napi_callback_info info)
189 {
190 EDMLOGI("NAPI_RemoveAllowedBluetoothDevices called");
191 return AddOrRemoveBluetoothDevices(env, info, FuncOperateType::REMOVE,
192 EdmInterfaceCode::ALLOWED_BLUETOOTH_DEVICES);
193 }
194
AddDisallowedBluetoothDevices(napi_env env,napi_callback_info info)195 napi_value BluetoothManagerAddon::AddDisallowedBluetoothDevices(napi_env env, napi_callback_info info)
196 {
197 EDMLOGI("NAPI_AddDisallowedBluetoothDevices called");
198 return AddOrRemoveBluetoothDevices(env, info, FuncOperateType::SET,
199 EdmInterfaceCode::DISALLOWED_BLUETOOTH_DEVICES);
200 }
201
RemoveDisallowedBluetoothDevices(napi_env env,napi_callback_info info)202 napi_value BluetoothManagerAddon::RemoveDisallowedBluetoothDevices(napi_env env, napi_callback_info info)
203 {
204 EDMLOGI("NAPI_RemoveDisallowedBluetoothDevices called");
205 return AddOrRemoveBluetoothDevices(env, info, FuncOperateType::REMOVE,
206 EdmInterfaceCode::DISALLOWED_BLUETOOTH_DEVICES);
207 }
208
AddOrRemoveBluetoothDevices(napi_env env,napi_callback_info info,FuncOperateType operateType,EdmInterfaceCode code)209 napi_value BluetoothManagerAddon::AddOrRemoveBluetoothDevices(napi_env env, napi_callback_info info,
210 FuncOperateType operateType, EdmInterfaceCode code)
211 {
212 AddonMethodSign addonMethodSign;
213 addonMethodSign.name = "AddOrRemoveBluetoothDevices";
214 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::ARRAY_STRING};
215 addonMethodSign.methodAttribute = MethodAttribute::HANDLE;
216 AdapterAddonData adapterAddonData{};
217 if (JsObjectToData(env, info, addonMethodSign, &adapterAddonData) == nullptr) {
218 return nullptr;
219 }
220 int32_t retCode = BluetoothManagerProxy::GetBluetoothManagerProxy()->
221 AddOrRemoveBluetoothDevices(adapterAddonData.data, operateType, code);
222 if (FAILED(retCode)) {
223 napi_throw(env, CreateError(env, retCode));
224 }
225 return nullptr;
226 }
227
TurnOnBluetooth(napi_env env,napi_callback_info info)228 napi_value BluetoothManagerAddon::TurnOnBluetooth(napi_env env, napi_callback_info info)
229 {
230 EDMLOGI("NAPI_TurnOnBluetooth called");
231 return TurnOnOrOffBluetooth(env, info, true);
232 }
233
TurnOffBluetooth(napi_env env,napi_callback_info info)234 napi_value BluetoothManagerAddon::TurnOffBluetooth(napi_env env, napi_callback_info info)
235 {
236 EDMLOGI("NAPI_TurnOffBluetooth called");
237 return TurnOnOrOffBluetooth(env, info, false);
238 }
239
TurnOnOrOffBluetooth(napi_env env,napi_callback_info info,bool isOpen)240 napi_value BluetoothManagerAddon::TurnOnOrOffBluetooth(napi_env env, napi_callback_info info, bool isOpen)
241 {
242 AddonMethodSign addonMethodSign;
243 addonMethodSign.name = "TurnOnOrOffBluetooth";
244 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT};
245 addonMethodSign.methodAttribute = MethodAttribute::HANDLE;
246 AdapterAddonData adapterAddonData{};
247 if (JsObjectToData(env, info, addonMethodSign, &adapterAddonData) == nullptr) {
248 return nullptr;
249 }
250 adapterAddonData.data.WriteBool(isOpen);
251 int32_t retCode = BluetoothManagerProxy::GetBluetoothManagerProxy()->TurnOnOrOffBluetooth(adapterAddonData.data);
252 if (FAILED(retCode)) {
253 napi_throw(env, CreateError(env, retCode));
254 }
255 return nullptr;
256 }
257
AddDisallowedBluetoothProtocols(napi_env env,napi_callback_info info)258 napi_value BluetoothManagerAddon::AddDisallowedBluetoothProtocols(napi_env env, napi_callback_info info)
259 {
260 EDMLOGI("NAPI_AddDisallowedBluetoothProtocols called");
261 return AddOrRemoveDisallowedBluetoothProtocols(env, info, "AddDisallowedBluetoothProtocols");
262 }
263
GetDisallowedBluetoothProtocols(napi_env env,napi_callback_info info)264 napi_value BluetoothManagerAddon::GetDisallowedBluetoothProtocols(napi_env env, napi_callback_info info)
265 {
266 EDMLOGI("NAPI_GetDisallowedBluetoothProtocols called");
267 AddonMethodSign addonMethodSign;
268 addonMethodSign.name = "GetDisallowedBluetoothProtocols";
269 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::USERID};
270 addonMethodSign.argsConvert = {nullptr, nullptr};
271 addonMethodSign.methodAttribute = MethodAttribute::GET;
272 AdapterAddonData adapterAddonData{};
273 if (JsObjectToData(env, info, addonMethodSign, &adapterAddonData) == nullptr) {
274 return nullptr;
275 }
276 std::vector<int32_t> protocols;
277 int32_t retCode = BluetoothManagerProxy::GetBluetoothManagerProxy()->
278 GetDisallowedBluetoothProtocols(adapterAddonData.data, protocols);
279 if (FAILED(retCode)) {
280 napi_throw(env, CreateError(env, retCode));
281 return nullptr;
282 }
283 napi_value jsList = nullptr;
284 NAPI_CALL(env, napi_create_array_with_length(env, protocols.size(), &jsList));
285 for (size_t i = 0; i < protocols.size(); i++) {
286 napi_value item;
287 NAPI_CALL(env, napi_create_int32(env, protocols[i], &item));
288 NAPI_CALL(env, napi_set_element(env, jsList, i, item));
289 }
290 return jsList;
291 }
292
RemoveDisallowedBluetoothProtocols(napi_env env,napi_callback_info info)293 napi_value BluetoothManagerAddon::RemoveDisallowedBluetoothProtocols(napi_env env, napi_callback_info info)
294 {
295 EDMLOGI("NAPI_RemoveDisallowedBluetoothProtocols called");
296 return AddOrRemoveDisallowedBluetoothProtocols(env, info, "RemoveDisallowedBluetoothProtocols");
297 }
298
AddOrRemoveDisallowedBluetoothProtocols(napi_env env,napi_callback_info info,std::string function)299 napi_value BluetoothManagerAddon::AddOrRemoveDisallowedBluetoothProtocols(napi_env env, napi_callback_info info,
300 std::string function)
301 {
302 EDMLOGI("NAPI_AddOrRemoveDisallowedBluetoothProtocols called");
303 auto convertBtProtocol2Data = [](napi_env env, napi_value argv, MessageParcel &data,
304 const AddonMethodSign &methodSign) {
305 std::vector<int32_t> bluetoothProtocols;
306 if (!ParseIntArray(env, bluetoothProtocols, argv)) {
307 EDMLOGE("NAPI_AddOrRemoveDisallowedBluetoothProtocols ParseIntArray fail");
308 return false;
309 }
310 data.WriteInt32Vector(bluetoothProtocols);
311 return true;
312 };
313 AddonMethodSign addonMethodSign;
314 addonMethodSign.name = "AddOrRemoveDisallowedBluetoothProtocols";
315 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::USERID, EdmAddonCommonType::CUSTOM};
316 addonMethodSign.argsConvert = {nullptr, nullptr, convertBtProtocol2Data};
317 addonMethodSign.methodAttribute = MethodAttribute::HANDLE;
318 AdapterAddonData adapterAddonData{};
319 if (JsObjectToData(env, info, addonMethodSign, &adapterAddonData) == nullptr) {
320 return nullptr;
321 }
322 int32_t retCode = BluetoothManagerProxy::GetBluetoothManagerProxy()->
323 AddOrRemoveDisallowedBluetoothProtocols(adapterAddonData.data, function == "AddDisallowedBluetoothProtocols");
324 if (FAILED(retCode)) {
325 napi_throw(env, CreateError(env, retCode));
326 }
327 return nullptr;
328 }
329
CreateProtocolObject(napi_env env,napi_value value)330 void BluetoothManagerAddon::CreateProtocolObject(napi_env env, napi_value value)
331 {
332 napi_value nGatt;
333 NAPI_CALL_RETURN_VOID(env, napi_create_uint32(env, static_cast<uint32_t>(BtProtocol::GATT), &nGatt));
334 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "GATT", nGatt));
335 napi_value nSpp;
336 NAPI_CALL_RETURN_VOID(env, napi_create_uint32(env, static_cast<uint32_t>(BtProtocol::SPP), &nSpp));
337 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "SPP", nSpp));
338 napi_value nOpp;
339 NAPI_CALL_RETURN_VOID(env, napi_create_uint32(env, static_cast<uint32_t>(BtProtocol::OPP), &nOpp));
340 NAPI_CALL_RETURN_VOID(env, napi_set_named_property(env, value, "OPP", nOpp));
341 }
342
343 static napi_module g_bluetoothModule = {
344 .nm_version = 1,
345 .nm_flags = 0,
346 .nm_filename = nullptr,
347 .nm_register_func = BluetoothManagerAddon::Init,
348 .nm_modname = "enterprise.bluetoothManager",
349 .nm_priv = ((void *)0),
350 .reserved = {0},
351 };
352
BluetoothManagerRegister()353 extern "C" __attribute__((constructor)) void BluetoothManagerRegister()
354 {
355 napi_module_register(&g_bluetoothModule);
356 }
357