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