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