• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "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     };
54     NAPI_CALL(env, napi_define_properties(env, exports, sizeof(property) / sizeof(property[0]), property));
55     return exports;
56 }
57 
GetAllowedInstallBundles(napi_env env,napi_callback_info info)58 napi_value BundleManagerAddon::GetAllowedInstallBundles(napi_env env, napi_callback_info info)
59 {
60     EDMLOGI("NAPI_GetAllowedInstallBundles called");
61     return GetAllowedOrDisallowedInstallBundles(env, info, "GetAllowedInstallBundles", NativeGetBundlesByPolicyType);
62 }
63 
GetDisallowedInstallBundles(napi_env env,napi_callback_info info)64 napi_value BundleManagerAddon::GetDisallowedInstallBundles(napi_env env, napi_callback_info info)
65 {
66     EDMLOGI("NAPI_GetDisallowedInstallBundles called");
67     return GetAllowedOrDisallowedInstallBundles(env, info, "GetDisallowedInstallBundles", NativeGetBundlesByPolicyType);
68 }
69 
GetDisallowedUninstallBundles(napi_env env,napi_callback_info info)70 napi_value BundleManagerAddon::GetDisallowedUninstallBundles(napi_env env, napi_callback_info info)
71 {
72     EDMLOGI("NAPI_GetDisallowedUninstallBundles called");
73     return GetAllowedOrDisallowedInstallBundles(env, info, "GetDisallowedUninstallBundles",
74         NativeGetBundlesByPolicyType);
75 }
76 
Uninstall(napi_env env,napi_callback_info info)77 napi_value BundleManagerAddon::Uninstall(napi_env env, napi_callback_info info)
78 {
79     EDMLOGI("NAPI_Uninstall called");
80     size_t argc = ARGS_SIZE_FIVE;
81     napi_value argv[ARGS_SIZE_FIVE] = {nullptr};
82     napi_value thisArg = nullptr;
83     void *data = nullptr;
84     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
85 
86     auto asyncCallbackInfo = new (std::nothrow) AsyncUninstallCallbackInfo();
87     if (asyncCallbackInfo == nullptr) {
88         return nullptr;
89     }
90     std::unique_ptr<AsyncUninstallCallbackInfo> callbackPtr{asyncCallbackInfo};
91     if (!CheckAndParseUninstallParamType(env, argc, argv, asyncCallbackInfo)) {
92         return nullptr;
93     }
94 
95     napi_value asyncWorkReturn =
96         HandleAsyncWork(env, asyncCallbackInfo, "NativeUninstall", NativeUninstall, NativeUninstallCallbackComplete);
97     callbackPtr.release();
98     return asyncWorkReturn;
99 }
100 
NativeUninstall(napi_env env,void * data)101 void BundleManagerAddon::NativeUninstall(napi_env env, void *data)
102 {
103     EDMLOGI("NAPI_NativeGetBundlesByPolicyType called");
104     if (data == nullptr) {
105         EDMLOGE("data is nullptr");
106         return;
107     }
108     AsyncUninstallCallbackInfo *asyncCallbackInfo = static_cast<AsyncUninstallCallbackInfo *>(data);
109     auto proxy = BundleManagerProxy::GetBundleManagerProxy();
110     if (proxy == nullptr) {
111         EDMLOGE("can not get BundleManagerProxy");
112         return;
113     }
114 
115     asyncCallbackInfo->ret = proxy->Uninstall(asyncCallbackInfo->elementName, asyncCallbackInfo->bundleName,
116         asyncCallbackInfo->userId, asyncCallbackInfo->isKeepData, asyncCallbackInfo->errMessage);
117 }
118 
Install(napi_env env,napi_callback_info info)119 napi_value BundleManagerAddon::Install(napi_env env, napi_callback_info info)
120 {
121     EDMLOGI("NAPI_Install called");
122     size_t argc = ARGS_SIZE_FOUR;
123     napi_value argv[ARGS_SIZE_FOUR] = {nullptr};
124     napi_value thisArg = nullptr;
125     void *data = nullptr;
126     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
127 
128     auto asyncCallbackInfo = new (std::nothrow) AsyncInstallCallbackInfo();
129     if (asyncCallbackInfo == nullptr) {
130         return nullptr;
131     }
132     std::unique_ptr<AsyncInstallCallbackInfo> callbackPtr{asyncCallbackInfo};
133     ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_TWO, "Parameter count error");
134     if (!CheckAndParseInstallParamType(env, argc, argv, asyncCallbackInfo)) {
135         return nullptr;
136     }
137 
138     napi_value asyncWorkReturn =
139         HandleAsyncWork(env, asyncCallbackInfo, "NativeInstall", NativeInstall, NativeVoidCallbackComplete);
140     callbackPtr.release();
141     return asyncWorkReturn;
142 }
143 
NativeInstall(napi_env env,void * data)144 void BundleManagerAddon::NativeInstall(napi_env env, void *data)
145 {
146     EDMLOGI("NAPI_NativeInstall called");
147     if (data == nullptr) {
148         EDMLOGE("data is nullptr");
149         return;
150     }
151     AsyncInstallCallbackInfo *asyncCallbackInfo = static_cast<AsyncInstallCallbackInfo *>(data);
152     auto proxy = BundleManagerProxy::GetBundleManagerProxy();
153     if (proxy == nullptr) {
154         EDMLOGE("can not get BundleManagerProxy");
155         return;
156     }
157 
158     asyncCallbackInfo->ret = proxy->Install(asyncCallbackInfo->elementName, asyncCallbackInfo->hapFilePaths,
159         asyncCallbackInfo->installParam, asyncCallbackInfo->innerCodeMsg);
160     EDMLOGI("NAPI_NativeInstall asyncCallbackInfo->ret : %{public}d", asyncCallbackInfo->ret);
161 }
162 
NativeUninstallCallbackComplete(napi_env env,napi_status status,void * data)163 void BundleManagerAddon::NativeUninstallCallbackComplete(napi_env env, napi_status status, void *data)
164 {
165     if (data == nullptr) {
166         EDMLOGE("data is nullptr");
167         return;
168     }
169     AsyncCallbackInfo *asyncCallbackInfo = static_cast<AsyncCallbackInfo *>(data);
170     napi_value error = nullptr;
171     if (asyncCallbackInfo->callback == nullptr) {
172         EDMLOGD("asyncCallbackInfo->deferred != nullptr");
173         if (asyncCallbackInfo->ret == ERR_OK) {
174             napi_get_null(env, &error);
175             napi_resolve_deferred(env, asyncCallbackInfo->deferred, error);
176         } else {
177             if (asyncCallbackInfo->ret == EdmReturnErrCode::PARAM_ERROR) {
178                 napi_reject_deferred(env, asyncCallbackInfo->deferred,
179                     CreateError(env, asyncCallbackInfo->ret, asyncCallbackInfo->errMessage));
180             } else {
181                 napi_reject_deferred(env, asyncCallbackInfo->deferred, CreateError(env, asyncCallbackInfo->ret));
182             }
183         }
184     } else {
185         if (asyncCallbackInfo->ret == ERR_OK) {
186             napi_get_null(env, &error);
187         } else {
188             if (asyncCallbackInfo->ret == EdmReturnErrCode::PARAM_ERROR) {
189                 error = CreateError(env, asyncCallbackInfo->ret, asyncCallbackInfo->errMessage);
190             } else {
191                 error = CreateError(env, asyncCallbackInfo->ret);
192             }
193         }
194         napi_value callback = nullptr;
195         napi_value result = nullptr;
196         napi_get_reference_value(env, asyncCallbackInfo->callback, &callback);
197         napi_call_function(env, nullptr, callback, ARGS_SIZE_ONE, &error, &result);
198         napi_delete_reference(env, asyncCallbackInfo->callback);
199     }
200     napi_delete_async_work(env, asyncCallbackInfo->asyncWork);
201     delete asyncCallbackInfo;
202 }
203 
CheckAndParseUninstallParamType(napi_env env,size_t argc,napi_value * argv,AsyncUninstallCallbackInfo * asyncCallbackInfo)204 bool BundleManagerAddon::CheckAndParseUninstallParamType(napi_env env, size_t argc, napi_value *argv,
205     AsyncUninstallCallbackInfo *asyncCallbackInfo)
206 {
207     ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_TWO, "Parameter count error");
208     ASSERT_AND_THROW_PARAM_ERROR(env, ParseElementName(env, asyncCallbackInfo->elementName, argv[ARR_INDEX_ZERO]),
209         "Parameter want error");
210     ASSERT_AND_THROW_PARAM_ERROR(env, ParseString(env, asyncCallbackInfo->bundleName, argv[ARR_INDEX_ONE]),
211         "Parameter bundle name error");
212     AccountSA::OsAccountManager::GetOsAccountLocalIdFromProcess(asyncCallbackInfo->userId);
213     if (argc == ARGS_SIZE_TWO) {
214         return true;
215     }
216     bool hasCallback = argc <= ARGS_SIZE_FIVE ? MatchValueType(env, argv[argc - 1], napi_function) :
217                                                 MatchValueType(env, argv[ARR_INDEX_FOUR], napi_function);
218     if (hasCallback) {
219         ASSERT_AND_THROW_PARAM_ERROR(env, ParseCallback(env, asyncCallbackInfo->callback,
220             argc <= ARGS_SIZE_FIVE ? argv[argc - 1] : argv[ARR_INDEX_FOUR]), "Parameter callback error");
221         switch (argc) {
222             case ARGS_SIZE_THREE:
223                 break;
224             case ARGS_SIZE_FOUR:
225                 if (MatchValueType(env, argv[ARR_INDEX_TWO], napi_number)) {
226                     ASSERT_AND_THROW_PARAM_ERROR(env, ParseInt(env, asyncCallbackInfo->userId, argv[ARR_INDEX_TWO]),
227                         "Parameter userId error");
228                 } else if (MatchValueType(env, argv[ARR_INDEX_TWO], napi_boolean)) {
229                     ASSERT_AND_THROW_PARAM_ERROR(env, ParseBool(env, asyncCallbackInfo->isKeepData,
230                         argv[ARR_INDEX_TWO]), "Parameter isKeepData error");
231                 } else {
232                     ASSERT_AND_THROW_PARAM_ERROR(env, false, "Parameter three type error");
233                 }
234                 break;
235             default:
236                 ASSERT_AND_THROW_PARAM_ERROR(env, ParseInt(env, asyncCallbackInfo->userId, argv[ARR_INDEX_TWO]),
237                     "Parameter userId error");
238                 ASSERT_AND_THROW_PARAM_ERROR(env, ParseBool(env, asyncCallbackInfo->isKeepData, argv[ARR_INDEX_THREE]),
239                     "Parameter isKeepData error");
240         }
241         return true;
242     }
243     if (argc == ARGS_SIZE_THREE) {
244         if (!ParseInt(env, asyncCallbackInfo->userId, argv[ARR_INDEX_TWO])) {
245             AccountSA::OsAccountManager::GetOsAccountLocalIdFromProcess(asyncCallbackInfo->userId);
246             ParseBool(env, asyncCallbackInfo->isKeepData, argv[ARR_INDEX_TWO]);
247         }
248         return true;
249     }
250     if (!ParseInt(env, asyncCallbackInfo->userId, argv[ARR_INDEX_TWO])) {
251         AccountSA::OsAccountManager::GetOsAccountLocalIdFromProcess(asyncCallbackInfo->userId);
252     }
253     ParseBool(env, asyncCallbackInfo->isKeepData, argv[ARR_INDEX_THREE]);
254     return true;
255 }
256 
jsObjectToInstallParam(napi_env env,napi_value object,OHOS::AppExecFwk::InstallParam & installParam)257 bool BundleManagerAddon::jsObjectToInstallParam(napi_env env, napi_value object,
258     OHOS::AppExecFwk::InstallParam &installParam)
259 {
260     int32_t installFlag = 0;
261     if (!JsObjectToInt(env, object, "userId", false, installParam.userId) ||
262         !JsObjectToInt(env, object, "installFlag", false, installFlag)) {
263         return false;
264     }
265     bool hasProperty = false;
266     if (napi_has_named_property(env, object, "userId", &hasProperty) == napi_ok && !hasProperty) {
267         AccountSA::OsAccountManager::GetOsAccountLocalIdFromProcess(installParam.userId);
268     }
269     if ((installFlag != static_cast<int32_t>(OHOS::AppExecFwk::InstallFlag::NORMAL)) &&
270         (installFlag != static_cast<int32_t>(OHOS::AppExecFwk::InstallFlag::REPLACE_EXISTING)) &&
271         (installFlag != static_cast<int32_t>(OHOS::AppExecFwk::InstallFlag::FREE_INSTALL))) {
272         EDMLOGE("invalid installFlag param");
273         return false;
274     }
275     installParam.installFlag = static_cast<OHOS::AppExecFwk::InstallFlag>(installFlag);
276     return true;
277 }
278 
CheckAndParseInstallParamType(napi_env env,size_t argc,napi_value * argv,AsyncInstallCallbackInfo * asyncCallbackInfo)279 bool BundleManagerAddon::CheckAndParseInstallParamType(napi_env env, size_t argc, napi_value *argv,
280     AsyncInstallCallbackInfo *asyncCallbackInfo)
281 {
282     ASSERT_AND_THROW_PARAM_ERROR(env, ParseElementName(env, asyncCallbackInfo->elementName, argv[ARR_INDEX_ZERO]),
283         "Parameter want error");
284     ASSERT_AND_THROW_PARAM_ERROR(env, ParseStringArray(env, asyncCallbackInfo->hapFilePaths, argv[ARR_INDEX_ONE]),
285         "Parameter bundleFilePaths error");
286     if (argc == ARGS_SIZE_TWO) {
287         return true;
288     }
289     bool hasCallback = argc <= ARGS_SIZE_FOUR ? MatchValueType(env, argv[argc - 1], napi_function) :
290                                                 MatchValueType(env, argv[ARR_INDEX_THREE], napi_function);
291     if (hasCallback) {
292         ASSERT_AND_THROW_PARAM_ERROR(env,
293             ParseCallback(env, asyncCallbackInfo->callback,
294                 argc <= ARGS_SIZE_FOUR ? argv[argc - 1] : argv[ARGS_SIZE_THREE]),
295             "Parameter callback error");
296         EDMLOGI("CheckAndParseInstallParamType ParseCallback success");
297         if (argc == ARGS_SIZE_FOUR) {
298             ASSERT_AND_THROW_PARAM_ERROR(env,
299                 jsObjectToInstallParam(env, argv[ARR_INDEX_TWO], asyncCallbackInfo->installParam),
300                 "installParam param error");
301         }
302         return true;
303     }
304     ASSERT_AND_THROW_PARAM_ERROR(env, jsObjectToInstallParam(env, argv[ARR_INDEX_TWO], asyncCallbackInfo->installParam),
305         "installParam param error");
306     return true;
307 }
308 
GetAllowedOrDisallowedInstallBundles(napi_env env,napi_callback_info info,const std::string & workName,napi_async_execute_callback execute)309 napi_value BundleManagerAddon::GetAllowedOrDisallowedInstallBundles(napi_env env, napi_callback_info info,
310     const std::string &workName, napi_async_execute_callback execute)
311 {
312     size_t argc = ARGS_SIZE_THREE;
313     napi_value argv[ARGS_SIZE_THREE] = {nullptr};
314     napi_value thisArg = nullptr;
315     void *data = nullptr;
316     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
317     bool hasCallback = false;
318     bool hasUserId = false;
319     auto asyncCallbackInfo = new (std::nothrow) AsyncBundlesCallbackInfo();
320     if (asyncCallbackInfo == nullptr) {
321         return nullptr;
322     }
323     std::unique_ptr<AsyncBundlesCallbackInfo> callbackPtr{asyncCallbackInfo};
324     ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_ONE, "Parameter count error");
325     ASSERT_AND_THROW_PARAM_ERROR(env, CheckAdminWithUserIdParamType(env, argc, argv, hasCallback, hasUserId),
326         "Parameter type error");
327     ASSERT_AND_THROW_PARAM_ERROR(env, ParseElementName(env, asyncCallbackInfo->elementName, argv[ARR_INDEX_ZERO]),
328         "Parameter want error");
329 
330     EDMLOGD("GetInstallBundles bundlename %{public}s, abilityname:%{public}s",
331         asyncCallbackInfo->elementName.GetBundleName().c_str(),
332         asyncCallbackInfo->elementName.GetAbilityName().c_str());
333     if (hasUserId) {
334         ASSERT_AND_THROW_PARAM_ERROR(env, ParseInt(env, asyncCallbackInfo->userId, argv[ARR_INDEX_ONE]),
335             "Parameter user id error");
336     } else {
337         AccountSA::OsAccountManager::GetOsAccountLocalIdFromProcess(asyncCallbackInfo->userId);
338     }
339     if (hasCallback) {
340         ASSERT_AND_THROW_PARAM_ERROR(env,
341             ParseCallback(env, asyncCallbackInfo->callback,
342                 argc <= ARR_INDEX_THREE ? argv[argc - 1] : argv[ARR_INDEX_TWO]),
343             "Parameter callback error");
344     }
345     InitCallbackInfoPolicyType(workName, asyncCallbackInfo);
346     EDMLOGI("GetInstallBundles::%{public}s policyType = %{public}d", workName.c_str(), asyncCallbackInfo->policyType);
347     napi_value asyncWorkReturn =
348         HandleAsyncWork(env, asyncCallbackInfo, workName, execute, NativeArrayStringCallbackComplete);
349     callbackPtr.release();
350     return asyncWorkReturn;
351 }
352 
InitCallbackInfoPolicyType(const std::string & workName,AsyncBundlesCallbackInfo * callbackInfo)353 void BundleManagerAddon::InitCallbackInfoPolicyType(const std::string &workName, AsyncBundlesCallbackInfo *callbackInfo)
354 {
355     auto iter = POLICY_TYPE_MAP.find(workName);
356     if (iter != POLICY_TYPE_MAP.end()) {
357         callbackInfo->policyType = iter->second;
358     } else {
359         EDMLOGI("policy type map get error");
360         callbackInfo->policyType = static_cast<int32_t>(PolicyType::INVALID_TYPE);
361     }
362 }
363 
NativeGetBundlesByPolicyType(napi_env env,void * data)364 void BundleManagerAddon::NativeGetBundlesByPolicyType(napi_env env, void *data)
365 {
366     EDMLOGI("NAPI_NativeGetBundlesByPolicyType called");
367     if (data == nullptr) {
368         EDMLOGE("data is nullptr");
369         return;
370     }
371     AsyncBundlesCallbackInfo *asyncCallbackInfo = static_cast<AsyncBundlesCallbackInfo *>(data);
372     auto proxy = BundleManagerProxy::GetBundleManagerProxy();
373     if (proxy == nullptr) {
374         EDMLOGE("can not get BundleManagerProxy");
375         return;
376     }
377 
378     asyncCallbackInfo->ret = proxy->GetBundlesByPolicyType(asyncCallbackInfo->elementName, asyncCallbackInfo->userId,
379         asyncCallbackInfo->arrayStringRet, asyncCallbackInfo->policyType);
380 }
381 
AddAllowedInstallBundles(napi_env env,napi_callback_info info)382 napi_value BundleManagerAddon::AddAllowedInstallBundles(napi_env env, napi_callback_info info)
383 {
384     return AddOrRemoveInstallBundles(env, info, "AddAllowedInstallBundles", NativeAddBundlesByPolicyType);
385 }
386 
AddDisallowedInstallBundles(napi_env env,napi_callback_info info)387 napi_value BundleManagerAddon::AddDisallowedInstallBundles(napi_env env, napi_callback_info info)
388 {
389     return AddOrRemoveInstallBundles(env, info, "AddDisallowedInstallBundles", NativeAddBundlesByPolicyType);
390 }
391 
AddDisallowedUninstallBundles(napi_env env,napi_callback_info info)392 napi_value BundleManagerAddon::AddDisallowedUninstallBundles(napi_env env, napi_callback_info info)
393 {
394     return AddOrRemoveInstallBundles(env, info, "AddDisallowedUninstallBundles", NativeAddBundlesByPolicyType);
395 }
396 
RemoveAllowedInstallBundles(napi_env env,napi_callback_info info)397 napi_value BundleManagerAddon::RemoveAllowedInstallBundles(napi_env env, napi_callback_info info)
398 {
399     return AddOrRemoveInstallBundles(env, info, "RemoveAllowedInstallBundles", NativeRemoveBundlesByPolicyType);
400 }
401 
RemoveDisallowedInstallBundles(napi_env env,napi_callback_info info)402 napi_value BundleManagerAddon::RemoveDisallowedInstallBundles(napi_env env, napi_callback_info info)
403 {
404     return AddOrRemoveInstallBundles(env, info, "RemoveDisallowedInstallBundles", NativeRemoveBundlesByPolicyType);
405 }
406 
RemoveDisallowedUninstallBundles(napi_env env,napi_callback_info info)407 napi_value BundleManagerAddon::RemoveDisallowedUninstallBundles(napi_env env, napi_callback_info info)
408 {
409     return AddOrRemoveInstallBundles(env, info, "RemoveDisallowedUninstallBundles", NativeRemoveBundlesByPolicyType);
410 }
411 
CheckAddInstallBundlesParamType(napi_env env,size_t argc,napi_value * argv,bool & hasCallback,bool & hasUserId)412 bool BundleManagerAddon::CheckAddInstallBundlesParamType(napi_env env, size_t argc, napi_value *argv, bool &hasCallback,
413     bool &hasUserId)
414 {
415     if (!MatchValueType(env, argv[ARR_INDEX_ZERO], napi_object) ||
416         !MatchValueType(env, argv[ARR_INDEX_ONE], napi_object)) {
417         EDMLOGE("CheckAddInstallBundlesParamType admin or array type check failed");
418         return false;
419     }
420     EDMLOGI("CheckAddInstallBundlesParamType argc = %{public}zu", argc);
421     if (argc == ARGS_SIZE_TWO) {
422         hasCallback = false;
423         hasUserId = false;
424         EDMLOGI("hasCallback = false; hasUserId = false;");
425         return true;
426     }
427 
428     if (argc == ARGS_SIZE_THREE) {
429         if (MatchValueType(env, argv[ARR_INDEX_TWO], napi_function)) {
430             hasCallback = true;
431             hasUserId = false;
432             EDMLOGI("hasCallback = true; hasUserId = false;");
433             return true;
434         } else {
435             hasCallback = false;
436             hasUserId = true;
437             EDMLOGI("hasCallback = false;  hasUserId = true;");
438             return MatchValueType(env, argv[ARR_INDEX_TWO], napi_number);
439         }
440     }
441     hasCallback = true;
442     hasUserId = true;
443     EDMLOGI("hasCallback = true; hasUserId = true;");
444     return MatchValueType(env, argv[ARR_INDEX_TWO], napi_number) &&
445         MatchValueType(env, argv[ARR_INDEX_THREE], napi_function);
446 }
447 
AddOrRemoveInstallBundles(napi_env env,napi_callback_info info,const std::string & workName,napi_async_execute_callback execute)448 napi_value BundleManagerAddon::AddOrRemoveInstallBundles(napi_env env, napi_callback_info info,
449     const std::string &workName, napi_async_execute_callback execute)
450 {
451     size_t argc = ARGS_SIZE_FOUR;
452     napi_value argv[ARGS_SIZE_FOUR] = {nullptr};
453     napi_value thisArg = nullptr;
454     void *data = nullptr;
455     bool hasCallback = false;
456     bool hasUserId = false;
457     NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisArg, &data));
458     auto asyncCallbackInfo = new (std::nothrow) AsyncBundlesCallbackInfo();
459     if (asyncCallbackInfo == nullptr) {
460         return nullptr;
461     }
462     std::unique_ptr<AsyncBundlesCallbackInfo> callbackPtr{asyncCallbackInfo};
463     ASSERT_AND_THROW_PARAM_ERROR(env, argc >= ARGS_SIZE_TWO, "Parameter count error");
464     ASSERT_AND_THROW_PARAM_ERROR(env, CheckAddInstallBundlesParamType(env, argc, argv, hasCallback, hasUserId),
465         "Parameter type error");
466     ASSERT_AND_THROW_PARAM_ERROR(env, ParseElementName(env, asyncCallbackInfo->elementName, argv[ARR_INDEX_ZERO]),
467         "Parameter want error");
468     ASSERT_AND_THROW_PARAM_ERROR(env, ParseStringArray(env, asyncCallbackInfo->bundles, argv[ARR_INDEX_ONE]),
469         "Parameter bundles error");
470     ASSERT_AND_THROW_PARAM_ERROR(env, asyncCallbackInfo->bundles.size() <= EdmConstants::APPID_MAX_SIZE,
471         "Parameter bundles too large");
472     EDMLOGD(
473         "EnableAdmin::asyncCallbackInfo->elementName.bundlename %{public}s, "
474         "asyncCallbackInfo->abilityname:%{public}s",
475         asyncCallbackInfo->elementName.GetBundleName().c_str(),
476         asyncCallbackInfo->elementName.GetAbilityName().c_str());
477     if (hasUserId) {
478         ASSERT_AND_THROW_PARAM_ERROR(env, ParseInt(env, asyncCallbackInfo->userId, argv[ARR_INDEX_TWO]),
479             "Parameter user id error");
480     } else {
481         AccountSA::OsAccountManager::GetOsAccountLocalIdFromProcess(asyncCallbackInfo->userId);
482     }
483     if (hasCallback) {
484         ASSERT_AND_THROW_PARAM_ERROR(env,
485             ParseCallback(env, asyncCallbackInfo->callback,
486                 argc <= ARGS_SIZE_FOUR ? argv[argc - 1] : argv[ARR_INDEX_THREE]),
487             "Parameter callback error");
488     }
489     InitCallbackInfoPolicyType(workName, asyncCallbackInfo);
490     EDMLOGI("AddOrRemoveInstallBundles::%{public}s policyType = %{public}d", workName.c_str(),
491         asyncCallbackInfo->policyType);
492     napi_value asyncWorkReturn = HandleAsyncWork(env, asyncCallbackInfo, workName, execute, NativeVoidCallbackComplete);
493     callbackPtr.release();
494     return asyncWorkReturn;
495 }
496 
NativeRemoveBundlesByPolicyType(napi_env env,void * data)497 void BundleManagerAddon::NativeRemoveBundlesByPolicyType(napi_env env, void *data)
498 {
499     EDMLOGI("NativeRemoveBundlesByPolicyType called");
500     if (data == nullptr) {
501         EDMLOGE("data is nullptr");
502         return;
503     }
504     AsyncBundlesCallbackInfo *asyncCallbackInfo = static_cast<AsyncBundlesCallbackInfo *>(data);
505     auto bundleManagerProxy = BundleManagerProxy::GetBundleManagerProxy();
506     if (bundleManagerProxy == nullptr) {
507         EDMLOGE("can not get BundleManagerProxy");
508         return;
509     }
510     asyncCallbackInfo->ret = bundleManagerProxy->RemoveBundlesByPolicyType(asyncCallbackInfo->elementName,
511         asyncCallbackInfo->bundles, asyncCallbackInfo->userId, asyncCallbackInfo->policyType);
512 }
513 
NativeAddBundlesByPolicyType(napi_env env,void * data)514 void BundleManagerAddon::NativeAddBundlesByPolicyType(napi_env env, void *data)
515 {
516     EDMLOGI("NAPI_NativeAddBundlesByPolicyType called");
517     if (data == nullptr) {
518         EDMLOGE("data is nullptr");
519         return;
520     }
521     AsyncBundlesCallbackInfo *asyncCallbackInfo = static_cast<AsyncBundlesCallbackInfo *>(data);
522     auto bundleManagerProxy = BundleManagerProxy::GetBundleManagerProxy();
523     if (bundleManagerProxy == nullptr) {
524         EDMLOGE("can not get BundleManagerProxy");
525         return;
526     }
527     asyncCallbackInfo->ret = bundleManagerProxy->AddBundlesByPolicyType(asyncCallbackInfo->elementName,
528         asyncCallbackInfo->bundles, asyncCallbackInfo->userId, asyncCallbackInfo->policyType);
529 }
530 
531 static napi_module g_bundleManagerModule = {
532     .nm_version = 1,
533     .nm_flags = 0,
534     .nm_filename = nullptr,
535     .nm_register_func = BundleManagerAddon::Init,
536     .nm_modname = "enterprise.bundleManager",
537     .nm_priv = ((void *)0),
538     .reserved = {0},
539 };
540 
BundleManagerRegister()541 extern "C" __attribute__((constructor)) void BundleManagerRegister()
542 {
543     napi_module_register(&g_bundleManagerModule);
544 }