1 /*
2  * Copyright (c) 2023-2024 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_common.h"
23 
24 using namespace OHOS::EDM;
25 
Init(napi_env env,napi_value exports)26 napi_value BluetoothManagerAddon::Init(napi_env env, napi_value exports)
27 {
28     napi_property_descriptor property[] = {
29         DECLARE_NAPI_FUNCTION("getBluetoothInfo", GetBluetoothInfo),
30         DECLARE_NAPI_FUNCTION("setBluetoothDisabled", SetBluetoothDisabled),
31         DECLARE_NAPI_FUNCTION("isBluetoothDisabled", IsBluetoothDisabled),
32         DECLARE_NAPI_FUNCTION("addAllowedBluetoothDevices", AddAllowedBluetoothDevices),
33         DECLARE_NAPI_FUNCTION("getAllowedBluetoothDevices", GetAllowedBluetoothDevices),
34         DECLARE_NAPI_FUNCTION("removeAllowedBluetoothDevices", RemoveAllowedBluetoothDevices),
35     };
36     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(property) / sizeof(property[0]), property));
37     return exports;
38 }
39 
GetBluetoothInfo(napi_env env,napi_callback_info info)40 napi_value BluetoothManagerAddon::GetBluetoothInfo(napi_env env, napi_callback_info info)
41 {
42     EDMLOGI("NAPI_GetBluetoothInfo called");
43     size_t argc = ARGS_SIZE_ONE;
44     napi_value argv[ARGS_SIZE_ONE] = { nullptr };
45     napi_value thisArg = nullptr;
46     void* data = nullptr;
47     OHOS::AppExecFwk::ElementName elementName;
48     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
49     ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_ONE, "parameter count error");
50     ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object), "parameter type error");
51     ASSERT_AND_THROW_PARAM_ERROR(env, ParseElementName(env, elementName, argv[ARR_INDEX_ZERO]),
52         "element name param error");
53     EDMLOGD(
54         "EnableAdmin: elementName.bundlename %{public}s, "
55         "elementName.abilityname:%{public}s",
56         elementName.GetBundleName().c_str(),
57         elementName.GetAbilityName().c_str());
58     BluetoothInfo bluetoothInfo;
59     auto bluetoothManagerProxy = BluetoothManagerProxy::GetBluetoothManagerProxy();
60     int32_t ret = bluetoothManagerProxy->GetBluetoothInfo(elementName, bluetoothInfo);
61     if (FAILED(ret)) {
62         napi_throw(env, CreateError(env, ret));
63         return nullptr;
64     }
65     return ConvertBluetoothInfo(env, bluetoothInfo);
66 }
67 
ConvertBluetoothInfo(napi_env env,BluetoothInfo & bluetoothInfo)68 napi_value BluetoothManagerAddon::ConvertBluetoothInfo(napi_env env, BluetoothInfo &bluetoothInfo)
69 {
70     napi_value objBluetoothInfo = nullptr;
71     NAPI_CALL(env, napi_create_object(env, &objBluetoothInfo));
72     napi_value napi_name;
73     napi_value napi_state;
74     napi_value napi_connectionState;
75     NAPI_CALL(env, napi_create_string_utf8(env, bluetoothInfo.name.c_str(), bluetoothInfo.name.size(), &napi_name));
76     NAPI_CALL(env, napi_create_int32(env, bluetoothInfo.state, &napi_state));
77     NAPI_CALL(env, napi_create_int32(env, bluetoothInfo.connectionState, &napi_connectionState));
78     NAPI_CALL(env, napi_set_named_property(env, objBluetoothInfo, "name", napi_name));
79     NAPI_CALL(env, napi_set_named_property(env, objBluetoothInfo, "state", napi_state));
80     NAPI_CALL(env, napi_set_named_property(env, objBluetoothInfo, "connectionState", napi_connectionState));
81     return objBluetoothInfo;
82 }
83 
SetBluetoothDisabled(napi_env env,napi_callback_info info)84 napi_value BluetoothManagerAddon::SetBluetoothDisabled(napi_env env, napi_callback_info info)
85 {
86     EDMLOGI("NAPI_SetBluetoothDisabled called");
87     size_t argc = ARGS_SIZE_TWO;
88     napi_value argv[ARGS_SIZE_TWO] = { nullptr };
89     napi_value thisArg = nullptr;
90     void* data = nullptr;
91     OHOS::AppExecFwk::ElementName elementName;
92     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
93 
94     ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_TWO, "parameter count error");
95     ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object),
96         "The first parameter must be want.");
97     ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_ONE], napi_boolean),
98         "The second parameter must be bool.");
99 
100     bool ret = ParseElementName(env, elementName, argv[ARR_INDEX_ZERO]);
101     ASSERT_AND_THROW_PARAM_ERROR(env, ret, "param 'admin' parse error");
102     EDMLOGD("EnableAdmin: elementName.bundlename %{public}s, elementName.abilityname:%{public}s",
103         elementName.GetBundleName().c_str(), elementName.GetAbilityName().c_str());
104 
105     bool disabled = false;
106     ret = ParseBool(env, disabled, argv[ARR_INDEX_ONE]);
107     ASSERT_AND_THROW_PARAM_ERROR(env, ret, "param 'disabled' parse error");
108 
109     auto bluetoothManagerProxy = BluetoothManagerProxy::GetBluetoothManagerProxy();
110     int32_t retCode = bluetoothManagerProxy->SetBluetoothDisabled(elementName, disabled);
111     if (FAILED(retCode)) {
112         napi_throw(env, CreateError(env, retCode));
113     }
114     return nullptr;
115 }
116 
IsBluetoothDisabled(napi_env env,napi_callback_info info)117 napi_value BluetoothManagerAddon::IsBluetoothDisabled(napi_env env, napi_callback_info info)
118 {
119     EDMLOGI("NAPI_IsBluetoothDisabled called");
120     size_t argc = ARGS_SIZE_ONE;
121     napi_value argv[ARGS_SIZE_ONE] = { nullptr };
122     napi_value thisArg = nullptr;
123     void* data = nullptr;
124     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
125     ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_ONE, "parameter count error");
126     bool hasAdmin = false;
127     OHOS::AppExecFwk::ElementName elementName;
128     ASSERT_AND_THROW_PARAM_ERROR(env, CheckGetPolicyAdminParam(env, argv[ARR_INDEX_ZERO], hasAdmin, elementName),
129         "param admin need be null or want");
130     bool isDisabled = false;
131     int32_t ret = ERR_OK;
132     if (hasAdmin) {
133         ret = BluetoothManagerProxy::GetBluetoothManagerProxy()->IsBluetoothDisabled(&elementName, isDisabled);
134     } else {
135         ret = BluetoothManagerProxy::GetBluetoothManagerProxy()->IsBluetoothDisabled(nullptr, isDisabled);
136     }
137     if (FAILED(ret)) {
138         napi_throw(env, CreateError(env, ret));
139         return nullptr;
140     }
141     napi_value result = nullptr;
142     napi_get_boolean(env, isDisabled, &result);
143     return result;
144 }
145 
AddAllowedBluetoothDevices(napi_env env,napi_callback_info info)146 napi_value BluetoothManagerAddon::AddAllowedBluetoothDevices(napi_env env, napi_callback_info info)
147 {
148     EDMLOGI("NAPI_AddAllowedBluetoothDevices called");
149     return AddOrRemoveBluetoothDevices(env, info, "AddAllowedBluetoothDevices");
150 }
151 
GetAllowedBluetoothDevices(napi_env env,napi_callback_info info)152 napi_value BluetoothManagerAddon::GetAllowedBluetoothDevices(napi_env env, napi_callback_info info)
153 {
154     EDMLOGI("NAPI_GetAllowedBluetoothDevices called");
155     size_t argc = ARGS_SIZE_ONE;
156     napi_value argv[ARGS_SIZE_ONE] = { nullptr };
157     napi_value thisArg = nullptr;
158     void *data = nullptr;
159     bool hasAdmin = false;
160     OHOS::AppExecFwk::ElementName elementName;
161     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
162     ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_ONE, "parameter count error");
163     ASSERT_AND_THROW_PARAM_ERROR(env, CheckGetPolicyAdminParam(env, argv[ARR_INDEX_ZERO], hasAdmin, elementName),
164         "param admin need be null or want");
165     EDMLOGD("EnableAdmin: elementName.bundlename %{public}s, "
166         "elementName.abilityname:%{public}s",
167         elementName.GetBundleName().c_str(), elementName.GetAbilityName().c_str());
168     auto bluetoothManagerProxy = BluetoothManagerProxy::GetBluetoothManagerProxy();
169     std::vector<std::string> deviceIds;
170     int32_t retCode = ERR_OK;
171     if (hasAdmin) {
172         retCode = bluetoothManagerProxy->GetAllowedBluetoothDevices(&elementName, deviceIds);
173     } else {
174         retCode = bluetoothManagerProxy->GetAllowedBluetoothDevices(nullptr, deviceIds);
175     }
176     if (FAILED(retCode)) {
177         napi_throw(env, CreateError(env, retCode));
178         return nullptr;
179     }
180     napi_value result = nullptr;
181     napi_create_array(env, &result);
182     for (size_t i = 0; i < deviceIds.size(); i++) {
183         napi_value allowedDevices = nullptr;
184         napi_create_string_utf8(env, deviceIds[i].c_str(), NAPI_AUTO_LENGTH, &allowedDevices);
185         napi_set_element(env, result, i, allowedDevices);
186     }
187     return result;
188 }
189 
RemoveAllowedBluetoothDevices(napi_env env,napi_callback_info info)190 napi_value BluetoothManagerAddon::RemoveAllowedBluetoothDevices(napi_env env, napi_callback_info info)
191 {
192     EDMLOGI("NAPI_RemoveAllowedBluetoothDevices called");
193     return AddOrRemoveBluetoothDevices(env, info, "RemoveAllowedBluetoothDevices");
194 }
195 
AddOrRemoveBluetoothDevices(napi_env env,napi_callback_info info,std::string function)196 napi_value BluetoothManagerAddon::AddOrRemoveBluetoothDevices(napi_env env, napi_callback_info info,
197     std::string function)
198 {
199     size_t argc = ARGS_SIZE_TWO;
200     napi_value argv[ARGS_SIZE_TWO] = { nullptr };
201     napi_value thisArg = nullptr;
202     void *data = nullptr;
203     OHOS::AppExecFwk::ElementName elementName;
204     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
205 
206     ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_TWO, "parameter count error");
207     ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object), "parameter type error");
208     bool ret = ParseElementName(env, elementName, argv[ARR_INDEX_ZERO]);
209     ASSERT_AND_THROW_PARAM_ERROR(env, ret, "param 'admin' parse error");
210     EDMLOGD("EnableAdmin: elementName.bundlename %{public}s, elementName.abilityname:%{public}s",
211         elementName.GetBundleName().c_str(), elementName.GetAbilityName().c_str());
212 
213     auto bluetoothManagerProxy = BluetoothManagerProxy::GetBluetoothManagerProxy();
214     std::vector<std::string> deviceIds;
215     ret = ParseStringArray(env, deviceIds, argv[ARR_INDEX_ONE]);
216     ASSERT_AND_THROW_PARAM_ERROR(env, ret, "param 'deviceIds' parse error");
217     int32_t retCode = ERR_OK;
218     if (function == "AddAllowedBluetoothDevices") {
219         retCode = bluetoothManagerProxy->AddAllowedBluetoothDevices(elementName, deviceIds);
220     } else {
221         retCode = bluetoothManagerProxy->RemoveAllowedBluetoothDevices(elementName, deviceIds);
222     }
223     if (FAILED(retCode)) {
224         napi_throw(env, CreateError(env, retCode));
225     }
226     return nullptr;
227 }
228 
229 static napi_module g_bluetoothModule = {
230     .nm_version = 1,
231     .nm_flags = 0,
232     .nm_filename = nullptr,
233     .nm_register_func = BluetoothManagerAddon::Init,
234     .nm_modname = "enterprise.bluetoothManager",
235     .nm_priv = ((void *)0),
236     .reserved = {0},
237 };
238 
BluetoothManagerRegister()239 extern "C" __attribute__((constructor)) void BluetoothManagerRegister()
240 {
241     napi_module_register(&g_bluetoothModule);
242 }
243