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