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