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 return nullptr;
166 }
167 napi_value res;
168 NAPI_CALL(env, napi_create_string_utf8(env, policies.c_str(), NAPI_AUTO_LENGTH, &res));
169 return res;
170 }
171
SetManagedBrowserPolicy(napi_env env,napi_callback_info info)172 napi_value BrowserAddon::SetManagedBrowserPolicy(napi_env env, napi_callback_info info)
173 {
174 EDMLOGI("BrowserAddon::SetManagedBrowserPolicy start");
175 auto convertPolicyValue = [](napi_env env, napi_value argv, MessageParcel &data,
176 const AddonMethodSign &methodSign) {
177 std::string policyValue;
178 if (!ParseString(env, policyValue, argv)) {
179 return false;
180 }
181 if (policyValue.empty()) {
182 return true;
183 }
184 cJSON* root = cJSON_Parse(policyValue.c_str());
185 if (root == nullptr) {
186 return false;
187 }
188 cJSON_Delete(root);
189 data.WriteString(policyValue);
190 return true;
191 };
192 AddonMethodSign addonMethodSign;
193 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::STRING,
194 EdmAddonCommonType::STRING, EdmAddonCommonType::CUSTOM};
195 addonMethodSign.argsConvert = {nullptr, nullptr, nullptr, convertPolicyValue};
196 addonMethodSign.methodAttribute = MethodAttribute::HANDLE;
197 AdapterAddonData adapterAddonData{};
198 if (JsObjectToData(env, info, addonMethodSign, &adapterAddonData) == nullptr) {
199 napi_throw(env, CreateError(env, EdmReturnErrCode::SYSTEM_ABNORMALLY));
200 return nullptr;
201 }
202 int32_t ret = BrowserProxy::GetBrowserProxy()->SetManagedBrowserPolicy(adapterAddonData.data);
203 if (FAILED(ret)) {
204 napi_throw(env, CreateError(env, ret));
205 }
206 return nullptr;
207 }
208
GetManagedBrowserPolicy(napi_env env,napi_callback_info info)209 napi_value BrowserAddon::GetManagedBrowserPolicy(napi_env env, napi_callback_info info)
210 {
211 EDMLOGI("BrowserAddon::GetManagedBrowserPolicy start");
212 auto convertBundleNameWithType = [](napi_env env, napi_value argv, MessageParcel &data,
213 const AddonMethodSign &methodSign) {
214 std::string bundleName;
215 if (!ParseString(env, bundleName, argv)) {
216 return false;
217 }
218 data.WriteString(EdmConstants::Browser::GET_MANAGED_BROWSER_FILE_DATA);
219 data.WriteString(bundleName);
220 return true;
221 };
222 AddonMethodSign addonMethodSign;
223 addonMethodSign.apiVersionTag = WITHOUT_PERMISSION_TAG;
224 addonMethodSign.argsType = {EdmAddonCommonType::ELEMENT, EdmAddonCommonType::CUSTOM};
225 addonMethodSign.argsConvert = {nullptr, convertBundleNameWithType};
226 AdapterAddonData adapterAddonData{};
227 napi_value result = JsObjectToData(env, info, addonMethodSign, &adapterAddonData);
228 if (result == nullptr) {
229 napi_throw(env, CreateError(env, EdmReturnErrCode::SYSTEM_ABNORMALLY));
230 return nullptr;
231 }
232 int32_t size = -1;
233 void* data = nullptr;
234 int32_t ret = BrowserProxy::GetBrowserProxy()->GetManagedBrowserPolicy(adapterAddonData.data, &data, size);
235 if (FAILED(ret)) {
236 napi_throw(env, CreateError(env, ret));
237 return nullptr;
238 }
239 return CreateArrayBuffer(env, data, size);
240 }
241
GetSelfManagedBrowserPolicyVersion(napi_env env,napi_callback_info info)242 napi_value BrowserAddon::GetSelfManagedBrowserPolicyVersion(napi_env env, napi_callback_info info)
243 {
244 EDMLOGI("BrowserAddon::GetManagedBrowserPolicy start");
245 int32_t version = -1;
246 int32_t ret = BrowserProxy::GetBrowserProxy()->GetSelfManagedBrowserPolicyVersion(version);
247 if (FAILED(ret)) {
248 napi_throw(env, CreateError(env, ret));
249 return nullptr;
250 }
251 if (version == -1) {
252 napi_throw(env, CreateError(env, EdmReturnErrCode::SYSTEM_ABNORMALLY));
253 return nullptr;
254 }
255 napi_value versionRet = nullptr;
256 NAPI_CALL(env, napi_create_string_utf8(env, std::to_string(version).c_str(), NAPI_AUTO_LENGTH, &versionRet));
257 return versionRet;
258 }
259
GetSelfManagedBrowserPolicy(napi_env env,napi_callback_info info)260 napi_value BrowserAddon::GetSelfManagedBrowserPolicy(napi_env env, napi_callback_info info)
261 {
262 EDMLOGI("BrowserAddon::GetSelfManagedBrowserPolicy start");
263 int32_t size = -1;
264 void* data = nullptr;
265 int32_t ret = BrowserProxy::GetBrowserProxy()->GetSelfManagedBrowserPolicy(&data, size);
266 if (FAILED(ret)) {
267 napi_throw(env, CreateError(env, ret));
268 return nullptr;
269 }
270 return CreateArrayBuffer(env, data, size);
271 }
272
SetPolicyCommon(napi_env env,napi_callback_info info,AsyncBrowserCallbackInfo * callbackInfo)273 napi_value BrowserAddon::SetPolicyCommon(napi_env env, napi_callback_info info, AsyncBrowserCallbackInfo* callbackInfo)
274 {
275 size_t argc = ARGS_SIZE_FOUR;
276 napi_value argv[ARGS_SIZE_FOUR] = {nullptr};
277 napi_value thisArg = nullptr;
278 void *data = nullptr;
279 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
280 ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_THREE, "Parameter count error");
281 bool matchFlag = MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object) &&
282 MatchValueType(env, argv[ARR_INDEX_ONE], napi_string) && MatchValueType(env, argv[ARR_INDEX_TWO], napi_string);
283
284 ASSERT_AND_THROW_PARAM_ERROR(env, matchFlag, "parameter type error");
285 ASSERT_AND_THROW_PARAM_ERROR(env, ParseElementName(env, callbackInfo->elementName, argv[ARR_INDEX_ZERO]),
286 "element name param error");
287 ASSERT_AND_THROW_PARAM_ERROR(env, ParseString(env, callbackInfo->appId, argv[ARR_INDEX_ONE]),
288 "Parameter appId error");
289 ASSERT_AND_THROW_PARAM_ERROR(env, ParseString(env, callbackInfo->policies, argv[ARR_INDEX_TWO]),
290 "Parameter policyName error");
291
292 EDMLOGD(
293 "setBrowserPolicy: elementName.bundlename %{public}s, "
294 "elementName.abilityname:%{public}s",
295 callbackInfo->elementName.GetBundleName().c_str(),
296 callbackInfo->elementName.GetAbilityName().c_str());
297
298 if (argc > ARGS_SIZE_THREE) {
299 callbackInfo->value = argv[ARR_INDEX_THREE];
300 }
301
302 napi_value ret;
303 NAPI_CALL(env, napi_create_int32(env, ERR_OK, &ret));
304 return ret;
305 }
306
GetPoliciesCommon(napi_env env,napi_callback_info info,AsyncBrowserCallbackInfo * asyncCallbackInfo)307 napi_value BrowserAddon::GetPoliciesCommon(napi_env env, napi_callback_info info,
308 AsyncBrowserCallbackInfo* asyncCallbackInfo)
309 {
310 size_t argc = ARGS_SIZE_THREE;
311 napi_value argv[ARGS_SIZE_THREE] = {nullptr};
312 napi_value thisArg = nullptr;
313 void *data = nullptr;
314 NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
315 ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_TWO, "Parameter count error");
316 ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object), "admin type error");
317 ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_ONE], napi_string), "appId type error");
318
319 ASSERT_AND_THROW_PARAM_ERROR(env, ParseElementName(env, asyncCallbackInfo->elementName, argv[ARR_INDEX_ZERO]),
320 "Parameter want error");
321 ASSERT_AND_THROW_PARAM_ERROR(env, ParseString(env, asyncCallbackInfo->appId, argv[ARR_INDEX_ONE]),
322 "Parameter appId error");
323 EDMLOGD(
324 "GetPolicies::asyncCallbackInfo->elementName.bundlename %{public}s, "
325 "asyncCallbackInfo->abilityname:%{public}s",
326 asyncCallbackInfo->elementName.GetBundleName().c_str(),
327 asyncCallbackInfo->elementName.GetAbilityName().c_str());
328
329 if (argc > ARGS_SIZE_TWO) {
330 ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_TWO], napi_function),
331 "callback type error");
332 asyncCallbackInfo->value = argv[ARR_INDEX_TWO];
333 }
334 napi_value ret;
335 NAPI_CALL(env, napi_create_int32(env, ERR_OK, &ret));
336 return ret;
337 }
338
CreateArrayBuffer(napi_env env,void * data,int32_t size)339 napi_value BrowserAddon::CreateArrayBuffer(napi_env env, void* data, int32_t size)
340 {
341 if (data == nullptr) {
342 EDMLOGE("BrowserAddon::CreateArrayBuffer data null");
343 napi_throw(env, CreateError(env, EdmReturnErrCode::SYSTEM_ABNORMALLY));
344 return nullptr;
345 }
346 if (size < 0) {
347 EDMLOGE("BrowserAddon::CreateArrayBuffer size error.size:%{public}d", size);
348 napi_throw(env, CreateError(env, EdmReturnErrCode::SYSTEM_ABNORMALLY));
349 return nullptr;
350 }
351 napi_value result = nullptr;
352 void* arrayBufferData = nullptr;
353 NAPI_CALL(env, napi_create_arraybuffer(env, size, &arrayBufferData, &result));
354 if (arrayBufferData == nullptr) {
355 EDMLOGE("BrowserAddon::CreateArrayBuffer arrayBufferData null");
356 napi_throw(env, CreateError(env, EdmReturnErrCode::SYSTEM_ABNORMALLY));
357 free(data);
358 data = nullptr;
359 return nullptr;
360 }
361 errno_t cpRet = memcpy_s(arrayBufferData, size, data, size);
362 if (cpRet != EOK) {
363 EDMLOGE("BrowserAddon::CreateArrayBuffer memcpy_s fail.errcode:%{public}d, size:%{public}d", cpRet, size);
364 napi_throw(env, CreateError(env, EdmReturnErrCode::SYSTEM_ABNORMALLY));
365 free(data);
366 data = nullptr;
367 return nullptr;
368 }
369 free(data);
370 data = nullptr;
371 return result;
372 }
373
374 static napi_module g_browserModule = {
375 .nm_version = 1,
376 .nm_flags = 0,
377 .nm_filename = nullptr,
378 .nm_register_func = BrowserAddon::Init,
379 .nm_modname = "enterprise.browser",
380 .nm_priv = ((void *)0),
381 .reserved = {0},
382 };
383
BrowserRegister()384 extern "C" __attribute__((constructor)) void BrowserRegister()
385 {
386 napi_module_register(&g_browserModule);
387 }