• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "bundle_manager_addon.h"
17 
18 #include <unordered_map>
19 
20 #include "edm_constants.h"
21 #include "edm_log.h"
22 #include "os_account_manager.h"
23 #include "policy_type.h"
24 
25 using namespace OHOS::EDM;
26 
27 static const std::unordered_map<std::string, int32_t> POLICY_TYPE_MAP = {
28     {"AddAllowedInstallBundles", static_cast<int32_t>(PolicyType::ALLOW_INSTALL)},
29     {"AddDisallowedInstallBundles", static_cast<int32_t>(PolicyType::DISALLOW_INSTALL)},
30     {"AddDisallowedUninstallBundles", static_cast<int32_t>(PolicyType::DISALLOW_UNINSTALL)},
31     {"RemoveAllowedInstallBundles", static_cast<int32_t>(PolicyType::ALLOW_INSTALL)},
32     {"RemoveDisallowedInstallBundles", static_cast<int32_t>(PolicyType::DISALLOW_INSTALL)},
33     {"RemoveDisallowedUninstallBundles", static_cast<int32_t>(PolicyType::DISALLOW_UNINSTALL)},
34     {"GetAllowedInstallBundles", static_cast<int32_t>(PolicyType::ALLOW_INSTALL)},
35     {"GetDisallowedInstallBundles", static_cast<int32_t>(PolicyType::DISALLOW_INSTALL)},
36     {"GetDisallowedUninstallBundles", static_cast<int32_t>(PolicyType::DISALLOW_UNINSTALL)},
37 };
38 
Init(napi_env env,napi_value exports)39 napi_value BundleManagerAddon::Init(napi_env env, napi_value exports)
40 {
41     napi_property_descriptor property[] = {
42         DECLARE_NAPI_FUNCTION("addAllowedInstallBundles", AddAllowedInstallBundles),
43         DECLARE_NAPI_FUNCTION("removeAllowedInstallBundles", RemoveAllowedInstallBundles),
44         DECLARE_NAPI_FUNCTION("getAllowedInstallBundles", GetAllowedInstallBundles),
45         DECLARE_NAPI_FUNCTION("addDisallowedInstallBundles", AddDisallowedInstallBundles),
46         DECLARE_NAPI_FUNCTION("removeDisallowedInstallBundles", RemoveDisallowedInstallBundles),
47         DECLARE_NAPI_FUNCTION("getDisallowedInstallBundles", GetDisallowedInstallBundles),
48         DECLARE_NAPI_FUNCTION("addDisallowedUninstallBundles", AddDisallowedUninstallBundles),
49         DECLARE_NAPI_FUNCTION("removeDisallowedUninstallBundles", RemoveDisallowedUninstallBundles),
50         DECLARE_NAPI_FUNCTION("getDisallowedUninstallBundles", GetDisallowedUninstallBundles),
51         DECLARE_NAPI_FUNCTION("uninstall", Uninstall),
52         DECLARE_NAPI_FUNCTION("install", Install),
53         DECLARE_NAPI_FUNCTION("addAllowedInstallBundlesSync", AddAllowedInstallBundlesSync),
54         DECLARE_NAPI_FUNCTION("removeAllowedInstallBundlesSync", RemoveAllowedInstallBundlesSync),
55         DECLARE_NAPI_FUNCTION("getAllowedInstallBundlesSync", GetAllowedInstallBundlesSync),
56         DECLARE_NAPI_FUNCTION("addDisallowedInstallBundlesSync", AddDisallowedInstallBundlesSync),
57         DECLARE_NAPI_FUNCTION("removeDisallowedInstallBundlesSync", RemoveDisallowedInstallBundlesSync),
58         DECLARE_NAPI_FUNCTION("getDisallowedInstallBundlesSync", GetDisallowedInstallBundlesSync),
59         DECLARE_NAPI_FUNCTION("addDisallowedUninstallBundlesSync", AddDisallowedUninstallBundlesSync),
60         DECLARE_NAPI_FUNCTION("removeDisallowedUninstallBundlesSync", RemoveDisallowedUninstallBundlesSync),
61         DECLARE_NAPI_FUNCTION("getDisallowedUninstallBundlesSync", GetDisallowedUninstallBundlesSync),
62     };
63     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(property) / sizeof(property[0]), property));
64     return exports;
65 }
66 
GetAllowedInstallBundles(napi_env env,napi_callback_info info)67 napi_value BundleManagerAddon::GetAllowedInstallBundles(napi_env env, napi_callback_info info)
68 {
69     EDMLOGI("NAPI_GetAllowedInstallBundles called");
70     return GetAllowedOrDisallowedInstallBundles(env, info, "GetAllowedInstallBundles", NativeGetBundlesByPolicyType);
71 }
72 
GetDisallowedInstallBundles(napi_env env,napi_callback_info info)73 napi_value BundleManagerAddon::GetDisallowedInstallBundles(napi_env env, napi_callback_info info)
74 {
75     EDMLOGI("NAPI_GetDisallowedInstallBundles called");
76     return GetAllowedOrDisallowedInstallBundles(env, info, "GetDisallowedInstallBundles", NativeGetBundlesByPolicyType);
77 }
78 
GetDisallowedUninstallBundles(napi_env env,napi_callback_info info)79 napi_value BundleManagerAddon::GetDisallowedUninstallBundles(napi_env env, napi_callback_info info)
80 {
81     EDMLOGI("NAPI_GetDisallowedUninstallBundles called");
82     return GetAllowedOrDisallowedInstallBundles(env, info, "GetDisallowedUninstallBundles",
83         NativeGetBundlesByPolicyType);
84 }
85 
Uninstall(napi_env env,napi_callback_info info)86 napi_value BundleManagerAddon::Uninstall(napi_env env, napi_callback_info info)
87 {
88     EDMLOGI("NAPI_Uninstall called");
89     size_t argc = ARGS_SIZE_FIVE;
90     napi_value argv[ARGS_SIZE_FIVE] = {nullptr};
91     napi_value thisArg = nullptr;
92     void *data = nullptr;
93     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
94 
95     auto asyncCallbackInfo = new (std::nothrow) AsyncUninstallCallbackInfo();
96     if (asyncCallbackInfo == nullptr) {
97         return nullptr;
98     }
99     std::unique_ptr<AsyncUninstallCallbackInfo> callbackPtr{asyncCallbackInfo};
100     if (!CheckAndParseUninstallParamType(env, argc, argv, asyncCallbackInfo)) {
101         return nullptr;
102     }
103 
104     napi_value asyncWorkReturn =
105         HandleAsyncWork(env, asyncCallbackInfo, "NativeUninstall", NativeUninstall, NativeUninstallCallbackComplete);
106     callbackPtr.release();
107     return asyncWorkReturn;
108 }
109 
NativeUninstall(napi_env env,void * data)110 void BundleManagerAddon::NativeUninstall(napi_env env, void *data)
111 {
112     EDMLOGI("NAPI_NativeGetBundlesByPolicyType called");
113     if (data == nullptr) {
114         EDMLOGE("data is nullptr");
115         return;
116     }
117     AsyncUninstallCallbackInfo *asyncCallbackInfo = static_cast<AsyncUninstallCallbackInfo *>(data);
118     auto proxy = BundleManagerProxy::GetBundleManagerProxy();
119     if (proxy == nullptr) {
120         EDMLOGE("can not get BundleManagerProxy");
121         return;
122     }
123 
124     asyncCallbackInfo->ret = proxy->Uninstall(asyncCallbackInfo->elementName, asyncCallbackInfo->bundleName,
125         asyncCallbackInfo->userId, asyncCallbackInfo->isKeepData, asyncCallbackInfo->errMessage);
126 }
127 
Install(napi_env env,napi_callback_info info)128 napi_value BundleManagerAddon::Install(napi_env env, napi_callback_info info)
129 {
130 #ifdef BUNDLE_FRAMEWORK_EDM_ENABLE
131     EDMLOGI("NAPI_Install called");
132     size_t argc = ARGS_SIZE_FOUR;
133     napi_value argv[ARGS_SIZE_FOUR] = {nullptr};
134     napi_value thisArg = nullptr;
135     void *data = nullptr;
136     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
137 
138     auto asyncCallbackInfo = new (std::nothrow) AsyncInstallCallbackInfo();
139     if (asyncCallbackInfo == nullptr) {
140         return nullptr;
141     }
142     std::unique_ptr<AsyncInstallCallbackInfo> callbackPtr{asyncCallbackInfo};
143     ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_TWO, "Parameter count error");
144     if (!CheckAndParseInstallParamType(env, argc, argv, asyncCallbackInfo)) {
145         return nullptr;
146     }
147 
148     napi_value asyncWorkReturn =
149         HandleAsyncWork(env, asyncCallbackInfo, "NativeInstall", NativeInstall, NativeVoidCallbackComplete);
150     callbackPtr.release();
151     return asyncWorkReturn;
152 #else
153     EDMLOGW("BundleManagerAddon::Install Unsupported Capabilities.");
154     napi_throw(env, CreateError(env, EdmReturnErrCode::INTERFACE_UNSUPPORTED));
155     return nullptr;
156 #endif
157 }
158 
NativeInstall(napi_env env,void * data)159 void BundleManagerAddon::NativeInstall(napi_env env, void *data)
160 {
161 #ifdef BUNDLE_FRAMEWORK_EDM_ENABLE
162     EDMLOGI("NAPI_NativeInstall called");
163     if (data == nullptr) {
164         EDMLOGE("data is nullptr");
165         return;
166     }
167     AsyncInstallCallbackInfo *asyncCallbackInfo = static_cast<AsyncInstallCallbackInfo *>(data);
168     auto proxy = BundleManagerProxy::GetBundleManagerProxy();
169     if (proxy == nullptr) {
170         EDMLOGE("can not get BundleManagerProxy");
171         return;
172     }
173 
174     asyncCallbackInfo->ret = proxy->Install(asyncCallbackInfo->elementName, asyncCallbackInfo->hapFilePaths,
175         asyncCallbackInfo->installParam, asyncCallbackInfo->innerCodeMsg);
176     EDMLOGI("NAPI_NativeInstall asyncCallbackInfo->ret : %{public}d", asyncCallbackInfo->ret);
177 #endif
178 }
179 
NativeUninstallCallbackComplete(napi_env env,napi_status status,void * data)180 void BundleManagerAddon::NativeUninstallCallbackComplete(napi_env env, napi_status status, void *data)
181 {
182     if (data == nullptr) {
183         EDMLOGE("data is nullptr");
184         return;
185     }
186     AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
187     napi_value error = nullptr;
188     if (asyncCallbackInfo->callback == nullptr) {
189         EDMLOGD("asyncCallbackInfo->deferred != nullptr");
190         if (asyncCallbackInfo->ret == ERR_OK) {
191             napi_get_null(env, &error);
192             napi_resolve_deferred(env, asyncCallbackInfo->deferred, error);
193         } else {
194             if (asyncCallbackInfo->ret == EdmReturnErrCode::PARAM_ERROR) {
195                 napi_reject_deferred(env, asyncCallbackInfo->deferred,
196                     CreateError(env, asyncCallbackInfo->ret, asyncCallbackInfo->errMessage));
197             } else {
198                 napi_reject_deferred(env, asyncCallbackInfo->deferred, CreateError(env, asyncCallbackInfo->ret));
199             }
200         }
201     } else {
202         if (asyncCallbackInfo->ret == ERR_OK) {
203             napi_get_null(env, &error);
204         } else {
205             if (asyncCallbackInfo->ret == EdmReturnErrCode::PARAM_ERROR) {
206                 error = CreateError(env, asyncCallbackInfo->ret, asyncCallbackInfo->errMessage);
207             } else {
208                 error = CreateError(env, asyncCallbackInfo->ret);
209             }
210         }
211         napi_value callback = nullptr;
212         napi_value result = nullptr;
213         napi_get_reference_value(env, asyncCallbackInfo->callback, &callback);
214         napi_call_function(env, nullptr, callback, ARGS_SIZE_ONE, &error, &result);
215         napi_delete_reference(env, asyncCallbackInfo->callback);
216     }
217     napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
218     delete asyncCallbackInfo;
219 }
220 
CheckAndParseUninstallParamType(napi_env env,size_t argc,napi_value * argv,AsyncUninstallCallbackInfo * asyncCallbackInfo)221 bool BundleManagerAddon::CheckAndParseUninstallParamType(napi_env env, size_t argc, napi_value *argv,
222     AsyncUninstallCallbackInfo *asyncCallbackInfo)
223 {
224     ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_TWO, "Parameter count error");
225     ASSERT_AND_THROW_PARAM_ERROR(env, ParseElementName(env, asyncCallbackInfo->elementName, argv[ARR_INDEX_ZERO]),
226         "Parameter want error");
227     ASSERT_AND_THROW_PARAM_ERROR(env, ParseString(env, asyncCallbackInfo->bundleName, argv[ARR_INDEX_ONE]),
228         "Parameter bundle name error");
229     AccountSA::OsAccountManager::GetOsAccountLocalIdFromProcess(asyncCallbackInfo->userId);
230     if (argc == ARGS_SIZE_TWO) {
231         return true;
232     }
233     bool hasCallback = argc <= ARGS_SIZE_FIVE ? MatchValueType(env, argv[argc - 1], napi_function) :
234                                                 MatchValueType(env, argv[ARR_INDEX_FOUR], napi_function);
235     if (hasCallback) {
236         ASSERT_AND_THROW_PARAM_ERROR(env, ParseCallback(env, asyncCallbackInfo->callback,
237             argc <= ARGS_SIZE_FIVE ? argv[argc - 1] : argv[ARR_INDEX_FOUR]), "Parameter callback error");
238         switch (argc) {
239             case ARGS_SIZE_THREE:
240                 break;
241             case ARGS_SIZE_FOUR:
242                 if (MatchValueType(env, argv[ARR_INDEX_TWO], napi_number)) {
243                     ASSERT_AND_THROW_PARAM_ERROR(env, ParseInt(env, asyncCallbackInfo->userId, argv[ARR_INDEX_TWO]),
244                         "Parameter userId error");
245                 } else if (MatchValueType(env, argv[ARR_INDEX_TWO], napi_boolean)) {
246                     ASSERT_AND_THROW_PARAM_ERROR(env, ParseBool(env, asyncCallbackInfo->isKeepData,
247                         argv[ARR_INDEX_TWO]), "Parameter isKeepData error");
248                 } else {
249                     ASSERT_AND_THROW_PARAM_ERROR(env, false, "Parameter three type error");
250                 }
251                 break;
252             default:
253                 ASSERT_AND_THROW_PARAM_ERROR(env, ParseInt(env, asyncCallbackInfo->userId, argv[ARR_INDEX_TWO]),
254                     "Parameter userId error");
255                 ASSERT_AND_THROW_PARAM_ERROR(env, ParseBool(env, asyncCallbackInfo->isKeepData, argv[ARR_INDEX_THREE]),
256                     "Parameter isKeepData error");
257         }
258         return true;
259     }
260     if (argc == ARGS_SIZE_THREE) {
261         if (!ParseInt(env, asyncCallbackInfo->userId, argv[ARR_INDEX_TWO])) {
262             AccountSA::OsAccountManager::GetOsAccountLocalIdFromProcess(asyncCallbackInfo->userId);
263             ParseBool(env, asyncCallbackInfo->isKeepData, argv[ARR_INDEX_TWO]);
264         }
265         return true;
266     }
267     if (!ParseInt(env, asyncCallbackInfo->userId, argv[ARR_INDEX_TWO])) {
268         AccountSA::OsAccountManager::GetOsAccountLocalIdFromProcess(asyncCallbackInfo->userId);
269     }
270     ParseBool(env, asyncCallbackInfo->isKeepData, argv[ARR_INDEX_THREE]);
271     return true;
272 }
273 
274 #ifdef BUNDLE_FRAMEWORK_EDM_ENABLE
jsObjectToInstallParam(napi_env env,napi_value object,OHOS::AppExecFwk::InstallParam & installParam)275 bool BundleManagerAddon::jsObjectToInstallParam(napi_env env, napi_value object,
276     OHOS::AppExecFwk::InstallParam &installParam)
277 {
278     int32_t installFlag = 0;
279     if (!JsObjectToInt(env, object, "userId", false, installParam.userId) ||
280         !JsObjectToInt(env, object, "installFlag", false, installFlag)) {
281         return false;
282     }
283     bool hasProperty = false;
284     if (napi_has_named_property(env, object, "userId", &hasProperty) == napi_ok && !hasProperty) {
285         AccountSA::OsAccountManager::GetOsAccountLocalIdFromProcess(installParam.userId);
286     }
287     if ((installFlag != static_cast<int32_t>(OHOS::AppExecFwk::InstallFlag::NORMAL)) &&
288         (installFlag != static_cast<int32_t>(OHOS::AppExecFwk::InstallFlag::REPLACE_EXISTING)) &&
289         (installFlag != static_cast<int32_t>(OHOS::AppExecFwk::InstallFlag::FREE_INSTALL))) {
290         EDMLOGE("invalid installFlag param");
291         return false;
292     }
293     installParam.installFlag = static_cast<OHOS::AppExecFwk::InstallFlag>(installFlag);
294     return true;
295 }
296 
CheckAndParseInstallParamType(napi_env env,size_t argc,napi_value * argv,AsyncInstallCallbackInfo * asyncCallbackInfo)297 bool BundleManagerAddon::CheckAndParseInstallParamType(napi_env env, size_t argc, napi_value *argv,
298     AsyncInstallCallbackInfo *asyncCallbackInfo)
299 {
300     ASSERT_AND_THROW_PARAM_ERROR(env, ParseElementName(env, asyncCallbackInfo->elementName, argv[ARR_INDEX_ZERO]),
301         "Parameter want error");
302     ASSERT_AND_THROW_PARAM_ERROR(env, ParseStringArray(env, asyncCallbackInfo->hapFilePaths, argv[ARR_INDEX_ONE]),
303         "Parameter bundleFilePaths error");
304     if (argc == ARGS_SIZE_TWO) {
305         return true;
306     }
307     bool hasCallback = argc <= ARGS_SIZE_FOUR ? MatchValueType(env, argv[argc - 1], napi_function) :
308                                                 MatchValueType(env, argv[ARR_INDEX_THREE], napi_function);
309     if (hasCallback) {
310         ASSERT_AND_THROW_PARAM_ERROR(env,
311             ParseCallback(env, asyncCallbackInfo->callback,
312                 argc <= ARGS_SIZE_FOUR ? argv[argc - 1] : argv[ARGS_SIZE_THREE]),
313             "Parameter callback error");
314         EDMLOGI("CheckAndParseInstallParamType ParseCallback success");
315         if (argc == ARGS_SIZE_FOUR) {
316             ASSERT_AND_THROW_PARAM_ERROR(env,
317                 jsObjectToInstallParam(env, argv[ARR_INDEX_TWO], asyncCallbackInfo->installParam),
318                 "installParam param error");
319         }
320         return true;
321     }
322     ASSERT_AND_THROW_PARAM_ERROR(env, jsObjectToInstallParam(env, argv[ARR_INDEX_TWO], asyncCallbackInfo->installParam),
323         "installParam param error");
324     return true;
325 }
326 #endif
327 
GetAllowedOrDisallowedInstallBundles(napi_env env,napi_callback_info info,const std::string & workName,napi_async_execute_callback execute)328 napi_value BundleManagerAddon::GetAllowedOrDisallowedInstallBundles(napi_env env, napi_callback_info info,
329     const std::string &workName, napi_async_execute_callback execute)
330 {
331     size_t argc = ARGS_SIZE_THREE;
332     napi_value argv[ARGS_SIZE_THREE] = {nullptr};
333     napi_value thisArg = nullptr;
334     void *data = nullptr;
335     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
336     bool hasCallback = false;
337     bool hasUserId = false;
338     auto asyncCallbackInfo = new (std::nothrow) AsyncBundlesCallbackInfo();
339     if (asyncCallbackInfo == nullptr) {
340         return nullptr;
341     }
342     std::unique_ptr<AsyncBundlesCallbackInfo> callbackPtr{asyncCallbackInfo};
343     ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_ONE, "Parameter count error");
344     ASSERT_AND_THROW_PARAM_ERROR(env, CheckAdminWithUserIdParamType(env, argc, argv, hasCallback, hasUserId),
345         "Parameter type error");
346     ASSERT_AND_THROW_PARAM_ERROR(env, ParseElementName(env, asyncCallbackInfo->elementName, argv[ARR_INDEX_ZERO]),
347         "Parameter want error");
348 
349     EDMLOGD("GetInstallBundles bundlename %{public}s, abilityname:%{public}s",
350         asyncCallbackInfo->elementName.GetBundleName().c_str(),
351         asyncCallbackInfo->elementName.GetAbilityName().c_str());
352     if (hasUserId) {
353         ASSERT_AND_THROW_PARAM_ERROR(env, ParseInt(env, asyncCallbackInfo->userId, argv[ARR_INDEX_ONE]),
354             "Parameter user id error");
355     } else {
356         AccountSA::OsAccountManager::GetOsAccountLocalIdFromProcess(asyncCallbackInfo->userId);
357     }
358     if (hasCallback) {
359         ASSERT_AND_THROW_PARAM_ERROR(env,
360             ParseCallback(env, asyncCallbackInfo->callback,
361                 argc <= ARR_INDEX_THREE ? argv[argc - 1] : argv[ARR_INDEX_TWO]),
362             "Parameter callback error");
363     }
364     InitCallbackInfoPolicyType(workName, asyncCallbackInfo);
365     EDMLOGI("GetInstallBundles::%{public}s policyType = %{public}d", workName.c_str(), asyncCallbackInfo->policyType);
366     napi_value asyncWorkReturn =
367         HandleAsyncWork(env, asyncCallbackInfo, workName, execute, NativeArrayStringCallbackComplete);
368     callbackPtr.release();
369     return asyncWorkReturn;
370 }
371 
InitCallbackInfoPolicyType(const std::string & workName,AsyncBundlesCallbackInfo * callbackInfo)372 void BundleManagerAddon::InitCallbackInfoPolicyType(const std::string &workName, AsyncBundlesCallbackInfo *callbackInfo)
373 {
374     auto iter = POLICY_TYPE_MAP.find(workName);
375     if (iter != POLICY_TYPE_MAP.end()) {
376         callbackInfo->policyType = iter->second;
377     } else {
378         EDMLOGI("policy type map get error");
379         callbackInfo->policyType = static_cast<int32_t>(PolicyType::INVALID_TYPE);
380     }
381 }
382 
NativeGetBundlesByPolicyType(napi_env env,void * data)383 void BundleManagerAddon::NativeGetBundlesByPolicyType(napi_env env, void *data)
384 {
385     EDMLOGI("NAPI_NativeGetBundlesByPolicyType called");
386     if (data == nullptr) {
387         EDMLOGE("data is nullptr");
388         return;
389     }
390     AsyncBundlesCallbackInfo *asyncCallbackInfo = static_cast<AsyncBundlesCallbackInfo *>(data);
391     auto proxy = BundleManagerProxy::GetBundleManagerProxy();
392     if (proxy == nullptr) {
393         EDMLOGE("can not get BundleManagerProxy");
394         return;
395     }
396 
397     asyncCallbackInfo->ret = proxy->GetBundlesByPolicyType(asyncCallbackInfo->elementName, asyncCallbackInfo->userId,
398         asyncCallbackInfo->arrayStringRet, asyncCallbackInfo->policyType);
399 }
400 
AddAllowedInstallBundles(napi_env env,napi_callback_info info)401 napi_value BundleManagerAddon::AddAllowedInstallBundles(napi_env env, napi_callback_info info)
402 {
403     return AddOrRemoveInstallBundles(env, info, "AddAllowedInstallBundles", NativeAddBundlesByPolicyType);
404 }
405 
AddDisallowedInstallBundles(napi_env env,napi_callback_info info)406 napi_value BundleManagerAddon::AddDisallowedInstallBundles(napi_env env, napi_callback_info info)
407 {
408     return AddOrRemoveInstallBundles(env, info, "AddDisallowedInstallBundles", NativeAddBundlesByPolicyType);
409 }
410 
AddDisallowedUninstallBundles(napi_env env,napi_callback_info info)411 napi_value BundleManagerAddon::AddDisallowedUninstallBundles(napi_env env, napi_callback_info info)
412 {
413     return AddOrRemoveInstallBundles(env, info, "AddDisallowedUninstallBundles", NativeAddBundlesByPolicyType);
414 }
415 
RemoveAllowedInstallBundles(napi_env env,napi_callback_info info)416 napi_value BundleManagerAddon::RemoveAllowedInstallBundles(napi_env env, napi_callback_info info)
417 {
418     return AddOrRemoveInstallBundles(env, info, "RemoveAllowedInstallBundles", NativeRemoveBundlesByPolicyType);
419 }
420 
RemoveDisallowedInstallBundles(napi_env env,napi_callback_info info)421 napi_value BundleManagerAddon::RemoveDisallowedInstallBundles(napi_env env, napi_callback_info info)
422 {
423     return AddOrRemoveInstallBundles(env, info, "RemoveDisallowedInstallBundles", NativeRemoveBundlesByPolicyType);
424 }
425 
RemoveDisallowedUninstallBundles(napi_env env,napi_callback_info info)426 napi_value BundleManagerAddon::RemoveDisallowedUninstallBundles(napi_env env, napi_callback_info info)
427 {
428     return AddOrRemoveInstallBundles(env, info, "RemoveDisallowedUninstallBundles", NativeRemoveBundlesByPolicyType);
429 }
430 
CheckAddInstallBundlesParamType(napi_env env,size_t argc,napi_value * argv,bool & hasCallback,bool & hasUserId)431 bool BundleManagerAddon::CheckAddInstallBundlesParamType(napi_env env, size_t argc, napi_value *argv, bool &hasCallback,
432     bool &hasUserId)
433 {
434     if (!MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object) ||
435         !MatchValueType(env, argv[ARR_INDEX_ONE], napi_object)) {
436         EDMLOGE("CheckAddInstallBundlesParamType admin or array type check failed");
437         return false;
438     }
439     EDMLOGI("CheckAddInstallBundlesParamType argc = %{public}zu", argc);
440     if (argc == ARGS_SIZE_TWO) {
441         hasCallback = false;
442         hasUserId = false;
443         EDMLOGI("hasCallback = false; hasUserId = false;");
444         return true;
445     }
446 
447     if (argc == ARGS_SIZE_THREE) {
448         if (MatchValueType(env, argv[ARR_INDEX_TWO], napi_function)) {
449             hasCallback = true;
450             hasUserId = false;
451             EDMLOGI("hasCallback = true; hasUserId = false;");
452             return true;
453         } else {
454             hasCallback = false;
455             hasUserId = true;
456             EDMLOGI("hasCallback = false;  hasUserId = true;");
457             return MatchValueType(env, argv[ARR_INDEX_TWO], napi_number);
458         }
459     }
460     hasCallback = true;
461     hasUserId = true;
462     EDMLOGI("hasCallback = true; hasUserId = true;");
463     return MatchValueType(env, argv[ARR_INDEX_TWO], napi_number) &&
464         MatchValueType(env, argv[ARR_INDEX_THREE], napi_function);
465 }
466 
AddOrRemoveInstallBundles(napi_env env,napi_callback_info info,const std::string & workName,napi_async_execute_callback execute)467 napi_value BundleManagerAddon::AddOrRemoveInstallBundles(napi_env env, napi_callback_info info,
468     const std::string &workName, napi_async_execute_callback execute)
469 {
470     size_t argc = ARGS_SIZE_FOUR;
471     napi_value argv[ARGS_SIZE_FOUR] = {nullptr};
472     napi_value thisArg = nullptr;
473     void *data = nullptr;
474     bool hasCallback = false;
475     bool hasUserId = false;
476     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
477     auto asyncCallbackInfo = new (std::nothrow) AsyncBundlesCallbackInfo();
478     if (asyncCallbackInfo == nullptr) {
479         return nullptr;
480     }
481     std::unique_ptr<AsyncBundlesCallbackInfo> callbackPtr{asyncCallbackInfo};
482     ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_TWO, "Parameter count error");
483     ASSERT_AND_THROW_PARAM_ERROR(env, CheckAddInstallBundlesParamType(env, argc, argv, hasCallback, hasUserId),
484         "Parameter type error");
485     ASSERT_AND_THROW_PARAM_ERROR(env, ParseElementName(env, asyncCallbackInfo->elementName, argv[ARR_INDEX_ZERO]),
486         "Parameter want error");
487     ASSERT_AND_THROW_PARAM_ERROR(env, ParseStringArray(env, asyncCallbackInfo->bundles, argv[ARR_INDEX_ONE]),
488         "Parameter bundles error");
489     ASSERT_AND_THROW_PARAM_ERROR(env, asyncCallbackInfo->bundles.size() <= EdmConstants::APPID_MAX_SIZE,
490         "Parameter bundles too large");
491     EDMLOGD("EnableAdmin::asyncCallbackInfo->elementName.bundlename %{public}s, "
492         "asyncCallbackInfo->abilityname:%{public}s", asyncCallbackInfo->elementName.GetBundleName().c_str(),
493         asyncCallbackInfo->elementName.GetAbilityName().c_str());
494     if (hasUserId) {
495         ASSERT_AND_THROW_PARAM_ERROR(env, ParseInt(env, asyncCallbackInfo->userId, argv[ARR_INDEX_TWO]),
496             "Parameter user id error");
497     } else {
498         AccountSA::OsAccountManager::GetOsAccountLocalIdFromProcess(asyncCallbackInfo->userId);
499     }
500     if (hasCallback) {
501         ASSERT_AND_THROW_PARAM_ERROR(env, ParseCallback(env, asyncCallbackInfo->callback,
502             argc <= ARGS_SIZE_FOUR ? argv[argc - 1] : argv[ARR_INDEX_THREE]), "Parameter callback error");
503     }
504     InitCallbackInfoPolicyType(workName, asyncCallbackInfo);
505     EDMLOGI("AddOrRemoveInstallBundles::%{public}s policyType = %{public}d", workName.c_str(),
506         asyncCallbackInfo->policyType);
507     napi_value asyncWorkReturn = HandleAsyncWork(env, asyncCallbackInfo, workName, execute, NativeVoidCallbackComplete);
508     callbackPtr.release();
509     return asyncWorkReturn;
510 }
511 
NativeRemoveBundlesByPolicyType(napi_env env,void * data)512 void BundleManagerAddon::NativeRemoveBundlesByPolicyType(napi_env env, void *data)
513 {
514     EDMLOGI("NativeRemoveBundlesByPolicyType called");
515     if (data == nullptr) {
516         EDMLOGE("data is nullptr");
517         return;
518     }
519     AsyncBundlesCallbackInfo *asyncCallbackInfo = static_cast<AsyncBundlesCallbackInfo *>(data);
520     auto bundleManagerProxy = BundleManagerProxy::GetBundleManagerProxy();
521     if (bundleManagerProxy == nullptr) {
522         EDMLOGE("can not get BundleManagerProxy");
523         return;
524     }
525     asyncCallbackInfo->ret = bundleManagerProxy->RemoveBundlesByPolicyType(asyncCallbackInfo->elementName,
526         asyncCallbackInfo->bundles, asyncCallbackInfo->userId, asyncCallbackInfo->policyType);
527 }
528 
NativeAddBundlesByPolicyType(napi_env env,void * data)529 void BundleManagerAddon::NativeAddBundlesByPolicyType(napi_env env, void *data)
530 {
531     EDMLOGI("NAPI_NativeAddBundlesByPolicyType called");
532     if (data == nullptr) {
533         EDMLOGE("data is nullptr");
534         return;
535     }
536     AsyncBundlesCallbackInfo *asyncCallbackInfo = static_cast<AsyncBundlesCallbackInfo *>(data);
537     auto bundleManagerProxy = BundleManagerProxy::GetBundleManagerProxy();
538     if (bundleManagerProxy == nullptr) {
539         EDMLOGE("can not get BundleManagerProxy");
540         return;
541     }
542     asyncCallbackInfo->ret = bundleManagerProxy->AddBundlesByPolicyType(asyncCallbackInfo->elementName,
543         asyncCallbackInfo->bundles, asyncCallbackInfo->userId, asyncCallbackInfo->policyType);
544 }
545 
AddAllowedInstallBundlesSync(napi_env env,napi_callback_info info)546 napi_value BundleManagerAddon::AddAllowedInstallBundlesSync(napi_env env, napi_callback_info info)
547 {
548     EDMLOGI("NAPI_AddAllowedInstallBundlesSync called");
549     return AddOrRemoveInstallBundlesSync(env, info, "AddAllowedInstallBundles", true);
550 }
551 
AddDisallowedInstallBundlesSync(napi_env env,napi_callback_info info)552 napi_value BundleManagerAddon::AddDisallowedInstallBundlesSync(napi_env env, napi_callback_info info)
553 {
554     EDMLOGI("NAPI_AddDisallowedInstallBundlesSync called");
555     return AddOrRemoveInstallBundlesSync(env, info, "AddDisallowedInstallBundles", true);
556 }
557 
AddDisallowedUninstallBundlesSync(napi_env env,napi_callback_info info)558 napi_value BundleManagerAddon::AddDisallowedUninstallBundlesSync(napi_env env, napi_callback_info info)
559 {
560     EDMLOGI("NAPI_AddDisallowedUninstallBundlesSync called");
561     return AddOrRemoveInstallBundlesSync(env, info, "AddDisallowedUninstallBundles", true);
562 }
563 
RemoveAllowedInstallBundlesSync(napi_env env,napi_callback_info info)564 napi_value BundleManagerAddon::RemoveAllowedInstallBundlesSync(napi_env env, napi_callback_info info)
565 {
566     EDMLOGI("NAPI_RemoveAllowedInstallBundlesSync called");
567     return AddOrRemoveInstallBundlesSync(env, info, "RemoveAllowedInstallBundles", false);
568 }
569 
RemoveDisallowedInstallBundlesSync(napi_env env,napi_callback_info info)570 napi_value BundleManagerAddon::RemoveDisallowedInstallBundlesSync(napi_env env, napi_callback_info info)
571 {
572     EDMLOGI("NAPI_RemoveDisallowedInstallBundlesSync called");
573     return AddOrRemoveInstallBundlesSync(env, info, "RemoveDisallowedInstallBundles", false);
574 }
575 
RemoveDisallowedUninstallBundlesSync(napi_env env,napi_callback_info info)576 napi_value BundleManagerAddon::RemoveDisallowedUninstallBundlesSync(napi_env env, napi_callback_info info)
577 {
578     EDMLOGI("NAPI_RemoveDisallowedUninstallBundlesSync called");
579     return AddOrRemoveInstallBundlesSync(env, info, "RemoveDisallowedUninstallBundles", false);
580 }
581 
AddOrRemoveInstallBundlesSync(napi_env env,napi_callback_info info,const std::string & workName,bool isAdd)582 napi_value BundleManagerAddon::AddOrRemoveInstallBundlesSync(napi_env env, napi_callback_info info,
583     const std::string &workName, bool isAdd)
584 {
585     size_t argc = ARGS_SIZE_THREE;
586     napi_value argv[ARGS_SIZE_THREE] = {nullptr};
587     napi_value thisArg = nullptr;
588     void *data = nullptr;
589     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
590 
591     bool hasAccountId = (argc == ARGS_SIZE_THREE);
592     ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_TWO, "parameter count error");
593     ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object), "parameter admin error");
594     ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_ONE], napi_object), "parameter appIds error");
595     OHOS::AppExecFwk::ElementName elementName;
596     ASSERT_AND_THROW_PARAM_ERROR(env, ParseElementName(env, elementName, argv[ARR_INDEX_ZERO]),
597         "parameter admin parse error");
598     std::vector<std::string> appIds;
599     ASSERT_AND_THROW_PARAM_ERROR(env, ParseStringArray(env, appIds, argv[ARR_INDEX_ONE]),
600         "parameter appIds parse error");
601     ASSERT_AND_THROW_PARAM_ERROR(env, appIds.size() <= EdmConstants::APPID_MAX_SIZE,
602         "parameter appIds too large");
603     EDMLOGD("CheckAddOrRemoveInstallBundlesParam: "
604         "elementName.bundleName %{public}s, elementName.abilityName:%{public}s",
605         elementName.GetBundleName().c_str(), elementName.GetAbilityName().c_str());
606     int32_t accountId = 0;
607     if (hasAccountId) {
608         ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_TWO], napi_number),
609             "parameter accountId error");
610         ASSERT_AND_THROW_PARAM_ERROR(env, ParseInt(env, accountId, argv[ARR_INDEX_TWO]),
611             "parameter accountId parse error");
612     } else {
613         AccountSA::OsAccountManager::GetOsAccountLocalIdFromProcess(accountId);
614     }
615     int32_t policyType = 0;
616     InitPolicyType(workName, policyType);
617     EDMLOGI("AddOrRemoveInstallBundlesSync::%{public}s policyType = %{public}d", workName.c_str(), policyType);
618 
619     auto bundleManagerProxy = BundleManagerProxy::GetBundleManagerProxy();
620     if (bundleManagerProxy == nullptr) {
621         EDMLOGE("can not get BundleManagerProxy");
622         return nullptr;
623     }
624     int32_t ret = ERR_OK;
625     if (isAdd) {
626         ret = bundleManagerProxy->AddBundlesByPolicyType(elementName, appIds, accountId, policyType);
627     } else {
628         ret = bundleManagerProxy->RemoveBundlesByPolicyType(elementName, appIds, accountId, policyType);
629     }
630     if (FAILED(ret)) {
631         napi_throw(env, CreateError(env, ret));
632     }
633     return nullptr;
634 }
635 
InitPolicyType(const std::string & workName,int32_t & policyType)636 void BundleManagerAddon::InitPolicyType(const std::string &workName, int32_t &policyType)
637 {
638     auto iter = POLICY_TYPE_MAP.find(workName);
639     if (iter != POLICY_TYPE_MAP.end()) {
640         policyType = iter->second;
641     } else {
642         EDMLOGI("policy type map get error");
643         policyType = static_cast<int32_t>(PolicyType::INVALID_TYPE);
644     }
645 }
646 
GetAllowedInstallBundlesSync(napi_env env,napi_callback_info info)647 napi_value BundleManagerAddon::GetAllowedInstallBundlesSync(napi_env env, napi_callback_info info)
648 {
649     EDMLOGI("NAPI_GetAllowedInstallBundles called");
650     return GetAllowedOrDisallowedInstallBundlesSync(env, info, "GetAllowedInstallBundles");
651 }
652 
GetDisallowedInstallBundlesSync(napi_env env,napi_callback_info info)653 napi_value BundleManagerAddon::GetDisallowedInstallBundlesSync(napi_env env, napi_callback_info info)
654 {
655     EDMLOGI("NAPI_GetDisallowedInstallBundles called");
656     return GetAllowedOrDisallowedInstallBundlesSync(env, info, "GetDisallowedInstallBundles");
657 }
658 
GetDisallowedUninstallBundlesSync(napi_env env,napi_callback_info info)659 napi_value BundleManagerAddon::GetDisallowedUninstallBundlesSync(napi_env env, napi_callback_info info)
660 {
661     EDMLOGI("NAPI_GetDisallowedUninstallBundles called");
662     return GetAllowedOrDisallowedInstallBundlesSync(env, info, "GetDisallowedUninstallBundles");
663 }
664 
GetAllowedOrDisallowedInstallBundlesSync(napi_env env,napi_callback_info info,const std::string & workName)665 napi_value BundleManagerAddon::GetAllowedOrDisallowedInstallBundlesSync(napi_env env, napi_callback_info info,
666     const std::string &workName)
667 {
668     EDMLOGI("NAPI_GetAllowedOrDisallowedInstallBundlesSync called");
669     size_t argc = ARGS_SIZE_TWO;
670     napi_value argv[ARGS_SIZE_TWO] = {nullptr};
671     napi_value thisArg = nullptr;
672     void *data = nullptr;
673     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
674     bool hasAccountId = (argc == ARGS_SIZE_TWO);
675     ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_ONE, "parameter count error");
676     ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object), "parameter admin error");
677     OHOS::AppExecFwk::ElementName elementName;
678     ASSERT_AND_THROW_PARAM_ERROR(env, ParseElementName(env, elementName, argv[ARR_INDEX_ZERO]),
679         "parameter admin parse error");
680     EDMLOGD("GetAllowedOrDisallowedInstallBundlesSync: "
681         "elementName.bundleName %{public}s, elementName.abilityName:%{public}s",
682         elementName.GetBundleName().c_str(), elementName.GetAbilityName().c_str());
683     int32_t accountId = 0;
684     if (hasAccountId) {
685         ASSERT_AND_THROW_PARAM_ERROR(env, MatchValueType(env, argv[ARR_INDEX_ONE], napi_number),
686             "parameter accountId error");
687         ASSERT_AND_THROW_PARAM_ERROR(env, ParseInt(env, accountId, argv[ARR_INDEX_ONE]),
688             "parameter accountId parse error");
689     } else {
690         AccountSA::OsAccountManager::GetOsAccountLocalIdFromProcess(accountId);
691     }
692     int32_t policyType = 0;
693     InitPolicyType(workName, policyType);
694     EDMLOGI("GetAllowedOrDisallowedInstallBundlesSync::%{public}s "
695         "policyType = %{public}d", workName.c_str(), policyType);
696 
697     auto bundleManagerProxy = BundleManagerProxy::GetBundleManagerProxy();
698     if (bundleManagerProxy == nullptr) {
699         EDMLOGE("can not get BundleManagerProxy");
700         return nullptr;
701     }
702     std::vector<std::string> appIds;
703     int32_t ret = bundleManagerProxy->GetBundlesByPolicyType(elementName, accountId, appIds, policyType);
704     if (FAILED(ret)) {
705         napi_throw(env, CreateError(env, ret));
706     }
707     napi_value result = nullptr;
708     napi_create_array(env, &result);
709     ConvertStringVectorToJS(env, appIds, result);
710     return result;
711 }
712 
713 static napi_module g_bundleManagerModule = {
714     .nm_version = 1,
715     .nm_flags = 0,
716     .nm_filename = nullptr,
717     .nm_register_func = BundleManagerAddon::Init,
718     .nm_modname = "enterprise.bundleManager",
719     .nm_priv = ((void *)0),
720     .reserved = {0},
721 };
722 
BundleManagerRegister()723 extern "C" __attribute__((constructor)) void BundleManagerRegister()
724 {
725     napi_module_register(&g_bundleManagerModule);
726 }