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 "browser_addon.h"
17
18 #include "browser_proxy.h"
19 #include "cJSON.h"
20 #include "edm_constants.h"
21 #include "edm_log.h"
22 #include "napi_edm_adapter.h"
23 #include "securec.h"
24
25 using namespace OHOS::EDM;
26
Init(napi_env env,napi_value exports)27 napi_value BrowserAddon::Init(napi_env env, napi_value exports)
28 {
29 napi_property_descriptor property[] = {
30 DECLARE_NAPI_FUNCTION("setPolicies", SetPolicies),
31 DECLARE_NAPI_FUNCTION("getPolicies", GetPolicies),
32 DECLARE_NAPI_FUNCTION("setPolicySync", SetPolicy),
33 DECLARE_NAPI_FUNCTION("getPoliciesSync", GetPoliciesSync),
34 DECLARE_NAPI_FUNCTION("setManagedBrowserPolicy", SetManagedBrowserPolicy),
35 DECLARE_NAPI_FUNCTION("getManagedBrowserPolicy", GetManagedBrowserPolicy),
36 DECLARE_NAPI_FUNCTION("getSelfManagedBrowserPolicyVersion", GetSelfManagedBrowserPolicyVersion),
37 DECLARE_NAPI_FUNCTION("getSelfManagedBrowserPolicy", GetSelfManagedBrowserPolicy),
38 };
39 NAPI_CALL(env, napi_define_properties(env, exports, sizeof(property) / sizeof(property[0]), property));
40 return exports;
41 }
42
SetPolicies(napi_env env,napi_callback_info info)43 napi_value BrowserAddon::SetPolicies(napi_env env, napi_callback_info info)
44 {
45 EDMLOGI("NAPI_SetPolicies called");
46 auto asyncCallbackInfo = new (std::nothrow) AsyncBrowserCallbackInfo();
47 if (asyncCallbackInfo == nullptr) {
48 return nullptr;
49 }
50 std::unique_ptr<AsyncBrowserCallbackInfo> callbackPtr{asyncCallbackInfo};
51 napi_value ret = SetPolicyCommon(env, info, asyncCallbackInfo);
52 int32_t errCode = -1;
53 NAPI_CALL(env, napi_get_value_int32(env, ret, &errCode));
54 if (ret == nullptr || errCode != ERR_OK) {
55 return nullptr;
56 }
57 if (asyncCallbackInfo->value != nullptr) {
58 ASSERT_AND_THROW_PARAM_ERROR(env,
59 MatchValueType(env, asyncCallbackInfo->value, napi_function), "Parameter callback error");
60 NAPI_CALL(env,
61 napi_create_reference(env, asyncCallbackInfo->value, NAPI_RETURN_ONE, &asyncCallbackInfo->callback));
62 }
63 napi_value asyncWorkReturn =
64 HandleAsyncWork(env, asyncCallbackInfo, "setPolicies", NativeSetPolicies, NativeVoidCallbackComplete);
65 callbackPtr.release();
66 return asyncWorkReturn;
67 }
68
NativeSetPolicies(napi_env env,void * data)69 void BrowserAddon::NativeSetPolicies(napi_env env, void *data)
70 {
71 EDMLOGI("NAPI_NativeSetPolicies called");
72 if (data == nullptr) {
73 EDMLOGE("data is nullptr");
74 return;
75 }
76 std::string empty;
77 AsyncBrowserCallbackInfo *asyncCallbackInfo = static_cast<AsyncBrowserCallbackInfo *>(data);
78 asyncCallbackInfo->ret = BrowserProxy::GetBrowserProxy()->SetPolicy(asyncCallbackInfo->elementName,
79 asyncCallbackInfo->appId, empty, asyncCallbackInfo->policies);
80 }
81
GetPolicies(napi_env env,napi_callback_info info)82 napi_value BrowserAddon::GetPolicies(napi_env env, napi_callback_info info)
83 {
84 EDMLOGI("NAPI_GetPolicies called");
85 auto asyncCallbackInfo = new (std::nothrow) AsyncBrowserCallbackInfo();
86 if (asyncCallbackInfo == nullptr) {
87 return nullptr;
88 }
89 std::unique_ptr<AsyncBrowserCallbackInfo> callbackPtr{asyncCallbackInfo};
90 napi_value ret = GetPoliciesCommon(env, info, asyncCallbackInfo);
91 int32_t errCode = -1;
92 NAPI_CALL(env, napi_get_value_int32(env, ret, &errCode));
93 if (ret == nullptr || errCode != ERR_OK) {
94 return nullptr;
95 }
96 if (asyncCallbackInfo->value != nullptr) {
97 ASSERT_AND_THROW_PARAM_ERROR(env,
98 MatchValueType(env, asyncCallbackInfo->value, napi_function), "Parameter callback error");
99 NAPI_CALL(env,
100 napi_create_reference(env, asyncCallbackInfo->value, NAPI_RETURN_ONE, &asyncCallbackInfo->callback));
101 }
102 napi_value asyncWorkReturn =
103 HandleAsyncWork(env, asyncCallbackInfo, "getPolicies", NativeGetPolicies, NativeStringCallbackComplete);
104 callbackPtr.release();
105 return asyncWorkReturn;
106 }
107
NativeGetPolicies(napi_env env,void * data)108 void BrowserAddon::NativeGetPolicies(napi_env env, void *data)
109 {
110 EDMLOGI("NativeGetPolicies called");
111 if (data == nullptr) {
112 EDMLOGE("data is nullptr");
113 return;
114 }
115 AsyncBrowserCallbackInfo *asyncCallbackInfo = static_cast<AsyncBrowserCallbackInfo *>(data);
116 asyncCallbackInfo->ret = BrowserProxy::GetBrowserProxy()->GetPolicies(asyncCallbackInfo->elementName,
117 asyncCallbackInfo->appId, asyncCallbackInfo->stringRet);
118 }
119
SetPolicy(napi_env env,napi_callback_info info)120 napi_value BrowserAddon::SetPolicy(napi_env env, napi_callback_info info)
121 {
122 EDMLOGI("NAPI_SetPolicy called");
123 std::string policyValue;
124 auto asyncCallbackInfo = new (std::nothrow) AsyncBrowserCallbackInfo();
125 if (asyncCallbackInfo == nullptr) {
126 return nullptr;
127 }
128 std::unique_ptr<AsyncBrowserCallbackInfo> callbackPtr{asyncCallbackInfo};
129 napi_value ret = SetPolicyCommon(env, info, asyncCallbackInfo);
130 int32_t errCode = -1;
131 NAPI_CALL(env, napi_get_value_int32(env, ret, &errCode));
132 if (ret == nullptr || errCode != ERR_OK) {
133 return nullptr;
134 }
135 ASSERT_AND_THROW_PARAM_ERROR(env,
136 ParseString(env, policyValue, asyncCallbackInfo->value), "Parameter policyValue error");
137
138 int32_t retCode = BrowserProxy::GetBrowserProxy()->SetPolicy(asyncCallbackInfo->elementName,
139 asyncCallbackInfo->appId, asyncCallbackInfo->policies, policyValue);
140 if (FAILED(retCode)) {
141 napi_throw(env, CreateError(env, retCode));
142 }
143 return nullptr;
144 }
145
GetPoliciesSync(napi_env env,napi_callback_info info)146 napi_value BrowserAddon::GetPoliciesSync(napi_env env, napi_callback_info info)
147 {
148 EDMLOGI("NAPI_GetPoliciesSync called");
149 auto asyncCallbackInfo = new (std::nothrow) AsyncBrowserCallbackInfo();
150 if (asyncCallbackInfo == nullptr) {
151 return nullptr;
152 }
153 std::unique_ptr<AsyncBrowserCallbackInfo> callbackPtr{asyncCallbackInfo};
154 napi_value ret = GetPoliciesCommon(env, info, asyncCallbackInfo);
155 int32_t errCode = -1;
156 NAPI_CALL(env, napi_get_value_int32(env, ret, &errCode));
157 if (ret == nullptr || errCode != ERR_OK) {
158 return nullptr;
159 }
160 std::string policies;
161 int32_t retCode = BrowserProxy::GetBrowserProxy()->GetPolicies(asyncCallbackInfo->elementName,
162 asyncCallbackInfo->appId, policies);
163 if (FAILED(retCode)) {
164 napi_throw(env, CreateError(env, retCode));
165 }
166 napi_value res;
167 NAPI_CALL(env, napi_create_string_utf8(env, policies.c_str(), NAPI_AUTO_LENGTH, &res));
168 return res;
169 }
170
SetManagedBrowserPolicy(napi_env env,napi_callback_info info)171 napi_value BrowserAddon::SetManagedBrowserPolicy(napi_env env, napi_callback_info info)
172 {
173 EDMLOGI("BrowserAddon::SetManagedBrowserPolicy start");
174 auto convertPolicyValue = [](napi_env env, napi_value argv, MessageParcel &data,
175 const AddonMethodSign &methodSign) {
176 std::string policyValue;
177 if (!ParseString(env, policyValue, argv)) {
178 return false;
179 }
180 if (policyValue.empty()) {
181 return true;
182 }
183 cJSON* root = cJSON_Parse(policyValue.c_str());
184 if (root == nullptr) {
185 return false;
186 }
187 cJSON_Delete(root);
188 data.WriteString(policyValue);
189 return true;
190 };
191 AddonMethodSign addonMethodSign;
192 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::STRING,
193 EdmAddonCommonType::STRING, EdmAddonCommonType::CUSTOM};
194 addonMethodSign.argsConvert = {nullptr, nullptr, nullptr, convertPolicyValue};
195 addonMethodSign.methodAttribute = MethodAttribute::HANDLE;
196 AdapterAddonData adapterAddonData{};
197 if (JsObjectToData(env, info, addonMethodSign, &adapterAddonData) == nullptr) {
198 napi_throw(env, CreateError(env, EdmReturnErrCode::SYSTEM_ABNORMALLY));
199 return nullptr;
200 }
201 int32_t ret = BrowserProxy::GetBrowserProxy()->SetManagedBrowserPolicy(adapterAddonData.data);
202 if (FAILED(ret)) {
203 napi_throw(env, CreateError(env, ret));
204 }
205 return nullptr;
206 }
207
GetManagedBrowserPolicy(napi_env env,napi_callback_info info)208 napi_value BrowserAddon::GetManagedBrowserPolicy(napi_env env, napi_callback_info info)
209 {
210 EDMLOGI("BrowserAddon::GetManagedBrowserPolicy start");
211 auto convertBundleNameWithType = [](napi_env env, napi_value argv, MessageParcel &data,
212 const AddonMethodSign &methodSign) {
213 std::string bundleName;
214 if (!ParseString(env, bundleName, argv)) {
215 return false;
216 }
217 data.WriteString(EdmConstants::Browser::GET_MANAGED_BROWSER_FILE_DATA);
218 data.WriteString(bundleName);
219 return true;
220 };
221 AddonMethodSign addonMethodSign;
222 addonMethodSign.apiVersionTag = WITHOUT_PERMISSION_TAG;
223 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::CUSTOM};
224 addonMethodSign.argsConvert = {nullptr, convertBundleNameWithType};
225 AdapterAddonData adapterAddonData{};
226 napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
227 if (result == nullptr) {
228 napi_throw(env, CreateError(env, EdmReturnErrCode::SYSTEM_ABNORMALLY));
229 return nullptr;
230 }
231 int32_t size = -1;
232 void* data = nullptr;
233 int32_t ret = BrowserProxy::GetBrowserProxy()->GetManagedBrowserPolicy(adapterAddonData.data, &data, size);
234 if (FAILED(ret)) {
235 napi_throw(env, CreateError(env, ret));
236 return nullptr;
237 }
238 return CreateArrayBuffer(env, data, size);
239 }
240
GetSelfManagedBrowserPolicyVersion(napi_env env,napi_callback_info info)241 napi_value BrowserAddon::GetSelfManagedBrowserPolicyVersion(napi_env env, napi_callback_info info)
242 {
243 EDMLOGI("BrowserAddon::GetManagedBrowserPolicy start");
244 int32_t version = -1;
245 int32_t ret = BrowserProxy::GetBrowserProxy()->GetSelfManagedBrowserPolicyVersion(version);
246 if (FAILED(ret)) {
247 napi_throw(env, CreateError(env, ret));
248 return nullptr;
249 }
250 if (version == -1) {
251 napi_throw(env, CreateError(env, EdmReturnErrCode::SYSTEM_ABNORMALLY));
252 return nullptr;
253 }
254 napi_value versionRet = nullptr;
255 NAPI_CALL(env, napi_create_string_utf8(env, std::to_string(version).c_str(), NAPI_AUTO_LENGTH, &versionRet));
256 return versionRet;
257 }
258
GetSelfManagedBrowserPolicy(napi_env env,napi_callback_info info)259 napi_value BrowserAddon::GetSelfManagedBrowserPolicy(napi_env env, napi_callback_info info)
260 {
261 EDMLOGI("BrowserAddon::GetSelfManagedBrowserPolicy start");
262 int32_t size = -1;
263 void* data = nullptr;
264 int32_t ret = BrowserProxy::GetBrowserProxy()->GetSelfManagedBrowserPolicy(&data, size);
265 if (FAILED(ret)) {
266 napi_throw(env, CreateError(env, ret));
267 return nullptr;
268 }
269 return CreateArrayBuffer(env, data, size);
270 }
271
SetPolicyCommon(napi_env env,napi_callback_info info,AsyncBrowserCallbackInfo * callbackInfo)272 napi_value BrowserAddon::SetPolicyCommon(napi_env env, napi_callback_info info, AsyncBrowserCallbackInfo* callbackInfo)
273 {
274 size_t argc = ARGS_SIZE_FOUR;
275 napi_value argv[ARGS_SIZE_FOUR] = {nullptr};
276 napi_value thisArg = nullptr;
277 void *data = nullptr;
278 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
279 ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_THREE, "Parameter count error");
280 bool matchFlag = MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object) &&
281 MatchValueType(env, argv[ARR_INDEX_ONE], napi_string) && MatchValueType(env, argv[ARR_INDEX_TWO], napi_string);
282
283 ASSERT_AND_THROW_PARAM_ERROR(env, matchFlag, "parameter type error");
284 ASSERT_AND_THROW_PARAM_ERROR(env, ParseElementName(env, callbackInfo->elementName, argv[ARR_INDEX_ZERO]),
285 "element name param error");
286 ASSERT_AND_THROW_PARAM_ERROR(env, ParseString(env, callbackInfo->appId, argv[ARR_INDEX_ONE]),
287 "Parameter appId error");
288 ASSERT_AND_THROW_PARAM_ERROR(env, ParseString(env, callbackInfo->policies, argv[ARR_INDEX_TWO]),
289 "Parameter policyName error");
290
291 EDMLOGD(
292 "setBrowserPolicy: elementName.bundlename %{public}s, "
293 "elementName.abilityname:%{public}s",
294 callbackInfo->elementName.GetBundleName().c_str(),
295 callbackInfo->elementName.GetAbilityName().c_str());
296
297 if (argc > ARGS_SIZE_THREE) {
298 callbackInfo->value = argv[ARR_INDEX_THREE];
299 }
300
301 napi_value ret;
302 NAPI_CALL(env, napi_create_int32(env, ERR_OK, &ret));
303 return ret;
304 }
305
GetPoliciesCommon(napi_env env,napi_callback_info info,AsyncBrowserCallbackInfo * asyncCallbackInfo)306 napi_value BrowserAddon::GetPoliciesCommon(napi_env env, napi_callback_info info,
307 AsyncBrowserCallbackInfo* asyncCallbackInfo)
308 {
309 size_t argc = ARGS_SIZE_THREE;
310 napi_value argv[ARGS_SIZE_THREE] = {nullptr};
311 napi_value thisArg = nullptr;
312 void *data = nullptr;
313 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
314 ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_TWO, "Parameter count error");
315 ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object), "admin type error");
316 ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_ONE], napi_string), "appId type error");
317
318 ASSERT_AND_THROW_PARAM_ERROR(env, ParseElementName(env, asyncCallbackInfo->elementName, argv[ARR_INDEX_ZERO]),
319 "Parameter want error");
320 ASSERT_AND_THROW_PARAM_ERROR(env, ParseString(env, asyncCallbackInfo->appId, argv[ARR_INDEX_ONE]),
321 "Parameter appId error");
322 EDMLOGD(
323 "GetPolicies::asyncCallbackInfo->elementName.bundlename %{public}s, "
324 "asyncCallbackInfo->abilityname:%{public}s",
325 asyncCallbackInfo->elementName.GetBundleName().c_str(),
326 asyncCallbackInfo->elementName.GetAbilityName().c_str());
327
328 if (argc > ARGS_SIZE_TWO) {
329 ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_TWO], napi_function),
330 "callback type error");
331 asyncCallbackInfo->value = argv[ARR_INDEX_TWO];
332 }
333 napi_value ret;
334 NAPI_CALL(env, napi_create_int32(env, ERR_OK, &ret));
335 return ret;
336 }
337
CreateArrayBuffer(napi_env env,void * data,int32_t size)338 napi_value BrowserAddon::CreateArrayBuffer(napi_env env, void* data, int32_t size)
339 {
340 if (data == nullptr) {
341 EDMLOGE("BrowserAddon::CreateArrayBuffer data null");
342 napi_throw(env, CreateError(env, EdmReturnErrCode::SYSTEM_ABNORMALLY));
343 return nullptr;
344 }
345 if (size < 0) {
346 EDMLOGE("BrowserAddon::CreateArrayBuffer size error.size:%{public}d", size);
347 napi_throw(env, CreateError(env, EdmReturnErrCode::SYSTEM_ABNORMALLY));
348 return nullptr;
349 }
350 napi_value result = nullptr;
351 void* arrayBufferData = nullptr;
352 NAPI_CALL(env, napi_create_arraybuffer(env, size, &arrayBufferData, &result));
353 if (arrayBufferData == nullptr) {
354 EDMLOGE("BrowserAddon::CreateArrayBuffer arrayBufferData null");
355 napi_throw(env, CreateError(env, EdmReturnErrCode::SYSTEM_ABNORMALLY));
356 free(data);
357 data = nullptr;
358 return nullptr;
359 }
360 errno_t cpRet = memcpy_s(arrayBufferData, size, data, size);
361 if (cpRet != EOK) {
362 EDMLOGE("BrowserAddon::CreateArrayBuffer memcpy_s fail.errcode:%{public}d, size:%{public}d", cpRet, size);
363 napi_throw(env, CreateError(env, EdmReturnErrCode::SYSTEM_ABNORMALLY));
364 free(data);
365 data = nullptr;
366 return nullptr;
367 }
368 free(data);
369 data = nullptr;
370 return result;
371 }
372
373 static napi_module g_browserModule = {
374 .nm_version = 1,
375 .nm_flags = 0,
376 .nm_filename = nullptr,
377 .nm_register_func = BrowserAddon::Init,
378 .nm_modname = "enterprise.browser",
379 .nm_priv = ((void *)0),
380 .reserved = {0},
381 };
382
BrowserRegister()383 extern "C" __attribute__((constructor)) void BrowserRegister()
384 {
385 napi_module_register(&g_browserModule);
386 }