• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 <unordered_map>
17 
18 #include "installer.h"
19 
20 #include "appexecfwk_errors.h"
21 #include "app_log_wrapper.h"
22 #include "bundle_errors.h"
23 #include "bundle_death_recipient.h"
24 #include "bundle_mgr_interface.h"
25 #include "bundle_mgr_proxy.h"
26 #include "business_error.h"
27 #include "common_func.h"
28 #include "if_system_ability_manager.h"
29 #include "installer_callback.h"
30 #include "napi_arg.h"
31 #include "napi_constants.h"
32 #include "system_ability_definition.h"
33 #include "ipc_skeleton.h"
34 
35 namespace OHOS {
36 namespace AppExecFwk {
37 namespace {
38 // resource name
39 const char* RESOURCE_NAME_OF_GET_BUNDLE_INSTALLER = "GetBundleInstaller";
40 const char* RESOURCE_NAME_OF_GET_BUNDLE_INSTALLER_SYNC = "GetBundleInstallerSync";
41 const char* RESOURCE_NAME_OF_INSTALL = "Install";
42 const char* RESOURCE_NAME_OF_UNINSTALL = "Uninstall";
43 const char* RESOURCE_NAME_OF_RECOVER = "Recover";
44 const char* RESOURCE_NAME_OF_UPDATE_BUNDLE_FOR_SELF = "UpdateBundleForSelf";
45 const char* RESOURCE_NAME_OF_UNINSTALL_AND_RECOVER = "UninstallAndRecover";
46 const char* EMPTY_STRING = "";
47 // install message
48 constexpr const char* INSTALL_PERMISSION =
49     "ohos.permission.INSTALL_BUNDLE or "
50     "ohos.permission.INSTALL_ENTERPRISE_BUNDLE or "
51     "ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE or "
52     "ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE";
53 constexpr const char* UNINSTALL_PERMISSION = "ohos.permission.INSTALL_BUNDLE or ohos.permission.UNINSTALL_BUNDLE";
54 constexpr const char* RECOVER_PERMISSION = "ohos.permission.INSTALL_BUNDLE or ohos.permission.RECOVER_BUNDLE";
55 constexpr const char* INSTALL_SELF_PERMISSION = "ohos.permission.INSTALL_SELF_BUNDLE";
56 constexpr const char* PARAMETERS = "parameters";
57 constexpr const char* CORRESPONDING_TYPE = "corresponding type";
58 constexpr const char* FUNCTION_TYPE = "napi_function";
59 constexpr const char* CALLBACK = "callback";
60 // property name
61 const char* USER_ID = "userId";
62 const char* INSTALL_FLAG = "installFlag";
63 const char* IS_KEEP_DATA = "isKeepData";
64 const char* CROWD_TEST_DEADLINE = "crowdtestDeadline";
65 const char* MODULE_NAME = "moduleName";
66 const char* HASH_VALUE = "hashValue";
67 const char* HASH_PARAMS = "hashParams";
68 const char* BUNDLE_NAME = "bundleName";
69 const char* APP_INDEX = "appIndex";
70 const char* FILE_PATH = "filePath";
71 const char* ADD_EXT_RESOURCE = "AddExtResource";
72 const char* REMOVE_EXT_RESOURCE = "RemoveExtResource";
73 const char* VERSION_CODE = "versionCode";
74 const char* SHARED_BUNDLE_DIR_PATHS = "sharedBundleDirPaths";
75 const char* SPECIFIED_DISTRIBUTION_TYPE = "specifiedDistributionType";
76 const char* ADDITIONAL_INFO = "additionalInfo";
77 const char* VERIFY_CODE_PARAM = "verifyCodeParams";
78 const char* SIGNATURE_FILE_PATH = "signatureFilePath";
79 const char* PGO_PARAM = "pgoParams";
80 const char* PGO_FILE_PATH = "pgoFilePath";
81 const char* HAPS_FILE_NEEDED =
82     "BusinessError 401: Parameter error. parameter hapFiles is needed for code signature";
83 const char* CREATE_APP_CLONE = "CreateAppClone";
84 const char* DESTROY_APP_CLONE = "destroyAppClone";
85 const char* INSTALL_PREEXISTING_APP = "installPreexistingApp";
86 constexpr int32_t FIRST_PARAM = 0;
87 constexpr int32_t SECOND_PARAM = 1;
88 
89 constexpr int32_t SPECIFIED_DISTRIBUTION_TYPE_MAX_SIZE = 128;
90 constexpr int32_t ADDITIONAL_INFO_MAX_SIZE = 3000;
91 constexpr int32_t ILLEGAL_APP_INDEX = -1;
92 } // namespace
93 napi_ref thread_local g_classBundleInstaller;
94 bool g_isSystemApp = false;
95 
~AsyncInstallCallbackInfo()96 AsyncInstallCallbackInfo::~AsyncInstallCallbackInfo()
97 {
98     if (callback) {
99         napi_delete_reference(env, callback);
100         callback = nullptr;
101     }
102     if (asyncWork) {
103         napi_delete_async_work(env, asyncWork);
104         asyncWork = nullptr;
105     }
106 }
107 
~AsyncGetBundleInstallerCallbackInfo()108 AsyncGetBundleInstallerCallbackInfo::~AsyncGetBundleInstallerCallbackInfo()
109 {
110     if (callback) {
111         napi_delete_reference(env, callback);
112         callback = nullptr;
113     }
114     if (asyncWork) {
115         napi_delete_async_work(env, asyncWork);
116         asyncWork = nullptr;
117     }
118 }
119 
GetBundleInstallerCompleted(napi_env env,napi_status status,void * data)120 void GetBundleInstallerCompleted(napi_env env, napi_status status, void *data)
121 {
122     AsyncGetBundleInstallerCallbackInfo *asyncCallbackInfo =
123         reinterpret_cast<AsyncGetBundleInstallerCallbackInfo *>(data);
124     std::unique_ptr<AsyncGetBundleInstallerCallbackInfo> callbackPtr {asyncCallbackInfo};
125 
126     napi_value m_classBundleInstaller = nullptr;
127     NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, g_classBundleInstaller,
128         &m_classBundleInstaller));
129     napi_value result[CALLBACK_PARAM_SIZE] = {0};
130     auto iBundleMgr = CommonFunc::GetBundleMgr();
131     if (iBundleMgr == nullptr) {
132         APP_LOGE("can not get iBundleMgr");
133         return;
134     }
135     if (!g_isSystemApp && !iBundleMgr->VerifySystemApi(Constants::INVALID_API_VERSION)) {
136         APP_LOGE("non-system app calling system api");
137         result[0] = BusinessError::CreateCommonError(
138             env, ERROR_NOT_SYSTEM_APP, RESOURCE_NAME_OF_GET_BUNDLE_INSTALLER, INSTALL_PERMISSION);
139         if (callbackPtr->deferred) {
140             NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, asyncCallbackInfo->deferred, result[0]));
141         } else {
142             napi_value callback = nullptr;
143             napi_value placeHolder = nullptr;
144             NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, asyncCallbackInfo->callback, &callback));
145             NAPI_CALL_RETURN_VOID(env, napi_call_function(env, nullptr, callback,
146                 sizeof(result) / sizeof(result[0]), result, &placeHolder));
147         }
148         return;
149     }
150     g_isSystemApp = true;
151     NAPI_CALL_RETURN_VOID(env, napi_new_instance(env, m_classBundleInstaller, 0, nullptr, &result[SECOND_PARAM]));
152 
153     if (callbackPtr->deferred) {
154         NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, callbackPtr->deferred, result[SECOND_PARAM]));
155     } else {
156         napi_value callback = CommonFunc::WrapVoidToJS(env);
157         NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, callbackPtr->callback, &callback));
158         napi_value undefined = CommonFunc::WrapVoidToJS(env);
159         NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined));
160         napi_value callResult = CommonFunc::WrapVoidToJS(env);
161         NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, CALLBACK_PARAM_SIZE,
162             &result[FIRST_PARAM], &callResult));
163     }
164 }
165 
166 /**
167  * Promise and async callback
168  */
GetBundleInstaller(napi_env env,napi_callback_info info)169 napi_value GetBundleInstaller(napi_env env, napi_callback_info info)
170 {
171     APP_LOGI_NOFUNC("napi GetBundleInstaller called");
172     NapiArg args(env, info);
173     if (!args.Init(FIRST_PARAM, SECOND_PARAM)) {
174         APP_LOGE("GetBundleInstaller args init failed");
175         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
176         return nullptr;
177     }
178     std::unique_ptr<AsyncGetBundleInstallerCallbackInfo> callbackPtr =
179         std::make_unique<AsyncGetBundleInstallerCallbackInfo>(env);
180 
181     auto argc = args.GetMaxArgc();
182     APP_LOGD("GetBundleInstaller argc = [%{public}zu]", argc);
183     // check param
184     if (argc == SECOND_PARAM) {
185         napi_value arg = args.GetArgv(argc - SECOND_PARAM);
186         if (arg == nullptr) {
187             APP_LOGE("the param is nullptr");
188             BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
189             return nullptr;
190         }
191         napi_valuetype valuetype = napi_undefined;
192         NAPI_CALL(env, napi_typeof(env, arg, &valuetype));
193         if (valuetype != napi_function) {
194             APP_LOGE("the param type is invalid");
195             BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, CALLBACK, FUNCTION_TYPE);
196             return nullptr;
197         }
198         NAPI_CALL(env, napi_create_reference(env, arg, NAPI_RETURN_ONE, &callbackPtr->callback));
199     }
200 
201     auto executeFunc = [](napi_env env, void *data) {};
202     napi_value promise = CommonFunc::AsyncCallNativeMethod(
203         env,
204         callbackPtr.get(),
205         RESOURCE_NAME_OF_GET_BUNDLE_INSTALLER,
206         executeFunc,
207         GetBundleInstallerCompleted);
208     callbackPtr.release();
209     APP_LOGI_NOFUNC("call GetBundleInstaller done");
210     return promise;
211 }
212 
GetBundleInstallerSync(napi_env env,napi_callback_info info)213 napi_value GetBundleInstallerSync(napi_env env, napi_callback_info info)
214 {
215     APP_LOGI("NAPI GetBundleInstallerSync called");
216     napi_value m_classBundleInstaller = nullptr;
217     NAPI_CALL(env, napi_get_reference_value(env, g_classBundleInstaller,
218         &m_classBundleInstaller));
219     auto iBundleMgr = CommonFunc::GetBundleMgr();
220     if (iBundleMgr == nullptr) {
221         APP_LOGE("can not get iBundleMgr");
222         return nullptr;
223     }
224     if (!g_isSystemApp && !iBundleMgr->VerifySystemApi(Constants::INVALID_API_VERSION)) {
225         APP_LOGE("non-system app calling system api");
226         napi_value businessError = BusinessError::CreateCommonError(
227             env, ERROR_NOT_SYSTEM_APP, RESOURCE_NAME_OF_GET_BUNDLE_INSTALLER_SYNC, INSTALL_PERMISSION);
228         napi_throw(env, businessError);
229         return nullptr;
230     }
231     g_isSystemApp = true;
232     napi_value nBundleInstaller = nullptr;
233     NAPI_CALL(env, napi_new_instance(env, m_classBundleInstaller, 0, nullptr, &nBundleInstaller));
234     APP_LOGD("call GetBundleInstallerSync done");
235     return nBundleInstaller;
236     APP_LOGI("call GetBundleInstallerSync done");
237 }
238 
CreateErrCodeMap(std::unordered_map<int32_t,int32_t> & errCodeMap)239 static void CreateErrCodeMap(std::unordered_map<int32_t, int32_t> &errCodeMap)
240 {
241     errCodeMap = {
242         { IStatusReceiver::SUCCESS, SUCCESS},
243         { IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION },
244         { IStatusReceiver::ERR_INSTALL_HOST_INSTALLER_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION },
245         { IStatusReceiver::ERR_INSTALLD_PARAM_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION },
246         { IStatusReceiver::ERR_INSTALLD_GET_PROXY_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION },
247         { IStatusReceiver::ERR_INSTALL_INSTALLD_SERVICE_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION },
248         { IStatusReceiver::ERR_UNINSTALL_BUNDLE_MGR_SERVICE_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION },
249         { IStatusReceiver::ERR_FAILED_SERVICE_DIED, ERROR_BUNDLE_SERVICE_EXCEPTION },
250         { IStatusReceiver::ERR_FAILED_GET_INSTALLER_PROXY, ERROR_BUNDLE_SERVICE_EXCEPTION },
251         { IStatusReceiver::ERR_USER_CREATE_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION },
252         { IStatusReceiver::ERR_USER_REMOVE_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION },
253         { IStatusReceiver::ERR_UNINSTALL_KILLING_APP_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION },
254         { IStatusReceiver::ERR_INSTALL_GENERATE_UID_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION },
255         { IStatusReceiver::ERR_INSTALL_STATE_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION },
256         { IStatusReceiver::ERR_RECOVER_NOT_ALLOWED, ERROR_BUNDLE_SERVICE_EXCEPTION },
257         { IStatusReceiver::ERR_RECOVER_GET_BUNDLEPATH_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION },
258         { IStatusReceiver::ERR_UNINSTALL_AND_RECOVER_NOT_PREINSTALLED_BUNDLE, ERROR_BUNDLE_NOT_PREINSTALLED },
259         { IStatusReceiver::ERR_UNINSTALL_SYSTEM_APP_ERROR, ERROR_UNINSTALL_PREINSTALL_APP_FAILED },
260         { IStatusReceiver::ERR_INSTALL_PARSE_FAILED, ERROR_INSTALL_PARSE_FAILED },
261         { IStatusReceiver::ERR_INSTALL_PARSE_UNEXPECTED, ERROR_INSTALL_PARSE_FAILED },
262         { IStatusReceiver::ERR_INSTALL_PARSE_MISSING_BUNDLE, ERROR_INSTALL_PARSE_FAILED },
263         { IStatusReceiver::ERR_INSTALL_PARSE_NO_PROFILE, ERROR_INSTALL_PARSE_FAILED },
264         { IStatusReceiver::ERR_INSTALL_PARSE_BAD_PROFILE, ERROR_INSTALL_PARSE_FAILED },
265         { IStatusReceiver::ERR_INSTALL_PARSE_PROFILE_PROP_TYPE_ERROR, ERROR_INSTALL_PARSE_FAILED },
266         { IStatusReceiver::ERR_INSTALL_PARSE_PROFILE_MISSING_PROP, ERROR_INSTALL_PARSE_FAILED },
267         { IStatusReceiver::ERR_INSTALL_PARSE_PERMISSION_ERROR, ERROR_INSTALL_PARSE_FAILED },
268         { IStatusReceiver::ERR_INSTALL_PARSE_PROFILE_PROP_CHECK_ERROR, ERROR_INSTALL_PARSE_FAILED },
269         { IStatusReceiver::ERR_INSTALL_PARSE_RPCID_FAILED, ERROR_INSTALL_PARSE_FAILED },
270         { IStatusReceiver::ERR_INSTALL_PARSE_NATIVE_SO_FAILED, ERROR_INSTALL_PARSE_FAILED },
271         { IStatusReceiver::ERR_INSTALL_PARSE_AN_FAILED, ERROR_INSTALL_PARSE_FAILED },
272         { IStatusReceiver::ERR_INSTALL_PARSE_MISSING_ABILITY, ERROR_INSTALL_PARSE_FAILED },
273         { IStatusReceiver::ERR_INSTALL_FAILED_PROFILE_PARSE_FAIL, ERROR_INSTALL_PARSE_FAILED },
274         { IStatusReceiver::ERR_INSTALL_VERIFICATION_FAILED, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED },
275         { IStatusReceiver::ERR_INSTALL_FAILED_INCOMPATIBLE_SIGNATURE, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED },
276         { IStatusReceiver::ERR_INSTALL_FAILED_INVALID_SIGNATURE_FILE_PATH, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED },
277         { IStatusReceiver::ERR_INSTALL_FAILED_BAD_BUNDLE_SIGNATURE_FILE, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED },
278         { IStatusReceiver::ERR_INSTALL_FAILED_NO_BUNDLE_SIGNATURE, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED },
279         { IStatusReceiver::ERR_INSTALL_FAILED_VERIFY_APP_PKCS7_FAIL, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED },
280         { IStatusReceiver::ERR_INSTALL_FAILED_APP_SOURCE_NOT_TRUESTED, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED },
281         { IStatusReceiver::ERR_INSTALL_FAILED_BAD_DIGEST, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED },
282         { IStatusReceiver::ERR_INSTALL_FAILED_BUNDLE_INTEGRITY_VERIFICATION_FAILURE,
283             ERROR_INSTALL_VERIFY_SIGNATURE_FAILED },
284         { IStatusReceiver::ERR_INSTALL_FAILED_BAD_PUBLICKEY, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED },
285         { IStatusReceiver::ERR_INSTALL_FAILED_BAD_BUNDLE_SIGNATURE, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED },
286         { IStatusReceiver::ERR_INSTALL_FAILED_NO_PROFILE_BLOCK_FAIL, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED },
287         { IStatusReceiver::ERR_INSTALL_FAILED_BUNDLE_SIGNATURE_VERIFICATION_FAILURE,
288             ERROR_INSTALL_VERIFY_SIGNATURE_FAILED },
289         { IStatusReceiver::ERR_INSTALL_FAILED_VERIFY_SOURCE_INIT_FAIL, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED },
290         { IStatusReceiver::ERR_INSTALL_SINGLETON_INCOMPATIBLE, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED },
291         { IStatusReceiver::ERR_INSTALL_FAILED_INCONSISTENT_SIGNATURE, ERROR_INSTALL_FAILED_INCONSISTENT_SIGNATURE },
292         { IStatusReceiver::ERR_INSTALL_PARAM_ERROR, ERROR_BUNDLE_NOT_EXIST },
293         { IStatusReceiver::ERR_UNINSTALL_PARAM_ERROR, ERROR_BUNDLE_NOT_EXIST },
294         { IStatusReceiver::ERR_RECOVER_INVALID_BUNDLE_NAME, ERROR_BUNDLE_NOT_EXIST },
295         { IStatusReceiver::ERR_UNINSTALL_INVALID_NAME, ERROR_BUNDLE_NOT_EXIST },
296         { IStatusReceiver::ERR_INSTALL_INVALID_BUNDLE_FILE, ERROR_INSTALL_HAP_FILEPATH_INVALID },
297         { IStatusReceiver::ERR_INSTALL_FAILED_MODULE_NAME_EMPTY, ERROR_MODULE_NOT_EXIST },
298         { IStatusReceiver::ERR_INSTALL_FAILED_MODULE_NAME_DUPLICATE, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
299         { IStatusReceiver::ERR_INSTALL_FAILED_CHECK_HAP_HASH_PARAM, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
300         { IStatusReceiver::ERR_UNINSTALL_MISSING_INSTALLED_BUNDLE, ERROR_BUNDLE_NOT_EXIST },
301         { IStatusReceiver::ERR_UNINSTALL_MISSING_INSTALLED_MODULE, ERROR_MODULE_NOT_EXIST },
302         { IStatusReceiver::ERR_USER_NOT_INSTALL_HAP, ERROR_BUNDLE_NOT_EXIST },
303         { IStatusReceiver::ERR_INSTALL_FILE_PATH_INVALID, ERROR_INSTALL_HAP_FILEPATH_INVALID },
304         { IStatusReceiver::ERR_INSTALL_PERMISSION_DENIED, ERROR_PERMISSION_DENIED_ERROR },
305         { IStatusReceiver::ERR_UNINSTALL_PERMISSION_DENIED, ERROR_PERMISSION_DENIED_ERROR },
306         { IStatusReceiver::ERR_INSTALL_GRANT_REQUEST_PERMISSIONS_FAILED, ERROR_INSTALL_PERMISSION_CHECK_ERROR },
307         { IStatusReceiver::ERR_INSTALL_UPDATE_HAP_TOKEN_FAILED, ERROR_INSTALL_PERMISSION_CHECK_ERROR },
308         { IStatusReceiver::ERR_INSTALLD_CREATE_DIR_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION },
309         { IStatusReceiver::ERR_INSTALLD_CHOWN_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION },
310         { IStatusReceiver::ERR_INSTALLD_CREATE_DIR_EXIST, ERROR_BUNDLE_SERVICE_EXCEPTION },
311         { IStatusReceiver::ERR_INSTALLD_REMOVE_DIR_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION },
312         { IStatusReceiver::ERR_INSTALLD_EXTRACT_FILES_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION },
313         { IStatusReceiver::ERR_INSTALLD_RNAME_DIR_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION },
314         { IStatusReceiver::ERR_INSTALLD_CLEAN_DIR_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION },
315         { IStatusReceiver::ERR_INSTALL_ENTRY_ALREADY_EXIST, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
316         { IStatusReceiver::ERR_INSTALL_ALREADY_EXIST, ERROR_INSTALL_ALREADY_EXIST },
317         { IStatusReceiver::ERR_INSTALL_BUNDLENAME_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
318         { IStatusReceiver::ERR_INSTALL_VERSIONCODE_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
319         { IStatusReceiver::ERR_INSTALL_VERSIONNAME_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
320         { IStatusReceiver::ERR_INSTALL_MINCOMPATIBLE_VERSIONCODE_NOT_SAME,
321             ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
322         { IStatusReceiver::ERR_INSTALL_VENDOR_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
323         { IStatusReceiver::ERR_INSTALL_RELEASETYPE_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
324         { IStatusReceiver::ERR_INSTALL_RELEASETYPE_TARGET_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
325         { IStatusReceiver::ERR_INSTALL_RELEASETYPE_COMPATIBLE_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
326         { IStatusReceiver::ERR_INSTALL_SINGLETON_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
327         { IStatusReceiver::ERR_INSTALL_ZERO_USER_WITH_NO_SINGLETON, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
328         { IStatusReceiver::ERR_INSTALL_CHECK_SYSCAP_FAILED, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
329         { IStatusReceiver::ERR_INSTALL_APPTYPE_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
330         { IStatusReceiver::ERR_INSTALL_URI_DUPLICATE, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
331         { IStatusReceiver::ERR_INSTALL_VERSION_NOT_COMPATIBLE, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
332         { IStatusReceiver::ERR_INSTALL_APP_DISTRIBUTION_TYPE_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
333         { IStatusReceiver::ERR_INSTALL_APP_PROVISION_TYPE_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
334         { IStatusReceiver::ERR_INSTALL_SO_INCOMPATIBLE, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
335         { IStatusReceiver::ERR_INSTALL_AN_INCOMPATIBLE, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
336         { IStatusReceiver::ERR_INSTALL_TYPE_ERROR, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
337         { IStatusReceiver::ERR_INSTALL_TYPE_ERROR, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
338         { IStatusReceiver::ERR_INSTALL_NOT_UNIQUE_DISTRO_MODULE_NAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
339         { IStatusReceiver::ERR_INSTALL_INCONSISTENT_MODULE_NAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
340         { IStatusReceiver::ERR_INSTALL_INVALID_NUMBER_OF_ENTRY_HAP, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
341         { IStatusReceiver::ERR_INSTALL_ASAN_ENABLED_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
342         { IStatusReceiver::ERR_INSTALL_ASAN_ENABLED_NOT_SUPPORT, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT},
343         { IStatusReceiver::ERR_INSTALL_BUNDLE_TYPE_NOT_SAME, ERROR_INSTALL_PARSE_FAILED},
344         { IStatusReceiver::ERR_INSTALL_DISK_MEM_INSUFFICIENT, ERROR_INSTALL_NO_DISK_SPACE_LEFT },
345         { IStatusReceiver::ERR_USER_NOT_EXIST, ERROR_INVALID_USER_ID },
346         { IStatusReceiver::ERR_INSTALL_VERSION_DOWNGRADE, ERROR_INSTALL_VERSION_DOWNGRADE },
347         { IStatusReceiver::ERR_INSTALL_DEVICE_TYPE_NOT_SUPPORTED, ERROR_INSTALL_PARSE_FAILED },
348         { IStatusReceiver::ERR_INSTALL_PARSE_PROFILE_PROP_SIZE_CHECK_ERROR, ERROR_INSTALL_PARSE_FAILED },
349         { IStatusReceiver::ERR_INSTALL_DEPENDENT_MODULE_NOT_EXIST, ERROR_INSTALL_DEPENDENT_MODULE_NOT_EXIST },
350         { IStatusReceiver::ERR_INSTALL_SHARE_APP_LIBRARY_NOT_ALLOWED, ERROR_INSTALL_SHARE_APP_LIBRARY_NOT_ALLOWED },
351         { IStatusReceiver::ERR_INSTALL_COMPATIBLE_POLICY_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
352         { IStatusReceiver::ERR_INSTALL_FILE_IS_SHARED_LIBRARY, ERROR_INSTALL_FILE_IS_SHARED_LIBRARY },
353         { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_INTERNAL_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION },
354         { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_INVALID_BUNDLE_NAME, ERROR_BUNDLE_NOT_EXIST },
355         { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_INVALID_MODULE_NAME, ERROR_MODULE_NOT_EXIST},
356         { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_ERROR_HAP_TYPE, ERROR_INVALID_TYPE },
357         { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_ERROR_BUNDLE_TYPE, ERROR_INVALID_TYPE },
358         { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_TARGET_BUNDLE_NAME_MISSED, ERROR_INSTALL_PARSE_FAILED },
359         { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_TARGET_MODULE_NAME_MISSED, ERROR_INSTALL_PARSE_FAILED },
360         { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_TARGET_BUNDLE_NAME_NOT_SAME,
361             ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
362         { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_INTERNAL_EXTERNAL_OVERLAY_EXISTED_SIMULTANEOUSLY,
363             ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
364         { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_TARGET_PRIORITY_NOT_SAME,
365             ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
366         { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_INVALID_PRIORITY, ERROR_INSTALL_PARSE_FAILED },
367         { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_INCONSISTENT_VERSION_CODE,
368             ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
369         { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_SERVICE_EXCEPTION, ERROR_BUNDLE_SERVICE_EXCEPTION },
370         { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_BUNDLE_NAME_SAME_WITH_TARGET_BUNDLE_NAME,
371             ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT},
372         { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_NO_SYSTEM_APPLICATION_FOR_EXTERNAL_OVERLAY,
373             ERROR_INSTALL_HAP_OVERLAY_CHECK_FAILED },
374         { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_DIFFERENT_SIGNATURE_CERTIFICATE,
375             ERROR_INSTALL_VERIFY_SIGNATURE_FAILED },
376         { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_TARGET_BUNDLE_IS_OVERLAY_BUNDLE,
377             ERROR_INSTALL_HAP_OVERLAY_CHECK_FAILED },
378         {IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_TARGET_MODULE_IS_OVERLAY_MODULE,
379             ERROR_INSTALL_HAP_OVERLAY_CHECK_FAILED },
380         { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_OVERLAY_TYPE_NOT_SAME,
381             ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
382         { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_INVALID_BUNDLE_DIR, ERROR_BUNDLE_SERVICE_EXCEPTION },
383         { IStatusReceiver::ERR_APPEXECFWK_UNINSTALL_SHARE_APP_LIBRARY_IS_NOT_EXIST,
384             ERROR_UNINSTALL_SHARE_APP_LIBRARY_IS_NOT_EXIST},
385         { IStatusReceiver::ERR_APPEXECFWK_UNINSTALL_SHARE_APP_LIBRARY_IS_RELIED,
386             ERROR_UNINSTALL_SHARE_APP_LIBRARY_IS_RELIED},
387         { IStatusReceiver::ERR_APPEXECFWK_UNINSTALL_BUNDLE_IS_SHARED_LIBRARY,
388             ERROR_UNINSTALL_BUNDLE_IS_SHARED_BUNDLE},
389         { IStatusReceiver::ERR_INSATLL_CHECK_PROXY_DATA_URI_FAILED,
390             ERROR_INSTALL_WRONG_DATA_PROXY_URI},
391         { IStatusReceiver::ERR_INSATLL_CHECK_PROXY_DATA_PERMISSION_FAILED,
392             ERROR_INSTALL_WRONG_DATA_PROXY_PERMISSION},
393         { IStatusReceiver::ERR_INSTALL_FAILED_DEBUG_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT },
394         { IStatusReceiver::ERR_INSTALL_DISALLOWED, ERROR_DISALLOW_INSTALL},
395         { IStatusReceiver::ERR_INSTALL_ISOLATION_MODE_FAILED, ERROR_INSTALL_WRONG_MODE_ISOLATION },
396         { IStatusReceiver::ERR_UNINSTALL_DISALLOWED, ERROR_DISALLOW_UNINSTALL },
397         { IStatusReceiver::ERR_INSTALL_CODE_SIGNATURE_FAILED, ERROR_INSTALL_CODE_SIGNATURE_FAILED },
398         { IStatusReceiver::ERR_INSTALL_CODE_SIGNATURE_FILE_IS_INVALID, ERROR_INSTALL_CODE_SIGNATURE_FAILED},
399         { IStatusReceiver::ERR_UNINSTALL_FROM_BMS_EXTENSION_FAILED, ERROR_BUNDLE_NOT_EXIST},
400         { IStatusReceiver::ERR_INSTALL_SELF_UPDATE_NOT_MDM, ERROR_INSTALL_SELF_UPDATE_NOT_MDM},
401         { IStatusReceiver::ERR_INSTALL_ENTERPRISE_BUNDLE_NOT_ALLOWED, ERROR_INSTALL_ENTERPRISE_BUNDLE_NOT_ALLOWED},
402         { IStatusReceiver::ERR_INSTALL_EXISTED_ENTERPRISE_BUNDLE_NOT_ALLOWED,
403             ERROR_INSTALL_EXISTED_ENTERPRISE_NOT_ALLOWED_ERROR},
404         { IStatusReceiver::ERR_INSTALL_SELF_UPDATE_BUNDLENAME_NOT_SAME, ERROR_INSTALL_SELF_UPDATE_BUNDLENAME_NOT_SAME},
405         { IStatusReceiver::ERR_INSTALL_GWP_ASAN_ENABLED_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT},
406         { IStatusReceiver::ERR_INSTALL_DEBUG_BUNDLE_NOT_ALLOWED, ERROR_INSTALL_DEBUG_BUNDLE_NOT_ALLOWED},
407         { IStatusReceiver::ERR_INSTALL_CHECK_ENCRYPTION_FAILED, ERROR_INSTALL_CODE_SIGNATURE_FAILED },
408         { IStatusReceiver::ERR_INSTALL_CODE_SIGNATURE_DELIVERY_FILE_FAILED, ERROR_INSTALL_CODE_SIGNATURE_FAILED},
409         { IStatusReceiver::ERR_INSTALL_CODE_SIGNATURE_REMOVE_FILE_FAILED, ERROR_INSTALL_CODE_SIGNATURE_FAILED},
410         { IStatusReceiver::ERR_INSTALL_CODE_APP_CONTROLLED_FAILED, ERROR_INSTALL_FAILED_CONTROLLED},
411         { IStatusReceiver::ERR_INSTALL_NATIVE_FAILED, ERROR_INSTALL_NATIVE_FAILED},
412         { IStatusReceiver::ERR_UNINSTALL_NATIVE_FAILED, ERROR_UNINSTALL_NATIVE_FAILED},
413         { IStatusReceiver::ERR_NATIVE_HNP_EXTRACT_FAILED, ERROR_INSTALL_NATIVE_FAILED},
414         { IStatusReceiver::ERR_UNINSTALL_CONTROLLED, ERROR_BUNDLE_CAN_NOT_BE_UNINSTALLED },
415         { IStatusReceiver::ERR_INSTALL_DEBUG_ENCRYPTED_BUNDLE_FAILED, ERROR_INSTALL_PARSE_FAILED }
416     };
417 }
418 
ConvertInstallResult(InstallResult & installResult)419 static void ConvertInstallResult(InstallResult &installResult)
420 {
421     APP_LOGD("ConvertInstallResult msg %{public}s, errCode is %{public}d", installResult.resultMsg.c_str(),
422         installResult.resultCode);
423     std::unordered_map<int32_t, int32_t> errCodeMap;
424     CreateErrCodeMap(errCodeMap);
425     auto iter = errCodeMap.find(installResult.resultCode);
426     if (iter != errCodeMap.end()) {
427         installResult.resultCode = iter->second;
428         return;
429     }
430     installResult.resultCode = ERROR_BUNDLE_SERVICE_EXCEPTION;
431 }
432 
ParseHashParam(napi_env env,napi_value args,std::string & key,std::string & value)433 static bool ParseHashParam(napi_env env, napi_value args, std::string &key, std::string &value)
434 {
435     APP_LOGD("start to parse moduleName");
436     bool ret = CommonFunc::ParseStringPropertyFromObject(env, args, MODULE_NAME, true, key);
437     if (!ret || key.empty()) {
438         APP_LOGE("param string moduleName is empty");
439         return false;
440     }
441     APP_LOGD("ParseHashParam moduleName=%{public}s", key.c_str());
442 
443     APP_LOGD("start to parse hashValue");
444     ret = CommonFunc::ParseStringPropertyFromObject(env, args, HASH_VALUE, true, value);
445     if (!ret || value.empty()) {
446         APP_LOGE("param string hashValue is empty");
447         return false;
448     }
449     APP_LOGD("ParseHashParam hashValue=%{public}s", value.c_str());
450     return true;
451 }
452 
ParseHashParams(napi_env env,napi_value args,std::map<std::string,std::string> & hashParams)453 static bool ParseHashParams(napi_env env, napi_value args, std::map<std::string, std::string> &hashParams)
454 {
455     APP_LOGD("start to parse hashParams");
456     std::vector<napi_value> valueVec;
457     bool res = CommonFunc::ParsePropertyArray(env, args, HASH_PARAMS, valueVec);
458     if (!res) {
459         APP_LOGW("hashParams type error,using default value");
460         return true;
461     }
462     if (valueVec.empty()) {
463         APP_LOGW("hashParams is empty,using default value");
464         return true;
465     }
466     for (const auto &property : valueVec) {
467         std::string key;
468         std::string value;
469         if (!ParseHashParam(env, property, key, value)) {
470             APP_LOGE("parse hash param failed");
471             return false;
472         }
473         if (hashParams.find(key) != hashParams.end()) {
474             APP_LOGE("moduleName(%{public}s) is duplicate", key.c_str());
475             return false;
476         }
477         hashParams.emplace(key, value);
478     }
479     return true;
480 }
481 
ParseVerifyCodeParam(napi_env env,napi_value args,std::string & key,std::string & value)482 static bool ParseVerifyCodeParam(napi_env env, napi_value args, std::string &key, std::string &value)
483 {
484     APP_LOGD("start to parse moduleName");
485     bool ret = CommonFunc::ParseStringPropertyFromObject(env, args, MODULE_NAME, true, key);
486     if (!ret || key.empty()) {
487         APP_LOGE("param string moduleName is empty");
488         return false;
489     }
490     APP_LOGD("ParseVerifyCodeParam moduleName is %{public}s", key.c_str());
491 
492     APP_LOGD("start to parse signatureFilePath");
493     ret = CommonFunc::ParseStringPropertyFromObject(env, args, SIGNATURE_FILE_PATH, true, value);
494     if (!ret || value.empty()) {
495         APP_LOGE("param string signatureFilePath is empty");
496         return false;
497     }
498     APP_LOGD("ParseVerifyCodeParam signatureFilePath is %{public}s", value.c_str());
499     return true;
500 }
501 
ParseVerifyCodeParams(napi_env env,napi_value args,std::map<std::string,std::string> & verifyCodeParams)502 static bool ParseVerifyCodeParams(napi_env env, napi_value args, std::map<std::string, std::string> &verifyCodeParams)
503 {
504     APP_LOGD("start to parse verifyCodeParams");
505     std::vector<napi_value> valueVec;
506     bool res = CommonFunc::ParsePropertyArray(env, args, VERIFY_CODE_PARAM, valueVec);
507     if (!res) {
508         APP_LOGW("verifyCodeParams type error, using default value");
509         return true;
510     }
511     if (valueVec.empty()) {
512         APP_LOGW("verifyCodeParams is empty, using default value");
513         return true;
514     }
515     for (const auto &property : valueVec) {
516         std::string key;
517         std::string value;
518         if (!ParseVerifyCodeParam(env, property, key, value)) {
519             APP_LOGE("parse verify code param failed");
520             return false;
521         }
522         if (verifyCodeParams.find(key) != verifyCodeParams.end()) {
523             APP_LOGE("moduleName(%{public}s) is duplicate", key.c_str());
524             return false;
525         }
526         verifyCodeParams.emplace(key, value);
527     }
528     return true;
529 }
530 
ParsePgoParam(napi_env env,napi_value args,std::string & key,std::string & value)531 static bool ParsePgoParam(napi_env env, napi_value args, std::string &key, std::string &value)
532 {
533     APP_LOGD("start to parse moduleName");
534     bool ret = CommonFunc::ParseStringPropertyFromObject(env, args, MODULE_NAME, true, key);
535     if (!ret || key.empty()) {
536         APP_LOGE("param string moduleName is empty");
537         return false;
538     }
539     APP_LOGD("ParsePgoParam moduleName is %{public}s", key.c_str());
540 
541     APP_LOGD("start to parse pgoFilePath");
542     ret = CommonFunc::ParseStringPropertyFromObject(env, args, PGO_FILE_PATH, true, value);
543     if (!ret || value.empty()) {
544         APP_LOGE("param string pgoFilePath is empty");
545         return false;
546     }
547     APP_LOGD("ParsePgoParam pgoFilePath is %{public}s", value.c_str());
548     return true;
549 }
550 
ParsePgoParams(napi_env env,napi_value args,std::map<std::string,std::string> & pgoParams)551 static bool ParsePgoParams(napi_env env, napi_value args, std::map<std::string, std::string> &pgoParams)
552 {
553     APP_LOGD("start to parse pgoParams");
554     std::vector<napi_value> valueVec;
555     bool res = CommonFunc::ParsePropertyArray(env, args, PGO_PARAM, valueVec);
556     if (!res) {
557         APP_LOGW("pgoParams type error, using default value");
558         return true;
559     }
560     if (valueVec.empty()) {
561         APP_LOGW("pgoParams is empty, using default value");
562         return true;
563     }
564     for (const auto &property : valueVec) {
565         std::string key;
566         std::string value;
567         if (!ParsePgoParam(env, property, key, value)) {
568             APP_LOGW("parse pgo param failed");
569             continue;
570         }
571         pgoParams.emplace(key, value);
572     }
573     return true;
574 }
575 
ParseBundleName(napi_env env,napi_value args,std::string & bundleName)576 static bool ParseBundleName(napi_env env, napi_value args, std::string &bundleName)
577 {
578     APP_LOGD("start to parse bundleName");
579     PropertyInfo propertyInfo = {
580         .propertyName = BUNDLE_NAME,
581         .isNecessary = true,
582         .propertyType = napi_string
583     };
584     napi_value property = nullptr;
585     bool res = CommonFunc::ParsePropertyFromObject(env, args, propertyInfo, property);
586     if (!res) {
587         APP_LOGE("parse bundleName failed, bundleName is %{public}s", bundleName.c_str());
588         return res;
589     }
590     if (property != nullptr) {
591         if (!CommonFunc::ParseString(env, property, bundleName)) {
592             APP_LOGE("ParseString failed");
593             return false;
594         }
595     }
596     APP_LOGD("param bundleName is %{public}s", bundleName.c_str());
597     return true;
598 }
599 
ParseModuleName(napi_env env,napi_value args,std::string & moduleName)600 static bool ParseModuleName(napi_env env, napi_value args, std::string &moduleName)
601 {
602     APP_LOGD("start to parse moduleName");
603     PropertyInfo propertyInfo = {
604         .propertyName = MODULE_NAME,
605         .isNecessary = false,
606         .propertyType = napi_string
607     };
608     napi_value property = nullptr;
609     bool res = CommonFunc::ParsePropertyFromObject(env, args, propertyInfo, property);
610     if (!res) {
611         APP_LOGE("parse moduleName failed");
612         return res;
613     }
614     if (property != nullptr) {
615         if (!CommonFunc::ParseString(env, property, moduleName)) {
616             APP_LOGE("ParseString failed");
617             return false;
618         }
619     }
620     return true;
621 }
622 
ParseVersionCode(napi_env env,napi_value args,int32_t & versionCode)623 static bool ParseVersionCode(napi_env env, napi_value args, int32_t &versionCode)
624 {
625     APP_LOGD("start to parse versionCode");
626     PropertyInfo propertyInfo = {
627         .propertyName = VERSION_CODE,
628         .isNecessary = false,
629         .propertyType = napi_number
630     };
631     napi_value property = nullptr;
632     bool res = CommonFunc::ParsePropertyFromObject(env, args, propertyInfo, property);
633     if (!res) {
634         APP_LOGE("parse versionCode failed");
635         return res;
636     }
637     if (property != nullptr) {
638         PARSE_PROPERTY(env, property, int32, versionCode);
639     }
640     APP_LOGD("param versionCode is %{public}d", versionCode);
641     return true;
642 }
643 
ParseUserId(napi_env env,napi_value args,int32_t & userId)644 static bool ParseUserId(napi_env env, napi_value args, int32_t &userId)
645 {
646     APP_LOGD("start to parse userId");
647     PropertyInfo propertyInfo = {
648         .propertyName = USER_ID,
649         .isNecessary = false,
650         .propertyType = napi_number
651     };
652     napi_value property = nullptr;
653     bool res = CommonFunc::ParsePropertyFromObject(env, args, propertyInfo, property);
654     if (!res) {
655         APP_LOGE("parse userId failed");
656         return res;
657     }
658     if (property != nullptr) {
659         PARSE_PROPERTY(env, property, int32, userId);
660     }
661     APP_LOGD("param userId is %{public}d", userId);
662     return true;
663 }
664 
ParseAppIndex(napi_env env,napi_value args,int32_t & appIndex)665 static bool ParseAppIndex(napi_env env, napi_value args, int32_t &appIndex)
666 {
667     APP_LOGD("start to parse appIndex");
668     PropertyInfo propertyInfo = {
669         .propertyName = APP_INDEX,
670         .isNecessary = true,
671         .propertyType = napi_number
672     };
673     napi_value property = nullptr;
674     bool res = CommonFunc::ParsePropertyFromObject(env, args, propertyInfo, property);
675     if (!res) {
676         APP_LOGE("parse appIndex failed");
677         return res;
678     }
679     if (property != nullptr) {
680         PARSE_PROPERTY(env, property, int32, appIndex);
681     }
682     APP_LOGD("param appIndex is %{public}d", appIndex);
683     return true;
684 }
685 
ParseInstallFlag(napi_env env,napi_value args,InstallFlag & installFlag)686 static bool ParseInstallFlag(napi_env env, napi_value args, InstallFlag &installFlag)
687 {
688     APP_LOGD("start to parse installFlag");
689     PropertyInfo propertyInfo = {
690         .propertyName = INSTALL_FLAG,
691         .isNecessary = false,
692         .propertyType = napi_number
693     };
694     napi_value property = nullptr;
695     bool res = CommonFunc::ParsePropertyFromObject(env, args, propertyInfo, property);
696     if (!res) {
697         APP_LOGE("parse installFlag failed");
698         return res;
699     }
700 
701     if (property != nullptr) {
702         int32_t flag = 0;
703         PARSE_PROPERTY(env, property, int32, flag);
704         APP_LOGD("param installFlag is %{public}d", flag);
705         if ((flag != static_cast<int32_t>(OHOS::AppExecFwk::InstallFlag::NORMAL)) &&
706             (flag != static_cast<int32_t>(OHOS::AppExecFwk::InstallFlag::REPLACE_EXISTING)) &&
707             (flag != static_cast<int32_t>(OHOS::AppExecFwk::InstallFlag::FREE_INSTALL))) {
708             APP_LOGE("invalid installFlag param");
709             return false;
710         }
711         installFlag = static_cast<OHOS::AppExecFwk::InstallFlag>(flag);
712     }
713     return true;
714 }
715 
ParseIsKeepData(napi_env env,napi_value args,bool & isKeepData)716 static bool ParseIsKeepData(napi_env env, napi_value args, bool &isKeepData)
717 {
718     APP_LOGD("start to parse isKeepData");
719     PropertyInfo propertyInfo = {
720         .propertyName = IS_KEEP_DATA,
721         .isNecessary = false,
722         .propertyType = napi_boolean
723     };
724     napi_value property = nullptr;
725     bool res = CommonFunc::ParsePropertyFromObject(env, args, propertyInfo, property);
726     if (!res) {
727         APP_LOGE("parse isKeepData failed");
728         return res;
729     }
730     if (property != nullptr) {
731         PARSE_PROPERTY(env, property, bool, isKeepData);
732     }
733     APP_LOGD("param isKeepData is %{public}d", isKeepData);
734     return true;
735 }
736 
ParseCrowdtestDeadline(napi_env env,napi_value args,int64_t & crowdtestDeadline)737 static bool ParseCrowdtestDeadline(napi_env env, napi_value args, int64_t &crowdtestDeadline)
738 {
739     APP_LOGD("start to parse crowdtestDeadline");
740     PropertyInfo propertyInfo = {
741         .propertyName = CROWD_TEST_DEADLINE,
742         .isNecessary = false,
743         .propertyType = napi_number
744     };
745     napi_value property = nullptr;
746     bool res = CommonFunc::ParsePropertyFromObject(env, args, propertyInfo, property);
747     if (!res) {
748         APP_LOGE("parse crowdtestDeadline failed");
749         return res;
750     }
751     if (property != nullptr) {
752         PARSE_PROPERTY(env, property, int64, crowdtestDeadline);
753     }
754     return true;
755 }
756 
ParseSharedBundleDirPaths(napi_env env,napi_value args,std::vector<std::string> & sharedBundleDirPaths)757 static bool ParseSharedBundleDirPaths(napi_env env, napi_value args, std::vector<std::string> &sharedBundleDirPaths)
758 {
759     APP_LOGD("start to parse sharedBundleDirPaths");
760     std::vector<napi_value> valueVec;
761     bool res = CommonFunc::ParsePropertyArray(env, args, SHARED_BUNDLE_DIR_PATHS, valueVec);
762     if (!res) {
763         APP_LOGE("parse sharedBundleDirPaths failed");
764         return res;
765     }
766     if (valueVec.empty()) {
767         APP_LOGD("sharedBundleDirPaths is empty");
768         return true;
769     }
770     for (const auto &value : valueVec) {
771         std::string path;
772         if (!CommonFunc::ParseString(env, value, path)) {
773             APP_LOGE("parse sharedBundleDirPaths element failed");
774             return false;
775         }
776         sharedBundleDirPaths.emplace_back(path);
777     }
778     return true;
779 }
780 
ParseSpecifiedDistributionType(napi_env env,napi_value args,std::string & specifiedDistributionType)781 static bool ParseSpecifiedDistributionType(napi_env env, napi_value args, std::string &specifiedDistributionType)
782 {
783     APP_LOGD("start to parse specifiedDistributionType");
784     PropertyInfo propertyInfo = {
785         .propertyName = SPECIFIED_DISTRIBUTION_TYPE,
786         .isNecessary = false,
787         .propertyType = napi_string
788     };
789     napi_value property = nullptr;
790     bool res = CommonFunc::ParsePropertyFromObject(env, args, propertyInfo, property);
791     if (!res) {
792         APP_LOGE("parse specifiedDistributionType failed");
793         return res;
794     }
795     if (property != nullptr) {
796         if (!CommonFunc::ParseString(env, property, specifiedDistributionType)) {
797             APP_LOGE("ParseString failed");
798             return false;
799         }
800     }
801     APP_LOGD("param specifiedDistributionType is %{public}s", specifiedDistributionType.c_str());
802     return true;
803 }
804 
ParseAdditionalInfo(napi_env env,napi_value args,std::string & additionalInfo)805 static bool ParseAdditionalInfo(napi_env env, napi_value args, std::string &additionalInfo)
806 {
807     APP_LOGD("start to parse the additionalInfo");
808     PropertyInfo propertyInfo = {
809         .propertyName = ADDITIONAL_INFO,
810         .isNecessary = false,
811         .propertyType = napi_string
812     };
813     napi_value property = nullptr;
814     bool res = CommonFunc::ParsePropertyFromObject(env, args, propertyInfo, property);
815     if (!res) {
816         APP_LOGE("parse additionalInfo failed");
817         return res;
818     }
819     if (property != nullptr) {
820         if (!CommonFunc::ParseString(env, property, additionalInfo)) {
821             APP_LOGE("ParseString failed");
822             return false;
823         }
824     }
825     APP_LOGD("param additionalInfo is %{public}s", additionalInfo.c_str());
826     return true;
827 }
828 
CheckInstallParam(napi_env env,InstallParam & installParam)829 static bool CheckInstallParam(napi_env env, InstallParam &installParam)
830 {
831     if (installParam.specifiedDistributionType.size() > SPECIFIED_DISTRIBUTION_TYPE_MAX_SIZE) {
832         APP_LOGE("Parse specifiedDistributionType size failed");
833         BusinessError::ThrowError(env, ERROR_PARAM_CHECK_ERROR,
834             "BusinessError 401: The size of specifiedDistributionType is greater than 128");
835         return false;
836     }
837     if (installParam.additionalInfo.size() > ADDITIONAL_INFO_MAX_SIZE) {
838         APP_LOGE("Parse additionalInfo size failed");
839         BusinessError::ThrowError(env, ERROR_PARAM_CHECK_ERROR,
840             "BusinessError 401: The size of additionalInfo is greater than 3000");
841         return false;
842     }
843     return true;
844 }
845 
ParseInstallParam(napi_env env,napi_value args,InstallParam & installParam)846 static bool ParseInstallParam(napi_env env, napi_value args, InstallParam &installParam)
847 {
848     if (!ParseHashParams(env, args, installParam.hashParams)) {
849         return false;
850     }
851     if (!ParseVerifyCodeParams(env, args, installParam.verifyCodeParams)) {
852         return false;
853     }
854     if (!ParsePgoParams(env, args, installParam.pgoParams)) {
855         return false;
856     }
857     if (!ParseUserId(env, args, installParam.userId)) {
858         APP_LOGW("Parse userId failed,using default value");
859     }
860     if (!ParseInstallFlag(env, args, installParam.installFlag)) {
861         APP_LOGW("Parse installFlag failed,using default value");
862     }
863     if (!ParseIsKeepData(env, args, installParam.isKeepData)) {
864         APP_LOGW("Parse isKeepData failed,using default value");
865     }
866     if (!ParseCrowdtestDeadline(env, args, installParam.crowdtestDeadline)) {
867         APP_LOGW("Parse crowdtestDeadline failed,using default value");
868     }
869     if (!ParseSharedBundleDirPaths(env, args, installParam.sharedBundleDirPaths)) {
870         APP_LOGW("Parse sharedBundleDirPaths failed,using default value");
871     }
872     if (!ParseSpecifiedDistributionType(env, args, installParam.specifiedDistributionType)) {
873         APP_LOGW("Parse specifiedDistributionType failed,using default value");
874     }
875     if (!ParseAdditionalInfo(env, args, installParam.additionalInfo)) {
876         APP_LOGW("Parse additionalInfo failed,using default value");
877     }
878     return true;
879 }
880 
ParseUninstallParam(napi_env env,napi_value args,UninstallParam & uninstallParam)881 static bool ParseUninstallParam(napi_env env, napi_value args, UninstallParam &uninstallParam)
882 {
883     if (!ParseBundleName(env, args, uninstallParam.bundleName) ||
884         !ParseModuleName(env, args, uninstallParam.moduleName) ||
885         !ParseVersionCode(env, args, uninstallParam.versionCode) ||
886         !ParseUserId(env, args, uninstallParam.userId)) {
887             APP_LOGE("Parse UninstallParam faied");
888             return false;
889     }
890     return true;
891 }
892 
CreateProxyErrCode(std::unordered_map<int32_t,int32_t> & errCodeMap)893 static void CreateProxyErrCode(std::unordered_map<int32_t, int32_t> &errCodeMap)
894 {
895     errCodeMap = {
896         { ERR_APPEXECFWK_INSTALL_PARAM_ERROR, IStatusReceiver::ERR_INSTALL_PARAM_ERROR },
897         { ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR, IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR },
898         { ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID, IStatusReceiver::ERR_INSTALL_FILE_PATH_INVALID },
899         { ERR_APPEXECFWK_INSTALL_DISK_MEM_INSUFFICIENT, IStatusReceiver::ERR_INSTALL_DISK_MEM_INSUFFICIENT },
900         { ERR_BUNDLEMANAGER_INSTALL_CODE_SIGNATURE_FILE_IS_INVALID,
901             IStatusReceiver::ERR_INSTALL_CODE_SIGNATURE_FILE_IS_INVALID}
902     };
903 }
904 
InstallExecuter(napi_env env,void * data)905 void InstallExecuter(napi_env env, void *data)
906 {
907     AsyncInstallCallbackInfo *asyncCallbackInfo = reinterpret_cast<AsyncInstallCallbackInfo *>(data);
908     if (asyncCallbackInfo == nullptr) {
909         APP_LOGE("asyncCallbackInfo is nullptr");
910         return;
911     }
912     const std::vector<std::string> bundleFilePath = asyncCallbackInfo->hapFiles;
913     InstallResult &installResult = asyncCallbackInfo->installResult;
914     if (bundleFilePath.empty() && asyncCallbackInfo->installParam.sharedBundleDirPaths.empty()) {
915         installResult.resultCode = static_cast<int32_t>(IStatusReceiver::ERR_INSTALL_FILE_PATH_INVALID);
916         return;
917     }
918     auto iBundleInstaller = CommonFunc::GetBundleInstaller();
919     if ((iBundleInstaller == nullptr) || (iBundleInstaller->AsObject() == nullptr)) {
920         APP_LOGE("can not get iBundleInstaller");
921         installResult.resultCode = static_cast<int32_t>(IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR);
922         return;
923     }
924 
925     sptr<InstallerCallback> callback = new (std::nothrow) InstallerCallback();
926     sptr<BundleDeathRecipient> recipient(new (std::nothrow) BundleDeathRecipient(callback));
927     if (callback == nullptr || recipient == nullptr) {
928         APP_LOGE("callback or death recipient is nullptr");
929         installResult.resultCode = static_cast<int32_t>(IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR);
930         return;
931     }
932     iBundleInstaller->AsObject()->AddDeathRecipient(recipient);
933 
934     ErrCode res = iBundleInstaller->StreamInstall(bundleFilePath, asyncCallbackInfo->installParam, callback);
935     if (res == ERR_OK) {
936         installResult.resultCode = callback->GetResultCode();
937         APP_LOGD("InnerInstall resultCode %{public}d", installResult.resultCode);
938         installResult.resultMsg = callback->GetResultMsg();
939         APP_LOGD("InnerInstall resultMsg %{public}s", installResult.resultMsg.c_str());
940         return;
941     }
942     APP_LOGE("install failed due to %{public}d", res);
943     std::unordered_map<int32_t, int32_t> proxyErrCodeMap;
944     CreateProxyErrCode(proxyErrCodeMap);
945     if (proxyErrCodeMap.find(res) != proxyErrCodeMap.end()) {
946         installResult.resultCode = proxyErrCodeMap.at(res);
947     } else {
948         installResult.resultCode = IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR;
949     }
950 }
951 
GetFunctionName(const InstallOption & option)952 static std::string GetFunctionName(const InstallOption &option)
953 {
954     if (option == InstallOption::INSTALL) {
955         return RESOURCE_NAME_OF_INSTALL;
956     } else if (option == InstallOption::RECOVER) {
957         return RESOURCE_NAME_OF_RECOVER;
958     } else if (option == InstallOption::UNINSTALL) {
959         return RESOURCE_NAME_OF_UNINSTALL;
960     } else if (option == InstallOption::UPDATE_BUNDLE_FOR_SELF) {
961         return RESOURCE_NAME_OF_UPDATE_BUNDLE_FOR_SELF;
962     } else if (option == InstallOption::UNINSTALL_AND_RECOVER) {
963         return RESOURCE_NAME_OF_UNINSTALL_AND_RECOVER;
964     }
965     return EMPTY_STRING;
966 }
967 
OperationCompleted(napi_env env,napi_status status,void * data)968 void OperationCompleted(napi_env env, napi_status status, void *data)
969 {
970     AsyncInstallCallbackInfo *asyncCallbackInfo = reinterpret_cast<AsyncInstallCallbackInfo *>(data);
971     std::unique_ptr<AsyncInstallCallbackInfo> callbackPtr {asyncCallbackInfo};
972     napi_value result[CALLBACK_PARAM_SIZE] = {0};
973     ConvertInstallResult(callbackPtr->installResult);
974     if (callbackPtr->installResult.resultCode != SUCCESS) {
975         switch (callbackPtr->option) {
976             case InstallOption::INSTALL:
977                 result[FIRST_PARAM] = BusinessError::CreateCommonError(env, callbackPtr->installResult.resultCode,
978                     RESOURCE_NAME_OF_INSTALL, INSTALL_PERMISSION);
979                 break;
980             case InstallOption::RECOVER:
981                 result[FIRST_PARAM] = BusinessError::CreateCommonError(env, callbackPtr->installResult.resultCode,
982                     RESOURCE_NAME_OF_RECOVER, RECOVER_PERMISSION);
983                 break;
984             case InstallOption::UNINSTALL:
985                 result[FIRST_PARAM] = BusinessError::CreateCommonError(env, callbackPtr->installResult.resultCode,
986                     RESOURCE_NAME_OF_UNINSTALL, UNINSTALL_PERMISSION);
987                 break;
988             case InstallOption::UPDATE_BUNDLE_FOR_SELF:
989                 result[FIRST_PARAM] = BusinessError::CreateCommonError(env, callbackPtr->installResult.resultCode,
990                     RESOURCE_NAME_OF_UPDATE_BUNDLE_FOR_SELF, INSTALL_SELF_PERMISSION);
991                 break;
992             case InstallOption::UNINSTALL_AND_RECOVER:
993                 result[FIRST_PARAM] = BusinessError::CreateCommonError(env, callbackPtr->installResult.resultCode,
994                     RESOURCE_NAME_OF_UNINSTALL_AND_RECOVER, UNINSTALL_PERMISSION);
995                 break;
996             default:
997                 break;
998         }
999     } else {
1000         NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[FIRST_PARAM]));
1001     }
1002     callbackPtr->err = callbackPtr->installResult.resultCode;
1003     APP_LOGI("installer callback");
1004     CommonFunc::NapiReturnDeferred<AsyncInstallCallbackInfo>(env, asyncCallbackInfo, result, ARGS_SIZE_ONE);
1005 }
1006 
1007 /**
1008  * Promise and async callback
1009  */
Install(napi_env env,napi_callback_info info)1010 napi_value Install(napi_env env, napi_callback_info info)
1011 {
1012     APP_LOGI("Install called");
1013     // obtain arguments of install interface
1014     NapiArg args(env, info);
1015     if (!args.Init(ARGS_SIZE_ONE, ARGS_SIZE_THREE)) {
1016         APP_LOGE("init param failed");
1017         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
1018         return nullptr;
1019     }
1020     auto argc = args.GetMaxArgc();
1021     APP_LOGD("the number of argc is  %{public}zu", argc);
1022     if (argc < ARGS_SIZE_ONE) {
1023         APP_LOGE("the params number is incorrect");
1024         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
1025         return nullptr;
1026     }
1027     std::unique_ptr<AsyncInstallCallbackInfo> callbackPtr = std::make_unique<AsyncInstallCallbackInfo>(env);
1028     callbackPtr->option = InstallOption::INSTALL;
1029     for (size_t i = 0; i < argc; ++i) {
1030         napi_valuetype valueType = napi_undefined;
1031         napi_typeof(env, args[i], &valueType);
1032         if (i == ARGS_POS_ZERO) {
1033             if (!CommonFunc::ParseStringArray(env, callbackPtr->hapFiles, args[i])) {
1034                 APP_LOGE("Flags %{public}s invalid", callbackPtr->bundleName.c_str());
1035                 BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAMETERS, CORRESPONDING_TYPE);
1036                 return nullptr;
1037             }
1038         } else if (i == ARGS_POS_ONE) {
1039             if (valueType == napi_function) {
1040                 NAPI_CALL(env, napi_create_reference(env, args[i], NAPI_RETURN_ONE, &callbackPtr->callback));
1041                 break;
1042             }
1043             if (valueType == napi_object && !ParseInstallParam(env, args[i], callbackPtr->installParam)) {
1044                 APP_LOGE("Parse installParam failed");
1045                 BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAMETERS, CORRESPONDING_TYPE);
1046                 return nullptr;
1047             }
1048         } else if (i == ARGS_POS_TWO) {
1049             if (valueType == napi_function) {
1050                 NAPI_CALL(env, napi_create_reference(env, args[i], NAPI_RETURN_ONE, &callbackPtr->callback));
1051                 break;
1052             }
1053         } else {
1054             APP_LOGE("param check error");
1055             BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAMETERS, CORRESPONDING_TYPE);
1056             return nullptr;
1057         }
1058     }
1059     if (!CheckInstallParam(env, callbackPtr->installParam)) {
1060         return nullptr;
1061     }
1062     if (callbackPtr->hapFiles.empty() && !callbackPtr->installParam.verifyCodeParams.empty()) {
1063         BusinessError::ThrowError(env, ERROR_PARAM_CHECK_ERROR, HAPS_FILE_NEEDED);
1064         return nullptr;
1065     }
1066     auto promise = CommonFunc::AsyncCallNativeMethod(env, callbackPtr.get(), RESOURCE_NAME_OF_INSTALL, InstallExecuter,
1067         OperationCompleted);
1068     callbackPtr.release();
1069     APP_LOGI("call Install done");
1070     return promise;
1071 }
1072 
UninstallOrRecoverExecuter(napi_env env,void * data)1073 void UninstallOrRecoverExecuter(napi_env env, void *data)
1074 {
1075     AsyncInstallCallbackInfo *asyncCallbackInfo = reinterpret_cast<AsyncInstallCallbackInfo *>(data);
1076     if (asyncCallbackInfo == nullptr) {
1077         APP_LOGE("asyncCallbackInfo is nullptr");
1078         return;
1079     }
1080     const std::string bundleName = asyncCallbackInfo->bundleName;
1081     InstallResult &installResult = asyncCallbackInfo->installResult;
1082     if (bundleName.empty()) {
1083         installResult.resultCode = static_cast<int32_t>(IStatusReceiver::ERR_RECOVER_INVALID_BUNDLE_NAME);
1084         return;
1085     }
1086     auto iBundleInstaller = CommonFunc::GetBundleInstaller();
1087     if ((iBundleInstaller == nullptr) || (iBundleInstaller->AsObject() == nullptr)) {
1088         APP_LOGE("can not get iBundleInstaller");
1089         installResult.resultCode = static_cast<int32_t>(IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR);
1090         return;
1091     }
1092 
1093     sptr<InstallerCallback> callback = new (std::nothrow) InstallerCallback();
1094     sptr<BundleDeathRecipient> recipient(new (std::nothrow) BundleDeathRecipient(callback));
1095     if (callback == nullptr || recipient == nullptr) {
1096         APP_LOGE("callback or death recipient is nullptr");
1097         installResult.resultCode = static_cast<int32_t>(IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR);
1098         return;
1099     }
1100     iBundleInstaller->AsObject()->AddDeathRecipient(recipient);
1101     if (asyncCallbackInfo->option == InstallOption::RECOVER) {
1102         iBundleInstaller->Recover(bundleName, asyncCallbackInfo->installParam, callback);
1103     } else if (asyncCallbackInfo->option == InstallOption::UNINSTALL) {
1104         iBundleInstaller->Uninstall(bundleName, asyncCallbackInfo->installParam, callback);
1105     } else {
1106         APP_LOGE("error install option");
1107         installResult.resultCode = static_cast<int32_t>(IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR);
1108         return;
1109     }
1110     installResult.resultMsg = callback->GetResultMsg();
1111     APP_LOGD("InnerRecover resultMsg %{public}s", installResult.resultMsg.c_str());
1112     installResult.resultCode = callback->GetResultCode();
1113     APP_LOGD("InnerRecover resultCode %{public}d", installResult.resultCode);
1114 }
1115 
UninstallByUninstallParamExecuter(napi_env env,void * data)1116 void UninstallByUninstallParamExecuter(napi_env env, void* data)
1117 {
1118     AsyncInstallCallbackInfo *asyncCallbackInfo = reinterpret_cast<AsyncInstallCallbackInfo *>(data);
1119     if (asyncCallbackInfo == nullptr) {
1120         APP_LOGE("asyncCallbackInfo is nullptr");
1121         return;
1122     }
1123     const std::string bundleName = asyncCallbackInfo->uninstallParam.bundleName;
1124     InstallResult &installResult = asyncCallbackInfo->installResult;
1125     if (bundleName.empty()) {
1126         installResult.resultCode =
1127             static_cast<int32_t>(IStatusReceiver::ERR_APPEXECFWK_UNINSTALL_SHARE_APP_LIBRARY_IS_NOT_EXIST);
1128         return;
1129     }
1130     auto iBundleInstaller = CommonFunc::GetBundleInstaller();
1131     if ((iBundleInstaller == nullptr) || (iBundleInstaller->AsObject() == nullptr)) {
1132         APP_LOGE("can not get iBundleInstaller");
1133         installResult.resultCode = static_cast<int32_t>(IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR);
1134         return;
1135     }
1136     sptr<InstallerCallback> callback = new (std::nothrow) InstallerCallback();
1137     sptr<BundleDeathRecipient> recipient(new (std::nothrow) BundleDeathRecipient(callback));
1138     if (callback == nullptr || recipient == nullptr) {
1139         APP_LOGE("callback or death recipient is nullptr");
1140         installResult.resultCode = static_cast<int32_t>(IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR);
1141         return;
1142     }
1143     iBundleInstaller->AsObject()->AddDeathRecipient(recipient);
1144     iBundleInstaller->Uninstall(asyncCallbackInfo->uninstallParam, callback);
1145     installResult.resultMsg = callback->GetResultMsg();
1146     installResult.resultCode = callback->GetResultCode();
1147 }
1148 
UninstallByUninstallParam(napi_env env,napi_callback_info info,std::unique_ptr<AsyncInstallCallbackInfo> & callbackPtr)1149 napi_value UninstallByUninstallParam(napi_env env, napi_callback_info info,
1150     std::unique_ptr<AsyncInstallCallbackInfo> &callbackPtr)
1151 {
1152     NapiArg args(env, info);
1153     if (!args.Init(ARGS_SIZE_ONE, ARGS_SIZE_TWO)) {
1154         APP_LOGE("init param failed");
1155         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
1156         return nullptr;
1157     }
1158     for (size_t i = 0; i < args.GetMaxArgc(); ++i) {
1159         napi_valuetype valueType = napi_undefined;
1160         napi_typeof(env, args[i], &valueType);
1161         if (i == ARGS_POS_ZERO) {
1162             if (!ParseUninstallParam(env, args[i], callbackPtr->uninstallParam)) {
1163                 APP_LOGE("parse uninstallParam failed");
1164                 BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAMETERS, CORRESPONDING_TYPE);
1165                 return nullptr;
1166             }
1167         } else if ((i == ARGS_POS_ONE) && (valueType == napi_function)) {
1168             NAPI_CALL(env, napi_create_reference(env, args[i], NAPI_RETURN_ONE, &callbackPtr->callback));
1169             break;
1170         } else {
1171             APP_LOGE("param check error");
1172             BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAMETERS, CORRESPONDING_TYPE);
1173             return nullptr;
1174         }
1175     }
1176     auto promise = CommonFunc::AsyncCallNativeMethod(env, callbackPtr.get(), GetFunctionName(callbackPtr->option),
1177         UninstallByUninstallParamExecuter, OperationCompleted);
1178     callbackPtr.release();
1179     return promise;
1180 }
1181 
UninstallOrRecover(napi_env env,napi_callback_info info,std::unique_ptr<AsyncInstallCallbackInfo> & callbackPtr)1182 napi_value UninstallOrRecover(napi_env env, napi_callback_info info,
1183     std::unique_ptr<AsyncInstallCallbackInfo> &callbackPtr)
1184 {
1185     APP_LOGD("UninstallOrRecover by bundleName called");
1186     // obtain arguments of install interface
1187     NapiArg args(env, info);
1188     if (!args.Init(ARGS_SIZE_ONE, ARGS_SIZE_THREE)) {
1189         APP_LOGE("init param failed");
1190         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
1191         return nullptr;
1192     }
1193 
1194     auto argc = args.GetMaxArgc();
1195     APP_LOGD("the number of argc is  %{public}zu", argc);
1196     if (argc < ARGS_SIZE_ONE) {
1197         APP_LOGE("the params number is incorrect");
1198         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
1199         return nullptr;
1200     }
1201 
1202     for (size_t i = 0; i < args.GetMaxArgc(); ++i) {
1203         napi_valuetype valueType = napi_undefined;
1204         napi_typeof(env, args[i], &valueType);
1205         if (i == ARGS_POS_ZERO) {
1206             if (!CommonFunc::ParseString(env, args[i], callbackPtr->bundleName)) {
1207                 APP_LOGE("Flags %{public}s invalid", callbackPtr->bundleName.c_str());
1208                 BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAMETERS, CORRESPONDING_TYPE);
1209                 return nullptr;
1210             }
1211         } else if (i == ARGS_POS_ONE) {
1212             if (valueType == napi_function) {
1213                 NAPI_CALL(env, napi_create_reference(env, args[i], NAPI_RETURN_ONE, &callbackPtr->callback));
1214                 break;
1215             }
1216             if (valueType == napi_object && !ParseInstallParam(env, args[i], callbackPtr->installParam)) {
1217                 APP_LOGE("Parse installParam.hashParams failed");
1218                 BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAMETERS, CORRESPONDING_TYPE);
1219                 return nullptr;
1220             }
1221         } else if (i == ARGS_POS_TWO) {
1222             if (valueType == napi_function) {
1223                 NAPI_CALL(env, napi_create_reference(env, args[i], NAPI_RETURN_ONE, &callbackPtr->callback));
1224                 break;
1225             }
1226         } else {
1227             APP_LOGE("param check error");
1228             BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAMETERS, CORRESPONDING_TYPE);
1229             return nullptr;
1230         }
1231     }
1232 
1233     auto promise = CommonFunc::AsyncCallNativeMethod(env, callbackPtr.get(), GetFunctionName(callbackPtr->option),
1234         UninstallOrRecoverExecuter, OperationCompleted);
1235     callbackPtr.release();
1236     return promise;
1237 }
1238 
Recover(napi_env env,napi_callback_info info)1239 napi_value Recover(napi_env env, napi_callback_info info)
1240 {
1241     APP_LOGI("Recover called");
1242     std::unique_ptr<AsyncInstallCallbackInfo> callbackPtr = std::make_unique<AsyncInstallCallbackInfo>(env);
1243     callbackPtr->option = InstallOption::RECOVER;
1244     APP_LOGI("call Recover done");
1245     return UninstallOrRecover(env, info, callbackPtr);
1246 }
1247 
Uninstall(napi_env env,napi_callback_info info)1248 napi_value Uninstall(napi_env env, napi_callback_info info)
1249 {
1250     APP_LOGI_NOFUNC("Uninstall called");
1251     std::unique_ptr<AsyncInstallCallbackInfo> callbackPtr = std::make_unique<AsyncInstallCallbackInfo>(env);
1252     callbackPtr->option = InstallOption::UNINSTALL;
1253     // uninstall uninstallParam
1254     NapiArg args(env, info);
1255     args.Init(ARGS_SIZE_ONE, ARGS_SIZE_THREE);
1256     napi_valuetype firstType = napi_undefined;
1257     napi_typeof(env, args[FIRST_PARAM], &firstType);
1258     if (firstType == napi_object) {
1259         return UninstallByUninstallParam(env, info, callbackPtr);
1260     }
1261     APP_LOGI_NOFUNC("call Uninstall done");
1262     return UninstallOrRecover(env, info, callbackPtr);
1263 }
1264 
BundleInstallerConstructor(napi_env env,napi_callback_info info)1265 napi_value BundleInstallerConstructor(napi_env env, napi_callback_info info)
1266 {
1267     napi_value jsthis = nullptr;
1268     NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &jsthis, nullptr));
1269     return jsthis;
1270 }
1271 
1272 /**
1273  * Promise and async callback
1274  */
UpdateBundleForSelf(napi_env env,napi_callback_info info)1275 napi_value UpdateBundleForSelf(napi_env env, napi_callback_info info)
1276 {
1277     APP_LOGI("UpdateBundleForSelf called");
1278     // obtain arguments of install interface
1279     NapiArg args(env, info);
1280     if (!args.Init(ARGS_SIZE_TWO, ARGS_SIZE_THREE)) {
1281         APP_LOGE("init param failed");
1282         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
1283         return nullptr;
1284     }
1285     auto argc = args.GetMaxArgc();
1286     std::unique_ptr<AsyncInstallCallbackInfo> callbackPtr = std::make_unique<AsyncInstallCallbackInfo>(env);
1287     callbackPtr->option = InstallOption::UPDATE_BUNDLE_FOR_SELF;
1288     for (size_t i = 0; i < argc; ++i) {
1289         napi_valuetype valueType = napi_undefined;
1290         napi_typeof(env, args[i], &valueType);
1291         if (i == ARGS_POS_ZERO) {
1292             if (!CommonFunc::ParseStringArray(env, callbackPtr->hapFiles, args[i])) {
1293                 APP_LOGE("Flags %{public}s invalid", callbackPtr->bundleName.c_str());
1294                 BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAMETERS, CORRESPONDING_TYPE);
1295                 return nullptr;
1296             }
1297         } else if (i == ARGS_POS_ONE) {
1298             if (valueType == napi_function) {
1299                 NAPI_CALL(env, napi_create_reference(env, args[i], NAPI_RETURN_ONE, &callbackPtr->callback));
1300                 break;
1301             }
1302             if (valueType == napi_object && !ParseInstallParam(env, args[i], callbackPtr->installParam)) {
1303                 APP_LOGE("Parse installParam failed");
1304                 BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAMETERS, CORRESPONDING_TYPE);
1305                 return nullptr;
1306             }
1307         } else if (i == ARGS_POS_TWO) {
1308             if (valueType == napi_function) {
1309                 NAPI_CALL(env, napi_create_reference(env, args[i], NAPI_RETURN_ONE, &callbackPtr->callback));
1310                 break;
1311             }
1312         } else {
1313             APP_LOGE("param check error");
1314             BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAMETERS, CORRESPONDING_TYPE);
1315             return nullptr;
1316         }
1317     }
1318     if (!CheckInstallParam(env, callbackPtr->installParam)) {
1319         return nullptr;
1320     }
1321     if (callbackPtr->hapFiles.empty() && !callbackPtr->installParam.verifyCodeParams.empty()) {
1322         BusinessError::ThrowError(env, ERROR_PARAM_CHECK_ERROR, HAPS_FILE_NEEDED);
1323         return nullptr;
1324     }
1325     callbackPtr->installParam.isSelfUpdate = true;
1326     auto promise = CommonFunc::AsyncCallNativeMethod(env, callbackPtr.get(), RESOURCE_NAME_OF_INSTALL, InstallExecuter,
1327         OperationCompleted);
1328     callbackPtr.release();
1329     APP_LOGI("call UpdateBundleForSelf done");
1330     return promise;
1331 }
1332 
UninstallAndRecoverExecuter(napi_env env,void * data)1333 void UninstallAndRecoverExecuter(napi_env env, void *data)
1334 {
1335     AsyncInstallCallbackInfo *asyncCallbackInfo = reinterpret_cast<AsyncInstallCallbackInfo *>(data);
1336     if (asyncCallbackInfo == nullptr) {
1337         APP_LOGE("asyncCallbackInfo is nullptr");
1338         return;
1339     }
1340     const std::string bundleName = asyncCallbackInfo->bundleName;
1341     InstallResult &installResult = asyncCallbackInfo->installResult;
1342     if (bundleName.empty()) {
1343         installResult.resultCode = static_cast<int32_t>(IStatusReceiver::ERR_RECOVER_INVALID_BUNDLE_NAME);
1344         return;
1345     }
1346     auto iBundleInstaller = CommonFunc::GetBundleInstaller();
1347     if ((iBundleInstaller == nullptr) || (iBundleInstaller->AsObject() == nullptr)) {
1348         APP_LOGE("can not get iBundleInstaller");
1349         installResult.resultCode = static_cast<int32_t>(IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR);
1350         return;
1351     }
1352     sptr<InstallerCallback> callback = new (std::nothrow) InstallerCallback();
1353     sptr<BundleDeathRecipient> recipient(new (std::nothrow) BundleDeathRecipient(callback));
1354     if (callback == nullptr || recipient == nullptr) {
1355         APP_LOGE("callback or death recipient is nullptr");
1356         installResult.resultCode = static_cast<int32_t>(IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR);
1357         return;
1358     }
1359     iBundleInstaller->AsObject()->AddDeathRecipient(recipient);
1360     iBundleInstaller->UninstallAndRecover(bundleName, asyncCallbackInfo->installParam, callback);
1361     installResult.resultMsg = callback->GetResultMsg();
1362     installResult.resultCode = callback->GetResultCode();
1363 }
1364 
UninstallAndRecover(napi_env env,napi_callback_info info)1365 napi_value UninstallAndRecover(napi_env env, napi_callback_info info)
1366 {
1367     APP_LOGI("UninstallAndRecover called");
1368     NapiArg args(env, info);
1369     if (!args.Init(ARGS_SIZE_ONE, ARGS_SIZE_TWO)) {
1370         APP_LOGE("init param failed");
1371         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
1372         return nullptr;
1373     }
1374     std::unique_ptr<AsyncInstallCallbackInfo> callbackPtr = std::make_unique<AsyncInstallCallbackInfo>(env);
1375     callbackPtr->option = InstallOption::UNINSTALL_AND_RECOVER;
1376     for (size_t i = 0; i < args.GetArgc(); ++i) {
1377         napi_valuetype valueType = napi_undefined;
1378         napi_typeof(env, args[i], &valueType);
1379         if (i == ARGS_POS_ZERO) {
1380             if (!CommonFunc::ParseString(env, args[i], callbackPtr->bundleName)) {
1381                 APP_LOGE("bundleName %{public}s invalid!", callbackPtr->bundleName.c_str());
1382                 BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
1383                 return nullptr;
1384             }
1385         } else if (i == ARGS_POS_ONE) {
1386             if (valueType != napi_object || !ParseInstallParam(env, args[i], callbackPtr->installParam)) {
1387                 APP_LOGW("Parse installParam failed");
1388             }
1389         } else {
1390             APP_LOGE("The number of parameters is incorrect.");
1391             BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
1392             return nullptr;
1393         }
1394     }
1395     auto promise = CommonFunc::AsyncCallNativeMethod(env, callbackPtr.get(), RESOURCE_NAME_OF_UNINSTALL_AND_RECOVER,
1396         UninstallAndRecoverExecuter, OperationCompleted);
1397     callbackPtr.release();
1398     APP_LOGI("call UninstallAndRecover done");
1399     return promise;
1400 }
1401 
InnerAddExtResource(const std::string & bundleName,const std::vector<std::string> & filePaths)1402 ErrCode InnerAddExtResource(
1403     const std::string &bundleName, const std::vector<std::string> &filePaths)
1404 {
1405     auto extResourceManager = CommonFunc::GetExtendResourceManager();
1406     if (extResourceManager == nullptr) {
1407         APP_LOGE("extResourceManager is null");
1408         return ERROR_BUNDLE_SERVICE_EXCEPTION;
1409     }
1410 
1411     std::vector<std::string> destFiles;
1412     ErrCode ret = extResourceManager->CopyFiles(filePaths, destFiles);
1413     if (ret != ERR_OK) {
1414         APP_LOGE("CopyFiles failed");
1415         return CommonFunc::ConvertErrCode(ret);
1416     }
1417 
1418     ret = extResourceManager->AddExtResource(bundleName, destFiles);
1419     if (ret != ERR_OK) {
1420         APP_LOGE("AddExtResource failed");
1421     }
1422 
1423     return CommonFunc::ConvertErrCode(ret);
1424 }
1425 
AddExtResourceExec(napi_env env,void * data)1426 void AddExtResourceExec(napi_env env, void *data)
1427 {
1428     ExtResourceCallbackInfo *asyncCallbackInfo = reinterpret_cast<ExtResourceCallbackInfo *>(data);
1429     if (asyncCallbackInfo == nullptr) {
1430         APP_LOGE("asyncCallbackInfo is null");
1431         return;
1432     }
1433     asyncCallbackInfo->err = InnerAddExtResource(
1434         asyncCallbackInfo->bundleName, asyncCallbackInfo->filePaths);
1435 }
1436 
AddExtResourceComplete(napi_env env,napi_status status,void * data)1437 void AddExtResourceComplete(napi_env env, napi_status status, void *data)
1438 {
1439     ExtResourceCallbackInfo *asyncCallbackInfo = reinterpret_cast<ExtResourceCallbackInfo *>(data);
1440     if (asyncCallbackInfo == nullptr) {
1441         APP_LOGE("asyncCallbackInfo is null");
1442         return;
1443     }
1444 
1445     std::unique_ptr<ExtResourceCallbackInfo> callbackPtr {asyncCallbackInfo};
1446     napi_value result[ARGS_POS_TWO] = {0};
1447     if (asyncCallbackInfo->err == NO_ERROR) {
1448         NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[0]));
1449     } else {
1450         result[0] = BusinessError::CreateCommonError(
1451             env, asyncCallbackInfo->err, ADD_EXT_RESOURCE, Constants::PERMISSION_INSTALL_BUNDLE);
1452     }
1453 
1454     CommonFunc::NapiReturnDeferred<ExtResourceCallbackInfo>(
1455         env, asyncCallbackInfo, result, ARGS_SIZE_ONE);
1456 }
1457 
AddExtResource(napi_env env,napi_callback_info info)1458 napi_value AddExtResource(napi_env env, napi_callback_info info)
1459 {
1460     APP_LOGD("AddExtResource called");
1461     NapiArg args(env, info);
1462     ExtResourceCallbackInfo *asyncCallbackInfo = new (std::nothrow) ExtResourceCallbackInfo(env);
1463     if (asyncCallbackInfo == nullptr) {
1464         APP_LOGE("asyncCallbackInfo is null");
1465         return nullptr;
1466     }
1467     std::unique_ptr<ExtResourceCallbackInfo> callbackPtr {asyncCallbackInfo};
1468     if (!args.Init(ARGS_SIZE_TWO, ARGS_SIZE_TWO)) {
1469         APP_LOGE("param count invalid");
1470         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
1471         return nullptr;
1472     }
1473     for (size_t i = 0; i < args.GetArgc(); ++i) {
1474         napi_valuetype valueType = napi_undefined;
1475         napi_typeof(env, args[i], &valueType);
1476         if (i == ARGS_POS_ZERO) {
1477             if (!CommonFunc::ParseString(env, args[i], asyncCallbackInfo->bundleName)) {
1478                 APP_LOGE("bundleName invalid");
1479                 BusinessError::ThrowParameterTypeError(
1480                     env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
1481                 return nullptr;
1482             }
1483         } else if (i == ARGS_POS_ONE) {
1484             if (CommonFunc::ParseStringArray(env, asyncCallbackInfo->filePaths, args[i]) == nullptr) {
1485                 APP_LOGE("filePaths invalid");
1486                 BusinessError::ThrowParameterTypeError(
1487                     env, ERROR_PARAM_CHECK_ERROR, FILE_PATH, TYPE_ARRAY);
1488                 return nullptr;
1489             }
1490         }
1491     }
1492     auto promise = CommonFunc::AsyncCallNativeMethod<ExtResourceCallbackInfo>(
1493         env, asyncCallbackInfo, "AddExtResource", AddExtResourceExec, AddExtResourceComplete);
1494     callbackPtr.release();
1495     APP_LOGD("call AddExtResource done");
1496     return promise;
1497 }
1498 
InnerRemoveExtResource(const std::string & bundleName,const std::vector<std::string> & moduleNames)1499 ErrCode InnerRemoveExtResource(
1500     const std::string &bundleName, const std::vector<std::string> &moduleNames)
1501 {
1502     auto extResourceManager = CommonFunc::GetExtendResourceManager();
1503     if (extResourceManager == nullptr) {
1504         APP_LOGE("extResourceManager is null");
1505         return ERROR_BUNDLE_SERVICE_EXCEPTION;
1506     }
1507 
1508     ErrCode ret = extResourceManager->RemoveExtResource(bundleName, moduleNames);
1509     if (ret != ERR_OK) {
1510         APP_LOGE("RemoveExtResource failed");
1511     }
1512 
1513     return CommonFunc::ConvertErrCode(ret);
1514 }
1515 
RemoveExtResourceExec(napi_env env,void * data)1516 void RemoveExtResourceExec(napi_env env, void *data)
1517 {
1518     ExtResourceCallbackInfo *asyncCallbackInfo = reinterpret_cast<ExtResourceCallbackInfo *>(data);
1519     if (asyncCallbackInfo == nullptr) {
1520         APP_LOGE("asyncCallbackInfo is null");
1521         return;
1522     }
1523     asyncCallbackInfo->err = InnerRemoveExtResource(
1524         asyncCallbackInfo->bundleName, asyncCallbackInfo->moduleNames);
1525 }
1526 
RemoveExtResourceComplete(napi_env env,napi_status status,void * data)1527 void RemoveExtResourceComplete(napi_env env, napi_status status, void *data)
1528 {
1529     ExtResourceCallbackInfo *asyncCallbackInfo = reinterpret_cast<ExtResourceCallbackInfo *>(data);
1530     if (asyncCallbackInfo == nullptr) {
1531         APP_LOGE("asyncCallbackInfo is null");
1532         return;
1533     }
1534 
1535     std::unique_ptr<ExtResourceCallbackInfo> callbackPtr {asyncCallbackInfo};
1536     napi_value result[ARGS_POS_TWO] = {0};
1537     if (asyncCallbackInfo->err == NO_ERROR) {
1538         NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[0]));
1539     } else {
1540         result[0] = BusinessError::CreateCommonError(
1541             env, asyncCallbackInfo->err, REMOVE_EXT_RESOURCE, Constants::PERMISSION_INSTALL_BUNDLE);
1542     }
1543 
1544     CommonFunc::NapiReturnDeferred<ExtResourceCallbackInfo>(
1545         env, asyncCallbackInfo, result, ARGS_SIZE_ONE);
1546 }
1547 
RemoveExtResource(napi_env env,napi_callback_info info)1548 napi_value RemoveExtResource(napi_env env, napi_callback_info info)
1549 {
1550     APP_LOGD("RemoveExtResource called");
1551     NapiArg args(env, info);
1552     ExtResourceCallbackInfo *asyncCallbackInfo = new (std::nothrow) ExtResourceCallbackInfo(env);
1553     if (asyncCallbackInfo == nullptr) {
1554         APP_LOGE("asyncCallbackInfo is null");
1555         return nullptr;
1556     }
1557     std::unique_ptr<ExtResourceCallbackInfo> callbackPtr {asyncCallbackInfo};
1558     if (!args.Init(ARGS_SIZE_TWO, ARGS_SIZE_TWO)) {
1559         APP_LOGE("param count invalid");
1560         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
1561         return nullptr;
1562     }
1563     for (size_t i = 0; i < args.GetArgc(); ++i) {
1564         napi_valuetype valueType = napi_undefined;
1565         napi_typeof(env, args[i], &valueType);
1566         if (i == ARGS_POS_ZERO) {
1567             if (!CommonFunc::ParseString(env, args[i], asyncCallbackInfo->bundleName)) {
1568                 APP_LOGE("bundleName invalid");
1569                 BusinessError::ThrowParameterTypeError(
1570                     env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
1571                 return nullptr;
1572             }
1573         } else if (i == ARGS_POS_ONE) {
1574             if (CommonFunc::ParseStringArray(env, asyncCallbackInfo->moduleNames, args[i]) == nullptr) {
1575                 APP_LOGE("moduleNames invalid");
1576                 BusinessError::ThrowParameterTypeError(
1577                     env, ERROR_PARAM_CHECK_ERROR, MODULE_NAME, TYPE_ARRAY);
1578                 return nullptr;
1579             }
1580         }
1581     }
1582     auto promise = CommonFunc::AsyncCallNativeMethod<ExtResourceCallbackInfo>(
1583         env, asyncCallbackInfo, "RemoveExtResource", RemoveExtResourceExec, RemoveExtResourceComplete);
1584     callbackPtr.release();
1585     APP_LOGD("call RemoveExtResource done");
1586     return promise;
1587 }
1588 
InnerCreateAppClone(std::string & bundleName,int32_t userId,int32_t & appIndex)1589 static ErrCode InnerCreateAppClone(std::string &bundleName, int32_t userId, int32_t &appIndex)
1590 {
1591     auto iBundleMgr = CommonFunc::GetBundleMgr();
1592     if (iBundleMgr == nullptr) {
1593         APP_LOGE("can not get iBundleMgr");
1594         return ERROR_BUNDLE_SERVICE_EXCEPTION;
1595     }
1596     auto iBundleInstaller = iBundleMgr->GetBundleInstaller();
1597     if ((iBundleInstaller == nullptr) || (iBundleInstaller->AsObject() == nullptr)) {
1598         APP_LOGE("can not get iBundleInstaller");
1599         return ERROR_BUNDLE_SERVICE_EXCEPTION;
1600     }
1601     ErrCode result = iBundleInstaller->InstallCloneApp(bundleName, userId, appIndex);
1602     APP_LOGD("InstallCloneApp result is %{public}d", result);
1603     return result;
1604 }
1605 
CreateAppCloneExec(napi_env env,void * data)1606 void CreateAppCloneExec(napi_env env, void *data)
1607 {
1608     CreateAppCloneCallbackInfo *asyncCallbackInfo = reinterpret_cast<CreateAppCloneCallbackInfo *>(data);
1609     if (asyncCallbackInfo == nullptr) {
1610         APP_LOGE("asyncCallbackInfo is null");
1611         return;
1612     }
1613     APP_LOGD("CreateAppCloneExec param: bundleName = %{public}s, userId = %{public}d, appIndex = %{public}d",
1614         asyncCallbackInfo->bundleName.c_str(),
1615         asyncCallbackInfo->userId,
1616         asyncCallbackInfo->appIndex);
1617     asyncCallbackInfo->err =
1618         InnerCreateAppClone(asyncCallbackInfo->bundleName, asyncCallbackInfo->userId, asyncCallbackInfo->appIndex);
1619 }
1620 
CreateAppCloneComplete(napi_env env,napi_status status,void * data)1621 void CreateAppCloneComplete(napi_env env, napi_status status, void *data)
1622 {
1623     CreateAppCloneCallbackInfo *asyncCallbackInfo = reinterpret_cast<CreateAppCloneCallbackInfo *>(data);
1624     if (asyncCallbackInfo == nullptr) {
1625         APP_LOGE("asyncCallbackInfo is null");
1626         return;
1627     }
1628     std::unique_ptr<CreateAppCloneCallbackInfo> callbackPtr {asyncCallbackInfo};
1629     asyncCallbackInfo->err = CommonFunc::ConvertErrCode(asyncCallbackInfo->err);
1630     APP_LOGD("CreateAppCloneComplete err is %{public}d, appIndex is %{public}d",
1631         asyncCallbackInfo->err,
1632         asyncCallbackInfo->appIndex);
1633     napi_value result[ARGS_SIZE_TWO] = {0};
1634     if (asyncCallbackInfo->err == SUCCESS) {
1635         NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[FIRST_PARAM]));
1636         NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, asyncCallbackInfo->appIndex, &result[SECOND_PARAM]));
1637     } else {
1638         result[FIRST_PARAM] = BusinessError::CreateCommonError(env, asyncCallbackInfo->err,
1639             CREATE_APP_CLONE, Constants::PERMISSION_INSTALL_CLONE_BUNDLE);
1640     }
1641     CommonFunc::NapiReturnDeferred<CreateAppCloneCallbackInfo>(env, asyncCallbackInfo, result, ARGS_SIZE_TWO);
1642 }
1643 
ParseAppCloneParam(napi_env env,napi_value args,int32_t & userId,int32_t & appIndex)1644 void ParseAppCloneParam(napi_env env, napi_value args, int32_t &userId, int32_t &appIndex)
1645 {
1646     if (!ParseUserId(env, args, userId)) {
1647         APP_LOGI("parse userId failed. assign a default value = %{public}d", userId);
1648     }
1649     if (ParseAppIndex(env, args, appIndex)) {
1650         if (appIndex == 0) {
1651             APP_LOGI("parse appIndex success, but appIndex is 0, assign a value: %{public}d", ILLEGAL_APP_INDEX);
1652             appIndex = ILLEGAL_APP_INDEX;
1653         }
1654     } else {
1655         APP_LOGI("parse appIndex failed. assign a default value = %{public}d", appIndex);
1656     }
1657 }
1658 
CreateAppClone(napi_env env,napi_callback_info info)1659 napi_value CreateAppClone(napi_env env, napi_callback_info info)
1660 {
1661     APP_LOGI("begin to CreateAppClone");
1662     NapiArg args(env, info);
1663     std::unique_ptr<CreateAppCloneCallbackInfo> asyncCallbackInfo = std::make_unique<CreateAppCloneCallbackInfo>(env);
1664     if (asyncCallbackInfo == nullptr) {
1665         APP_LOGW("asyncCallbackInfo is null");
1666         return nullptr;
1667     }
1668     if (!args.Init(ARGS_SIZE_ONE, ARGS_SIZE_TWO)) {
1669         APP_LOGW("param count invalid");
1670         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
1671         return nullptr;
1672     }
1673     size_t argc = args.GetMaxArgc();
1674     for (size_t i = 0; i < argc; ++i) {
1675         napi_valuetype valueType = napi_undefined;
1676         napi_typeof(env, args[i], &valueType);
1677         if (i == ARGS_POS_ZERO) {
1678             if (!CommonFunc::ParseString(env, args[i], asyncCallbackInfo->bundleName)) {
1679                 APP_LOGW("parse bundleName failed");
1680                 BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
1681                 return nullptr;
1682             }
1683         } else if (i == ARGS_POS_ONE) {
1684             if (valueType == napi_object) {
1685                 ParseAppCloneParam(env, args[i], asyncCallbackInfo->userId, asyncCallbackInfo->appIndex);
1686             }
1687         } else {
1688             APP_LOGW("The number of parameters is incorrect");
1689             BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
1690             return nullptr;
1691         }
1692     }
1693     if (asyncCallbackInfo->userId == Constants::UNSPECIFIED_USERID) {
1694         asyncCallbackInfo->userId = IPCSkeleton::GetCallingUid() / Constants::BASE_USER_RANGE;
1695     }
1696     auto promise = CommonFunc::AsyncCallNativeMethod<CreateAppCloneCallbackInfo>(
1697         env, asyncCallbackInfo.get(), CREATE_APP_CLONE, CreateAppCloneExec, CreateAppCloneComplete);
1698     asyncCallbackInfo.release();
1699     APP_LOGI("call napi CreateAppClone done");
1700     return promise;
1701 }
1702 
InnerDestroyAppClone(std::string & bundleName,int32_t userId,int32_t appIndex)1703 static ErrCode InnerDestroyAppClone(std::string &bundleName, int32_t userId, int32_t appIndex)
1704 {
1705     auto iBundleMgr = CommonFunc::GetBundleMgr();
1706     if (iBundleMgr == nullptr) {
1707         APP_LOGE("can not get iBundleMgr");
1708         return ERROR_BUNDLE_SERVICE_EXCEPTION;
1709     }
1710     auto iBundleInstaller = iBundleMgr->GetBundleInstaller();
1711     if ((iBundleInstaller == nullptr) || (iBundleInstaller->AsObject() == nullptr)) {
1712         APP_LOGE("can not get iBundleInstaller");
1713         return ERROR_BUNDLE_SERVICE_EXCEPTION;
1714     }
1715     ErrCode result = iBundleInstaller->UninstallCloneApp(bundleName, userId, appIndex);
1716     APP_LOGD("UninstallCloneApp result is %{public}d", result);
1717     return result;
1718 }
1719 
DestroyAppCloneExec(napi_env env,void * data)1720 void DestroyAppCloneExec(napi_env env, void *data)
1721 {
1722     CreateAppCloneCallbackInfo *asyncCallbackInfo = reinterpret_cast<CreateAppCloneCallbackInfo *>(data);
1723     if (asyncCallbackInfo == nullptr) {
1724         APP_LOGE("asyncCallbackInfo is null");
1725         return;
1726     }
1727     APP_LOGD("DestroyAppCloneExec param: bundleName = %{public}s, userId = %{public}d, appIndex = %{public}d",
1728         asyncCallbackInfo->bundleName.c_str(),
1729         asyncCallbackInfo->userId,
1730         asyncCallbackInfo->appIndex);
1731     asyncCallbackInfo->err =
1732         InnerDestroyAppClone(asyncCallbackInfo->bundleName, asyncCallbackInfo->userId, asyncCallbackInfo->appIndex);
1733 }
1734 
DestroyAppCloneComplete(napi_env env,napi_status status,void * data)1735 void DestroyAppCloneComplete(napi_env env, napi_status status, void *data)
1736 {
1737     CreateAppCloneCallbackInfo *asyncCallbackInfo = reinterpret_cast<CreateAppCloneCallbackInfo *>(data);
1738     if (asyncCallbackInfo == nullptr) {
1739         APP_LOGE("asyncCallbackInfo is null");
1740         return;
1741     }
1742     std::unique_ptr<CreateAppCloneCallbackInfo> callbackPtr {asyncCallbackInfo};
1743     asyncCallbackInfo->err = CommonFunc::ConvertErrCode(asyncCallbackInfo->err);
1744     APP_LOGD("DestroyAppCloneComplete err is %{public}d, appIndex is %{public}d",
1745         asyncCallbackInfo->err,
1746         asyncCallbackInfo->appIndex);
1747     napi_value result[ARGS_SIZE_TWO] = {0};
1748     if (asyncCallbackInfo->err == SUCCESS) {
1749         NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[FIRST_PARAM]));
1750     } else {
1751         result[FIRST_PARAM] = BusinessError::CreateCommonError(env, asyncCallbackInfo->err,
1752             DESTROY_APP_CLONE, Constants::PERMISSION_UNINSTALL_CLONE_BUNDLE);
1753     }
1754     CommonFunc::NapiReturnDeferred<CreateAppCloneCallbackInfo>(env, asyncCallbackInfo, result, ARGS_SIZE_ONE);
1755 }
1756 
DestroyAppClone(napi_env env,napi_callback_info info)1757 napi_value DestroyAppClone(napi_env env, napi_callback_info info)
1758 {
1759     APP_LOGI("begin to destroyAppClone");
1760     NapiArg args(env, info);
1761     std::unique_ptr<CreateAppCloneCallbackInfo> asyncCallbackInfo = std::make_unique<CreateAppCloneCallbackInfo>(env);
1762     if (asyncCallbackInfo == nullptr) {
1763         APP_LOGW("asyncCallbackInfo is null");
1764         return nullptr;
1765     }
1766     if (!args.Init(ARGS_SIZE_TWO, ARGS_SIZE_THREE)) {
1767         APP_LOGW("param count invalid");
1768         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
1769         return nullptr;
1770     }
1771     size_t argc = args.GetMaxArgc();
1772     for (size_t i = 0; i < argc; ++i) {
1773         napi_valuetype valueType = napi_undefined;
1774         napi_typeof(env, args[i], &valueType);
1775         if (i == ARGS_POS_ZERO) {
1776             if (!CommonFunc::ParseString(env, args[i], asyncCallbackInfo->bundleName)) {
1777                 APP_LOGW("parse bundleName failed");
1778                 BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
1779                 return nullptr;
1780             }
1781         } else if (i == ARGS_POS_ONE) {
1782             if (!CommonFunc::ParseInt(env, args[i], asyncCallbackInfo->appIndex)) {
1783                 APP_LOGW("parse appIndex failed");
1784                 BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, APP_INDEX, TYPE_NUMBER);
1785                 return nullptr;
1786             }
1787         } else if (i == ARGS_POS_TWO) {
1788             if (!CommonFunc::ParseInt(env, args[i], asyncCallbackInfo->userId)) {
1789                 APP_LOGW("Parse userId failed, set this parameter to the caller userId");
1790             }
1791         } else {
1792             APP_LOGE("The number of parameters is incorrect");
1793             BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
1794             return nullptr;
1795         }
1796     }
1797     if (asyncCallbackInfo->userId == Constants::UNSPECIFIED_USERID) {
1798         asyncCallbackInfo->userId = IPCSkeleton::GetCallingUid() / Constants::BASE_USER_RANGE;
1799     }
1800     auto promise = CommonFunc::AsyncCallNativeMethod<CreateAppCloneCallbackInfo>(
1801         env, asyncCallbackInfo.get(), DESTROY_APP_CLONE, DestroyAppCloneExec, DestroyAppCloneComplete);
1802     asyncCallbackInfo.release();
1803     APP_LOGI("call napi destroyAppTwin done");
1804     return promise;
1805 }
1806 
InnerInstallPreexistingApp(std::string & bundleName,int32_t userId)1807 static ErrCode InnerInstallPreexistingApp(std::string &bundleName, int32_t userId)
1808 {
1809     auto iBundleMgr = CommonFunc::GetBundleMgr();
1810     if (iBundleMgr == nullptr) {
1811         APP_LOGE("can not get iBundleMgr");
1812         return ERROR_BUNDLE_SERVICE_EXCEPTION;
1813     }
1814     auto iBundleInstaller = iBundleMgr->GetBundleInstaller();
1815     if ((iBundleInstaller == nullptr) || (iBundleInstaller->AsObject() == nullptr)) {
1816         APP_LOGE("can not get iBundleInstaller");
1817         return ERROR_BUNDLE_SERVICE_EXCEPTION;
1818     }
1819     ErrCode result = iBundleInstaller->InstallExisted(bundleName, userId);
1820     APP_LOGD("result is %{public}d", result);
1821     return result;
1822 }
1823 
InstallPreexistingAppExec(napi_env env,void * data)1824 void InstallPreexistingAppExec(napi_env env, void *data)
1825 {
1826     InstallPreexistingAppCallbackInfo *asyncCallbackInfo = reinterpret_cast<InstallPreexistingAppCallbackInfo *>(data);
1827     if (asyncCallbackInfo == nullptr) {
1828         APP_LOGE("asyncCallbackInfo is null");
1829         return;
1830     }
1831     APP_LOGD("param: bundleName = %{public}s, userId = %{public}d",
1832         asyncCallbackInfo->bundleName.c_str(),
1833         asyncCallbackInfo->userId);
1834     asyncCallbackInfo->err =
1835         InnerInstallPreexistingApp(asyncCallbackInfo->bundleName, asyncCallbackInfo->userId);
1836 }
1837 
InstallPreexistingAppComplete(napi_env env,napi_status status,void * data)1838 void InstallPreexistingAppComplete(napi_env env, napi_status status, void *data)
1839 {
1840     InstallPreexistingAppCallbackInfo *asyncCallbackInfo = reinterpret_cast<InstallPreexistingAppCallbackInfo *>(data);
1841     if (asyncCallbackInfo == nullptr) {
1842         APP_LOGE("asyncCallbackInfo is null");
1843         return;
1844     }
1845     std::unique_ptr<InstallPreexistingAppCallbackInfo> callbackPtr {asyncCallbackInfo};
1846     asyncCallbackInfo->err = CommonFunc::ConvertErrCode(asyncCallbackInfo->err);
1847     APP_LOGD("err is %{public}d", asyncCallbackInfo->err);
1848 
1849     napi_value result[ARGS_SIZE_ONE] = {0};
1850     if (asyncCallbackInfo->err == SUCCESS) {
1851         NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[FIRST_PARAM]));
1852     } else {
1853         result[FIRST_PARAM] = BusinessError::CreateCommonError(env, asyncCallbackInfo->err,
1854             INSTALL_PREEXISTING_APP, Constants::PERMISSION_INSTALL_BUNDLE);
1855     }
1856     CommonFunc::NapiReturnDeferred<InstallPreexistingAppCallbackInfo>(env, asyncCallbackInfo, result, ARGS_SIZE_ONE);
1857 }
1858 
InstallPreexistingApp(napi_env env,napi_callback_info info)1859 napi_value InstallPreexistingApp(napi_env env, napi_callback_info info)
1860 {
1861     APP_LOGI("begin");
1862     NapiArg args(env, info);
1863     std::unique_ptr<InstallPreexistingAppCallbackInfo> asyncCallbackInfo
1864         = std::make_unique<InstallPreexistingAppCallbackInfo>(env);
1865     if (asyncCallbackInfo == nullptr) {
1866         APP_LOGW("asyncCallbackInfo is null");
1867         return nullptr;
1868     }
1869     if (!args.Init(ARGS_SIZE_ONE, ARGS_SIZE_TWO)) {
1870         APP_LOGW("param count invalid");
1871         BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
1872         return nullptr;
1873     }
1874     size_t argc = args.GetMaxArgc();
1875     for (size_t i = 0; i < argc; ++i) {
1876         if (i == ARGS_POS_ZERO) {
1877             if (!CommonFunc::ParseString(env, args[i], asyncCallbackInfo->bundleName)) {
1878                 APP_LOGW("parse bundleName failed");
1879                 BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
1880                 return nullptr;
1881             }
1882         } else if (i == ARGS_POS_ONE) {
1883             if (!CommonFunc::ParseInt(env, args[i], asyncCallbackInfo->userId)) {
1884                 APP_LOGW("parse userId failed");
1885             }
1886         } else {
1887             APP_LOGW("The number of parameters is incorrect");
1888             BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
1889             return nullptr;
1890         }
1891     }
1892     if (asyncCallbackInfo->userId == Constants::UNSPECIFIED_USERID) {
1893         asyncCallbackInfo->userId = IPCSkeleton::GetCallingUid() / Constants::BASE_USER_RANGE;
1894     }
1895     auto promise = CommonFunc::AsyncCallNativeMethod<InstallPreexistingAppCallbackInfo>(
1896         env, asyncCallbackInfo.get(), INSTALL_PREEXISTING_APP,
1897         InstallPreexistingAppExec, InstallPreexistingAppComplete);
1898     asyncCallbackInfo.release();
1899     APP_LOGI("call napi done");
1900     return promise;
1901 }
1902 } // AppExecFwk
1903 } // OHOS