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
35namespace OHOS {
36namespace AppExecFwk {
37namespace {
38// resource name
39const char* RESOURCE_NAME_OF_GET_BUNDLE_INSTALLER = "GetBundleInstaller";
40const char* RESOURCE_NAME_OF_GET_BUNDLE_INSTALLER_SYNC = "GetBundleInstallerSync";
41const char* RESOURCE_NAME_OF_INSTALL = "Install";
42const char* RESOURCE_NAME_OF_UNINSTALL = "Uninstall";
43const char* RESOURCE_NAME_OF_RECOVER = "Recover";
44const char* RESOURCE_NAME_OF_UPDATE_BUNDLE_FOR_SELF = "UpdateBundleForSelf";
45const char* RESOURCE_NAME_OF_UNINSTALL_AND_RECOVER = "UninstallAndRecover";
46const char* EMPTY_STRING = "";
47// install message
48constexpr 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";
54constexpr const char* UNINSTALL_PERMISSION = "ohos.permission.INSTALL_BUNDLE or ohos.permission.UNINSTALL_BUNDLE";
55constexpr const char* RECOVER_PERMISSION = "ohos.permission.INSTALL_BUNDLE or ohos.permission.RECOVER_BUNDLE";
56constexpr const char* INSTALL_SELF_PERMISSION = "ohos.permission.INSTALL_SELF_BUNDLE";
57constexpr const char* PARAMETERS = "parameters";
58constexpr const char* CORRESPONDING_TYPE = "corresponding type";
59constexpr const char* FUNCTION_TYPE = "napi_function";
60constexpr const char* CALLBACK = "callback";
61// property name
62const char* USER_ID = "userId";
63const char* INSTALL_FLAG = "installFlag";
64const char* IS_KEEP_DATA = "isKeepData";
65const char* CROWD_TEST_DEADLINE = "crowdtestDeadline";
66const char* MODULE_NAME = "moduleName";
67const char* HASH_VALUE = "hashValue";
68const char* HASH_PARAMS = "hashParams";
69const char* BUNDLE_NAME = "bundleName";
70const char* APP_INDEX = "appIndex";
71const char* FILE_PATH = "filePath";
72const char* ADD_EXT_RESOURCE = "AddExtResource";
73const char* REMOVE_EXT_RESOURCE = "RemoveExtResource";
74const char* VERSION_CODE = "versionCode";
75const char* SHARED_BUNDLE_DIR_PATHS = "sharedBundleDirPaths";
76const char* SPECIFIED_DISTRIBUTION_TYPE = "specifiedDistributionType";
77const char* ADDITIONAL_INFO = "additionalInfo";
78const char* VERIFY_CODE_PARAM = "verifyCodeParams";
79const char* SIGNATURE_FILE_PATH = "signatureFilePath";
80const char* PGO_PARAM = "pgoParams";
81const char* PGO_FILE_PATH = "pgoFilePath";
82const char* HAPS_FILE_NEEDED =
83    "BusinessError 401: Parameter error. parameter hapFiles is needed for code signature";
84const char* CREATE_APP_CLONE = "CreateAppClone";
85const char* DESTROY_APP_CLONE = "destroyAppClone";
86const char* INSTALL_PREEXISTING_APP = "installPreexistingApp";
87constexpr int32_t FIRST_PARAM = 0;
88constexpr int32_t SECOND_PARAM = 1;
89
90constexpr int32_t SPECIFIED_DISTRIBUTION_TYPE_MAX_SIZE = 128;
91constexpr int32_t ADDITIONAL_INFO_MAX_SIZE = 3000;
92constexpr int32_t ILLEGAL_APP_INDEX = -1;
93} // namespace
94napi_ref thread_local g_classBundleInstaller;
95bool g_isSystemApp = false;
96
97AsyncInstallCallbackInfo::~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
109AsyncGetBundleInstallerCallbackInfo::~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
121void 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 */
170napi_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
214napi_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
240static 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
421static 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
435static 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
455static 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
484static 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
504static 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
533static 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
553static 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
578static 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
602static 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
625static 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
646static 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
667static 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
688static 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
718static 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
739static 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
759static 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
783static 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
807static 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
831static 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
848static 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
883static 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
895static 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
907void 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
954static 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
970void 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 */
1012napi_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
1075void 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
1118void 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
1151napi_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
1184napi_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
1241napi_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
1250napi_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
1267napi_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 */
1277napi_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
1335void 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
1367napi_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
1404ErrCode 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
1428void 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
1439void 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
1460napi_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
1501ErrCode 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
1518void 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
1529void 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
1550napi_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
1591static 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
1608void 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
1623void 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
1646void 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
1661napi_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
1705static 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
1722void 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
1737void 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
1759napi_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
1809static 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
1826void 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
1840void 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
1861napi_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