* Copyright (c) 2022-2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <unordered_map>
#include "installer.h"
#include "appexecfwk_errors.h"
#include "app_log_wrapper.h"
#include "bundle_errors.h"
#include "bundle_death_recipient.h"
#include "bundle_mgr_interface.h"
#include "bundle_mgr_proxy.h"
#include "business_error.h"
#include "common_func.h"
#include "if_system_ability_manager.h"
#include "installer_callback.h"
#include "installer_helper.h"
#include "napi_arg.h"
#include "napi_constants.h"
#include "system_ability_definition.h"
#include "ipc_skeleton.h"
namespace OHOS {
namespace AppExecFwk {
namespace {
const char* EMPTY_STRING = "";
constexpr const char* FUNCTION_TYPE = "napi_function";
constexpr const char* CALLBACK = "callback";
const char* INSTALL_FLAG = "installFlag";
const char* IS_KEEP_DATA = "isKeepData";
const char* CROWD_TEST_DEADLINE = "crowdtestDeadline";
const char* HASH_VALUE = "hashValue";
const char* HASH_PARAMS = "hashParams";
const char* VERSION_CODE = "versionCode";
const char* SHARED_BUNDLE_DIR_PATHS = "sharedBundleDirPaths";
const char* SPECIFIED_DISTRIBUTION_TYPE = "specifiedDistributionType";
const char* VERIFY_CODE_PARAM = "verifyCodeParams";
const char* SIGNATURE_FILE_PATH = "signatureFilePath";
const char* PGO_PARAM = "pgoParams";
const char* PGO_FILE_PATH = "pgoFilePath";
const char* KEY = "key";
const char* VALUE = "value";
constexpr int32_t FIRST_PARAM = 0;
constexpr int32_t SECOND_PARAM = 1;
constexpr int32_t ILLEGAL_APP_INDEX = -1;
}
napi_ref thread_local g_classBundleInstaller;
bool g_isSystemApp = false;
AsyncInstallCallbackInfo::~AsyncInstallCallbackInfo()
{
if (callback) {
napi_delete_reference(env, callback);
callback = nullptr;
}
if (asyncWork) {
napi_delete_async_work(env, asyncWork);
asyncWork = nullptr;
}
}
AsyncGetBundleInstallerCallbackInfo::~AsyncGetBundleInstallerCallbackInfo()
{
if (callback) {
napi_delete_reference(env, callback);
callback = nullptr;
}
if (asyncWork) {
napi_delete_async_work(env, asyncWork);
asyncWork = nullptr;
}
}
void GetBundleInstallerCompleted(napi_env env, napi_status status, void *data)
{
AsyncGetBundleInstallerCallbackInfo *asyncCallbackInfo =
reinterpret_cast<AsyncGetBundleInstallerCallbackInfo *>(data);
std::unique_ptr<AsyncGetBundleInstallerCallbackInfo> callbackPtr {asyncCallbackInfo};
napi_value m_classBundleInstaller = nullptr;
NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, g_classBundleInstaller,
&m_classBundleInstaller));
napi_value result[CALLBACK_PARAM_SIZE] = {0};
auto iBundleMgr = CommonFunc::GetBundleMgr();
if (iBundleMgr == nullptr) {
APP_LOGE("can not get iBundleMgr");
return;
}
if (!g_isSystemApp && !iBundleMgr->VerifySystemApi(Constants::INVALID_API_VERSION)) {
APP_LOGE("non-system app calling system api");
result[0] = BusinessError::CreateCommonError(
env, ERROR_NOT_SYSTEM_APP, RESOURCE_NAME_OF_GET_BUNDLE_INSTALLER, INSTALL_PERMISSION);
if (callbackPtr->deferred) {
NAPI_CALL_RETURN_VOID(env, napi_reject_deferred(env, asyncCallbackInfo->deferred, result[0]));
} else {
napi_value callback = nullptr;
napi_value placeHolder = nullptr;
NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, asyncCallbackInfo->callback, &callback));
NAPI_CALL_RETURN_VOID(env, napi_call_function(env, nullptr, callback,
sizeof(result) / sizeof(result[0]), result, &placeHolder));
}
return;
}
g_isSystemApp = true;
NAPI_CALL_RETURN_VOID(env, napi_new_instance(env, m_classBundleInstaller, 0, nullptr, &result[SECOND_PARAM]));
if (callbackPtr->deferred) {
NAPI_CALL_RETURN_VOID(env, napi_resolve_deferred(env, callbackPtr->deferred, result[SECOND_PARAM]));
} else {
napi_value callback = CommonFunc::WrapVoidToJS(env);
NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, callbackPtr->callback, &callback));
napi_value undefined = CommonFunc::WrapVoidToJS(env);
NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined));
napi_value callResult = CommonFunc::WrapVoidToJS(env);
NAPI_CALL_RETURN_VOID(env, napi_call_function(env, undefined, callback, CALLBACK_PARAM_SIZE,
&result[FIRST_PARAM], &callResult));
}
}
* Promise and async callback
*/
napi_value GetBundleInstaller(napi_env env, napi_callback_info info)
{
APP_LOGI_NOFUNC("napi GetBundleInstaller called");
NapiArg args(env, info);
if (!args.Init(FIRST_PARAM, SECOND_PARAM)) {
APP_LOGE("GetBundleInstaller args init failed");
BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
return nullptr;
}
std::unique_ptr<AsyncGetBundleInstallerCallbackInfo> callbackPtr =
std::make_unique<AsyncGetBundleInstallerCallbackInfo>(env);
auto argc = args.GetMaxArgc();
APP_LOGD("GetBundleInstaller argc = [%{public}zu]", argc);
if (argc == SECOND_PARAM) {
napi_value arg = args.GetArgv(argc - SECOND_PARAM);
if (arg == nullptr) {
APP_LOGE("the param is nullptr");
BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
return nullptr;
}
napi_valuetype valuetype = napi_undefined;
NAPI_CALL(env, napi_typeof(env, arg, &valuetype));
if (valuetype != napi_function) {
APP_LOGE("the param type is invalid");
BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, CALLBACK, FUNCTION_TYPE);
return nullptr;
}
NAPI_CALL(env, napi_create_reference(env, arg, NAPI_RETURN_ONE, &callbackPtr->callback));
}
auto executeFunc = [](napi_env env, void *data) {};
napi_value promise = CommonFunc::AsyncCallNativeMethod(
env,
callbackPtr.get(),
RESOURCE_NAME_OF_GET_BUNDLE_INSTALLER,
executeFunc,
GetBundleInstallerCompleted);
callbackPtr.release();
APP_LOGI_NOFUNC("call GetBundleInstaller done");
return promise;
}
napi_value GetBundleInstallerSync(napi_env env, napi_callback_info info)
{
APP_LOGI("NAPI GetBundleInstallerSync called");
napi_value m_classBundleInstaller = nullptr;
NAPI_CALL(env, napi_get_reference_value(env, g_classBundleInstaller,
&m_classBundleInstaller));
auto iBundleMgr = CommonFunc::GetBundleMgr();
if (iBundleMgr == nullptr) {
APP_LOGE("can not get iBundleMgr");
return nullptr;
}
if (!g_isSystemApp && !iBundleMgr->VerifySystemApi(Constants::INVALID_API_VERSION)) {
APP_LOGE("non-system app calling system api");
napi_value businessError = BusinessError::CreateCommonError(
env, ERROR_NOT_SYSTEM_APP, RESOURCE_NAME_OF_GET_BUNDLE_INSTALLER_SYNC, INSTALL_PERMISSION);
napi_throw(env, businessError);
return nullptr;
}
g_isSystemApp = true;
napi_value nBundleInstaller = nullptr;
NAPI_CALL(env, napi_new_instance(env, m_classBundleInstaller, 0, nullptr, &nBundleInstaller));
APP_LOGD("call GetBundleInstallerSync done");
return nBundleInstaller;
}
static bool ParseHashParam(napi_env env, napi_value args, std::string &key, std::string &value)
{
APP_LOGD("start to parse moduleName");
bool ret = CommonFunc::ParseStringPropertyFromObject(env, args, MODULE_NAME, true, key);
if (!ret || key.empty()) {
APP_LOGE("param string moduleName is empty");
return false;
}
APP_LOGD("ParseHashParam moduleName=%{public}s", key.c_str());
APP_LOGD("start to parse hashValue");
ret = CommonFunc::ParseStringPropertyFromObject(env, args, HASH_VALUE, true, value);
if (!ret || value.empty()) {
APP_LOGE("param string hashValue is empty");
return false;
}
APP_LOGD("ParseHashParam hashValue=%{public}s", value.c_str());
return true;
}
static bool ParseHashParams(napi_env env, napi_value args, std::map<std::string, std::string> &hashParams)
{
APP_LOGD("start to parse hashParams");
std::vector<napi_value> valueVec;
bool res = CommonFunc::ParsePropertyArray(env, args, HASH_PARAMS, valueVec);
if (!res) {
APP_LOGW("hashParams type error,using default value");
return true;
}
if (valueVec.empty()) {
APP_LOGW("hashParams is empty,using default value");
return true;
}
for (const auto &property : valueVec) {
std::string key;
std::string value;
if (!ParseHashParam(env, property, key, value)) {
APP_LOGE("parse hash param failed");
return false;
}
if (hashParams.find(key) != hashParams.end()) {
APP_LOGE("moduleName(%{public}s) is duplicate", key.c_str());
return false;
}
hashParams.emplace(key, value);
}
return true;
}
static bool ParseVerifyCodeParam(napi_env env, napi_value args, std::string &key, std::string &value)
{
APP_LOGD("start to parse moduleName");
bool ret = CommonFunc::ParseStringPropertyFromObject(env, args, MODULE_NAME, true, key);
if (!ret || key.empty()) {
APP_LOGE("param string moduleName is empty");
return false;
}
APP_LOGD("ParseVerifyCodeParam moduleName is %{public}s", key.c_str());
APP_LOGD("start to parse signatureFilePath");
ret = CommonFunc::ParseStringPropertyFromObject(env, args, SIGNATURE_FILE_PATH, true, value);
if (!ret || value.empty()) {
APP_LOGE("param string signatureFilePath is empty");
return false;
}
APP_LOGD("ParseVerifyCodeParam signatureFilePath is %{public}s", value.c_str());
return true;
}
static bool ParseVerifyCodeParams(napi_env env, napi_value args, std::map<std::string, std::string> &verifyCodeParams)
{
APP_LOGD("start to parse verifyCodeParams");
std::vector<napi_value> valueVec;
bool res = CommonFunc::ParsePropertyArray(env, args, VERIFY_CODE_PARAM, valueVec);
if (!res) {
APP_LOGW("verifyCodeParams type error, using default value");
return true;
}
if (valueVec.empty()) {
APP_LOGW("verifyCodeParams is empty, using default value");
return true;
}
for (const auto &property : valueVec) {
std::string key;
std::string value;
if (!ParseVerifyCodeParam(env, property, key, value)) {
APP_LOGE("parse verify code param failed");
return false;
}
if (verifyCodeParams.find(key) != verifyCodeParams.end()) {
APP_LOGE("moduleName(%{public}s) is duplicate", key.c_str());
return false;
}
verifyCodeParams.emplace(key, value);
}
return true;
}
static bool ParseParameter(napi_env env, napi_value args, std::string &key, std::string &value)
{
APP_LOGD("start to parse parameter");
bool ret = CommonFunc::ParseStringPropertyFromObject(env, args, KEY, true, key);
if (!ret || key.empty()) {
APP_LOGE("param key is empty");
return false;
}
APP_LOGD("ParseParameter key is %{public}s", key.c_str());
APP_LOGD("start to parse value");
ret = CommonFunc::ParseStringPropertyFromObject(env, args, VALUE, true, value);
if (!ret || value.empty()) {
APP_LOGE("param value is empty");
return false;
}
APP_LOGD("ParseParameter value is %{public}s", value.c_str());
return true;
}
static bool ParseParameters(napi_env env, napi_value args, std::map<std::string, std::string> ¶meters)
{
APP_LOGD("start to parse parameters");
std::vector<napi_value> valueVec;
bool res = CommonFunc::ParsePropertyArray(env, args, PARAMETERS, valueVec);
if (!res) {
APP_LOGW("parameters type error, using default value");
return true;
}
if (valueVec.empty()) {
APP_LOGW("parameters is empty, using default value");
return true;
}
for (const auto &property : valueVec) {
std::string key;
std::string value;
if (!ParseParameter(env, property, key, value)) {
APP_LOGE("parse parameter failed");
return false;
}
if (key == Constants::VERIFY_UNINSTALL_FORCED_KEY) {
APP_LOGW("No support VERIFY_UNINSTALL_FORCED_KEY");
continue;
}
if (parameters.find(key) != parameters.end()) {
APP_LOGE("key(%{public}s) is duplicate", key.c_str());
return false;
}
parameters.emplace(key, value);
}
return true;
}
static bool ParsePgoParam(napi_env env, napi_value args, std::string &key, std::string &value)
{
APP_LOGD("start to parse moduleName");
bool ret = CommonFunc::ParseStringPropertyFromObject(env, args, MODULE_NAME, true, key);
if (!ret || key.empty()) {
APP_LOGE("param string moduleName is empty");
return false;
}
APP_LOGD("ParsePgoParam moduleName is %{public}s", key.c_str());
APP_LOGD("start to parse pgoFilePath");
ret = CommonFunc::ParseStringPropertyFromObject(env, args, PGO_FILE_PATH, true, value);
if (!ret || value.empty()) {
APP_LOGE("param string pgoFilePath is empty");
return false;
}
APP_LOGD("ParsePgoParam pgoFilePath is %{public}s", value.c_str());
return true;
}
static bool ParsePgoParams(napi_env env, napi_value args, std::map<std::string, std::string> &pgoParams)
{
APP_LOGD("start to parse pgoParams");
std::vector<napi_value> valueVec;
bool res = CommonFunc::ParsePropertyArray(env, args, PGO_PARAM, valueVec);
if (!res) {
APP_LOGW("pgoParams type error, using default value");
return true;
}
if (valueVec.empty()) {
APP_LOGW("pgoParams is empty, using default value");
return true;
}
for (const auto &property : valueVec) {
std::string key;
std::string value;
if (!ParsePgoParam(env, property, key, value)) {
APP_LOGW("parse pgo param failed");
continue;
}
pgoParams.emplace(key, value);
}
return true;
}
static bool ParseBundleName(napi_env env, napi_value args, std::string &bundleName)
{
APP_LOGD("start to parse bundleName");
PropertyInfo propertyInfo = {
.isNecessary = true,
.propertyType = napi_string,
.propertyName = BUNDLE_NAME
};
napi_value property = nullptr;
bool res = CommonFunc::ParsePropertyFromObject(env, args, propertyInfo, property);
if (!res) {
APP_LOGE("parse bundleName failed, bundleName is %{public}s", bundleName.c_str());
return res;
}
if (property != nullptr) {
if (!CommonFunc::ParseString(env, property, bundleName)) {
APP_LOGE("ParseString failed");
return false;
}
}
APP_LOGD("param bundleName is %{public}s", bundleName.c_str());
return true;
}
static bool ParseModuleName(napi_env env, napi_value args, std::string &moduleName)
{
APP_LOGD("start to parse moduleName");
PropertyInfo propertyInfo = {
.isNecessary = false,
.propertyType = napi_string,
.propertyName = MODULE_NAME
};
napi_value property = nullptr;
bool res = CommonFunc::ParsePropertyFromObject(env, args, propertyInfo, property);
if (!res) {
APP_LOGE("parse moduleName failed");
return res;
}
if (property != nullptr) {
if (!CommonFunc::ParseString(env, property, moduleName)) {
APP_LOGE("ParseString failed");
return false;
}
}
return true;
}
static bool ParseVersionCode(napi_env env, napi_value args, int32_t &versionCode)
{
APP_LOGD("start to parse versionCode");
PropertyInfo propertyInfo = {
.isNecessary = false,
.propertyType = napi_number,
.propertyName = VERSION_CODE
};
napi_value property = nullptr;
bool res = CommonFunc::ParsePropertyFromObject(env, args, propertyInfo, property);
if (!res) {
APP_LOGE("parse versionCode failed");
return res;
}
if (property != nullptr) {
PARSE_PROPERTY(env, property, int32, versionCode);
}
APP_LOGD("param versionCode is %{public}d", versionCode);
return true;
}
static bool ParseUserId(napi_env env, napi_value args, int32_t &userId)
{
APP_LOGD("start to parse userId");
PropertyInfo propertyInfo = {
.isNecessary = false,
.propertyType = napi_number,
.propertyName = USER_ID
};
napi_value property = nullptr;
bool res = CommonFunc::ParsePropertyFromObject(env, args, propertyInfo, property);
if (!res) {
APP_LOGE("parse userId failed");
return res;
}
if (property != nullptr) {
PARSE_PROPERTY(env, property, int32, userId);
}
APP_LOGD("param userId is %{public}d", userId);
return true;
}
static bool ParseAppIndex(napi_env env, napi_value args, int32_t &appIndex)
{
APP_LOGD("start to parse appIndex");
PropertyInfo propertyInfo = {
.isNecessary = true,
.propertyType = napi_number,
.propertyName = APP_INDEX
};
napi_value property = nullptr;
bool res = CommonFunc::ParsePropertyFromObject(env, args, propertyInfo, property);
if (!res) {
APP_LOGE("parse appIndex failed");
return res;
}
if (property != nullptr) {
PARSE_PROPERTY(env, property, int32, appIndex);
}
APP_LOGD("param appIndex is %{public}d", appIndex);
return true;
}
static bool ParseInstallFlag(napi_env env, napi_value args, InstallFlag &installFlag)
{
APP_LOGD("start to parse installFlag");
PropertyInfo propertyInfo = {
.isNecessary = false,
.propertyType = napi_number,
.propertyName = INSTALL_FLAG
};
napi_value property = nullptr;
bool res = CommonFunc::ParsePropertyFromObject(env, args, propertyInfo, property);
if (!res) {
APP_LOGE("parse installFlag failed");
return res;
}
if (property != nullptr) {
int32_t flag = 0;
PARSE_PROPERTY(env, property, int32, flag);
APP_LOGD("param installFlag is %{public}d", flag);
if ((flag != static_cast<int32_t>(OHOS::AppExecFwk::InstallFlag::NORMAL)) &&
(flag != static_cast<int32_t>(OHOS::AppExecFwk::InstallFlag::REPLACE_EXISTING)) &&
(flag != static_cast<int32_t>(OHOS::AppExecFwk::InstallFlag::FREE_INSTALL))) {
APP_LOGE("invalid installFlag param");
return false;
}
installFlag = static_cast<OHOS::AppExecFwk::InstallFlag>(flag);
}
return true;
}
static bool ParseIsKeepData(napi_env env, napi_value args, bool &isKeepData)
{
APP_LOGD("start to parse isKeepData");
PropertyInfo propertyInfo = {
.isNecessary = false,
.propertyType = napi_boolean,
.propertyName = IS_KEEP_DATA
};
napi_value property = nullptr;
bool res = CommonFunc::ParsePropertyFromObject(env, args, propertyInfo, property);
if (!res) {
APP_LOGE("parse isKeepData failed");
return res;
}
if (property != nullptr) {
PARSE_PROPERTY(env, property, bool, isKeepData);
}
APP_LOGD("param isKeepData is %{public}d", isKeepData);
return true;
}
static bool ParseCrowdtestDeadline(napi_env env, napi_value args, int64_t &crowdtestDeadline)
{
APP_LOGD("start to parse crowdtestDeadline");
PropertyInfo propertyInfo = {
.isNecessary = false,
.propertyType = napi_number,
.propertyName = CROWD_TEST_DEADLINE
};
napi_value property = nullptr;
bool res = CommonFunc::ParsePropertyFromObject(env, args, propertyInfo, property);
if (!res) {
APP_LOGE("parse crowdtestDeadline failed");
return res;
}
if (property != nullptr) {
PARSE_PROPERTY(env, property, int64, crowdtestDeadline);
}
return true;
}
static bool ParseSharedBundleDirPaths(napi_env env, napi_value args, std::vector<std::string> &sharedBundleDirPaths)
{
APP_LOGD("start to parse sharedBundleDirPaths");
std::vector<napi_value> valueVec;
bool res = CommonFunc::ParsePropertyArray(env, args, SHARED_BUNDLE_DIR_PATHS, valueVec);
if (!res) {
APP_LOGE("parse sharedBundleDirPaths failed");
return res;
}
if (valueVec.empty()) {
APP_LOGD("sharedBundleDirPaths is empty");
return true;
}
for (const auto &value : valueVec) {
std::string path;
if (!CommonFunc::ParseString(env, value, path)) {
APP_LOGE("parse sharedBundleDirPaths element failed");
return false;
}
sharedBundleDirPaths.emplace_back(path);
}
return true;
}
static bool ParseSpecifiedDistributionType(napi_env env, napi_value args, std::string &specifiedDistributionType)
{
APP_LOGD("start to parse specifiedDistributionType");
PropertyInfo propertyInfo = {
.isNecessary = false,
.propertyType = napi_string,
.propertyName = SPECIFIED_DISTRIBUTION_TYPE
};
napi_value property = nullptr;
bool res = CommonFunc::ParsePropertyFromObject(env, args, propertyInfo, property);
if (!res) {
APP_LOGE("parse specifiedDistributionType failed");
return res;
}
if (property != nullptr) {
if (!CommonFunc::ParseString(env, property, specifiedDistributionType)) {
APP_LOGE("ParseString failed");
return false;
}
}
APP_LOGD("param specifiedDistributionType is %{public}s", specifiedDistributionType.c_str());
return true;
}
static bool ParseAdditionalInfo(napi_env env, napi_value args, std::string &additionalInfo)
{
APP_LOGD("start to parse the additionalInfo");
PropertyInfo propertyInfo = {
.isNecessary = false,
.propertyType = napi_string,
.propertyName = ADDITIONAL_INFO
};
napi_value property = nullptr;
bool res = CommonFunc::ParsePropertyFromObject(env, args, propertyInfo, property);
if (!res) {
APP_LOGE("parse additionalInfo failed");
return res;
}
if (property != nullptr) {
if (!CommonFunc::ParseString(env, property, additionalInfo)) {
APP_LOGE("ParseString failed");
return false;
}
}
APP_LOGD("param additionalInfo is %{public}s", additionalInfo.c_str());
return true;
}
static bool CheckInstallParam(napi_env env, InstallParam &installParam)
{
if (installParam.specifiedDistributionType.size() > SPECIFIED_DISTRIBUTION_TYPE_MAX_SIZE) {
APP_LOGE("Parse specifiedDistributionType size failed");
BusinessError::ThrowError(env, ERROR_PARAM_CHECK_ERROR,
"BusinessError 401: The size of specifiedDistributionType is greater than 128");
return false;
}
if (installParam.additionalInfo.size() > ADDITIONAL_INFO_MAX_SIZE) {
APP_LOGE("Parse additionalInfo size failed");
BusinessError::ThrowError(env, ERROR_PARAM_CHECK_ERROR,
"BusinessError 401: The size of additionalInfo is greater than 3000");
return false;
}
return true;
}
static bool ParseInstallParam(napi_env env, napi_value args, InstallParam &installParam)
{
if (!ParseHashParams(env, args, installParam.hashParams)) {
return false;
}
if (!ParseVerifyCodeParams(env, args, installParam.verifyCodeParams)) {
return false;
}
if (!ParsePgoParams(env, args, installParam.pgoParams)) {
return false;
}
if (!ParseUserId(env, args, installParam.userId)) {
APP_LOGW("Parse userId failed,using default value");
}
if (!ParseInstallFlag(env, args, installParam.installFlag)) {
APP_LOGW("Parse installFlag failed,using default value");
}
if (!ParseIsKeepData(env, args, installParam.isKeepData)) {
APP_LOGW("Parse isKeepData failed,using default value");
}
if (!ParseCrowdtestDeadline(env, args, installParam.crowdtestDeadline)) {
APP_LOGW("Parse crowdtestDeadline failed,using default value");
}
if (!ParseSharedBundleDirPaths(env, args, installParam.sharedBundleDirPaths)) {
APP_LOGW("Parse sharedBundleDirPaths failed,using default value");
}
if (!ParseSpecifiedDistributionType(env, args, installParam.specifiedDistributionType)) {
APP_LOGW("Parse specifiedDistributionType failed,using default value");
}
if (!ParseAdditionalInfo(env, args, installParam.additionalInfo)) {
APP_LOGW("Parse additionalInfo failed,using default value");
}
if (!ParseParameters(env, args, installParam.parameters)) {
APP_LOGW("Parse parameters failed,using default value");
}
return true;
}
static bool ParseUninstallParam(napi_env env, napi_value args, UninstallParam &uninstallParam)
{
if (!ParseBundleName(env, args, uninstallParam.bundleName) ||
!ParseModuleName(env, args, uninstallParam.moduleName) ||
!ParseVersionCode(env, args, uninstallParam.versionCode) ||
!ParseUserId(env, args, uninstallParam.userId)) {
APP_LOGE("Parse UninstallParam failed");
return false;
}
return true;
}
void InstallExecuter(napi_env env, void *data)
{
AsyncInstallCallbackInfo *asyncCallbackInfo = reinterpret_cast<AsyncInstallCallbackInfo *>(data);
if (asyncCallbackInfo == nullptr) {
APP_LOGE("asyncCallbackInfo is nullptr");
return;
}
const std::vector<std::string> bundleFilePath = asyncCallbackInfo->hapFiles;
InstallResult &installResult = asyncCallbackInfo->installResult;
if (bundleFilePath.empty() && asyncCallbackInfo->installParam.sharedBundleDirPaths.empty()) {
installResult.resultCode = static_cast<int32_t>(IStatusReceiver::ERR_INSTALL_FILE_PATH_INVALID);
return;
}
auto iBundleInstaller = CommonFunc::GetBundleInstaller();
if ((iBundleInstaller == nullptr) || (iBundleInstaller->AsObject() == nullptr)) {
APP_LOGE("can not get iBundleInstaller");
installResult.resultCode = static_cast<int32_t>(IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR);
return;
}
sptr<InstallerCallback> callback = new (std::nothrow) InstallerCallback();
sptr<BundleDeathRecipient> recipient(new (std::nothrow) BundleDeathRecipient(callback));
if (callback == nullptr || recipient == nullptr) {
APP_LOGE("callback or death recipient is nullptr");
installResult.resultCode = static_cast<int32_t>(IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR);
return;
}
iBundleInstaller->AsObject()->AddDeathRecipient(recipient);
if (asyncCallbackInfo->installParam.installFlag == InstallFlag::NORMAL) {
asyncCallbackInfo->installParam.installFlag = InstallFlag::REPLACE_EXISTING;
}
ErrCode res = iBundleInstaller->StreamInstall(bundleFilePath, asyncCallbackInfo->installParam, callback);
if (res == ERR_OK) {
installResult.resultCode = callback->GetResultCode();
APP_LOGD("InnerInstall resultCode %{public}d", installResult.resultCode);
installResult.resultMsg = callback->GetResultMsg();
APP_LOGD("InnerInstall resultMsg %{public}s", installResult.resultMsg.c_str());
installResult.innerCode = callback->GetInnerCode();
return;
}
APP_LOGE("install failed due to %{public}d", res);
std::unordered_map<int32_t, int32_t> proxyErrCodeMap;
InstallerHelper::CreateProxyErrCode(proxyErrCodeMap);
if (proxyErrCodeMap.find(res) != proxyErrCodeMap.end()) {
installResult.resultCode = proxyErrCodeMap.at(res);
installResult.innerCode = res;
} else {
installResult.resultCode = IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR;
}
}
static std::string GetFunctionName(const InstallOption &option)
{
if (option == InstallOption::INSTALL) {
return RESOURCE_NAME_OF_INSTALL;
} else if (option == InstallOption::RECOVER) {
return RESOURCE_NAME_OF_RECOVER;
} else if (option == InstallOption::UNINSTALL) {
return RESOURCE_NAME_OF_UNINSTALL;
} else if (option == InstallOption::UPDATE_BUNDLE_FOR_SELF) {
return RESOURCE_NAME_OF_UPDATE_BUNDLE_FOR_SELF;
} else if (option == InstallOption::UNINSTALL_AND_RECOVER) {
return RESOURCE_NAME_OF_UNINSTALL_AND_RECOVER;
}
return EMPTY_STRING;
}
void OperationCompleted(napi_env env, napi_status status, void *data)
{
AsyncInstallCallbackInfo *asyncCallbackInfo = reinterpret_cast<AsyncInstallCallbackInfo *>(data);
std::unique_ptr<AsyncInstallCallbackInfo> callbackPtr {asyncCallbackInfo};
napi_value result[CALLBACK_PARAM_SIZE] = {0};
InstallerHelper::ConvertInstallResult(callbackPtr->installResult);
if (callbackPtr->installResult.resultCode != SUCCESS) {
switch (callbackPtr->option) {
case InstallOption::INSTALL:
result[FIRST_PARAM] = BusinessError::CreateInstallError(env, callbackPtr->installResult.resultCode,
callbackPtr->installResult.innerCode, RESOURCE_NAME_OF_INSTALL, INSTALL_PERMISSION);
break;
case InstallOption::RECOVER:
result[FIRST_PARAM] = BusinessError::CreateCommonError(env, callbackPtr->installResult.resultCode,
RESOURCE_NAME_OF_RECOVER, RECOVER_PERMISSION);
break;
case InstallOption::UNINSTALL:
result[FIRST_PARAM] = BusinessError::CreateCommonError(env, callbackPtr->installResult.resultCode,
RESOURCE_NAME_OF_UNINSTALL, UNINSTALL_PERMISSION);
break;
case InstallOption::UPDATE_BUNDLE_FOR_SELF:
result[FIRST_PARAM] = BusinessError::CreateCommonError(env, callbackPtr->installResult.resultCode,
RESOURCE_NAME_OF_UPDATE_BUNDLE_FOR_SELF, INSTALL_SELF_PERMISSION);
break;
case InstallOption::UNINSTALL_AND_RECOVER:
result[FIRST_PARAM] = BusinessError::CreateCommonError(env, callbackPtr->installResult.resultCode,
RESOURCE_NAME_OF_UNINSTALL_AND_RECOVER, UNINSTALL_PERMISSION);
break;
default:
break;
}
} else {
NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[FIRST_PARAM]));
}
callbackPtr->err = callbackPtr->installResult.resultCode;
APP_LOGI("installer callback");
CommonFunc::NapiReturnDeferred<AsyncInstallCallbackInfo>(env, asyncCallbackInfo, result, ARGS_SIZE_ONE);
}
* Promise and async callback
*/
napi_value Install(napi_env env, napi_callback_info info)
{
APP_LOGI("Install called");
NapiArg args(env, info);
if (!args.Init(ARGS_SIZE_ONE, ARGS_SIZE_THREE)) {
APP_LOGE("init param failed");
BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
return nullptr;
}
auto argc = args.GetMaxArgc();
APP_LOGD("the number of argc is %{public}zu", argc);
if (argc < ARGS_SIZE_ONE) {
APP_LOGE("the params number is incorrect");
BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
return nullptr;
}
std::unique_ptr<AsyncInstallCallbackInfo> callbackPtr = std::make_unique<AsyncInstallCallbackInfo>(env);
callbackPtr->option = InstallOption::INSTALL;
for (size_t i = 0; i < argc; ++i) {
napi_valuetype valueType = napi_undefined;
napi_typeof(env, args[i], &valueType);
if (i == ARGS_POS_ZERO) {
if (!CommonFunc::ParseStringArray(env, callbackPtr->hapFiles, args[i])) {
APP_LOGE("Flags %{public}s invalid", callbackPtr->bundleName.c_str());
BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAMETERS, CORRESPONDING_TYPE);
return nullptr;
}
} else if (i == ARGS_POS_ONE) {
if (valueType == napi_function) {
NAPI_CALL(env, napi_create_reference(env, args[i], NAPI_RETURN_ONE, &callbackPtr->callback));
break;
}
if (valueType == napi_object && !ParseInstallParam(env, args[i], callbackPtr->installParam)) {
APP_LOGE("Parse installParam failed");
BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAMETERS, CORRESPONDING_TYPE);
return nullptr;
}
} else if (i == ARGS_POS_TWO) {
if (valueType == napi_function) {
NAPI_CALL(env, napi_create_reference(env, args[i], NAPI_RETURN_ONE, &callbackPtr->callback));
break;
}
} else {
APP_LOGE("param check error");
BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAMETERS, CORRESPONDING_TYPE);
return nullptr;
}
}
if (!CheckInstallParam(env, callbackPtr->installParam)) {
return nullptr;
}
if (callbackPtr->hapFiles.empty() && !callbackPtr->installParam.verifyCodeParams.empty()) {
BusinessError::ThrowError(env, ERROR_PARAM_CHECK_ERROR, PARAM_HAPS_FILE_EMPTY_ERROR);
return nullptr;
}
auto promise = CommonFunc::AsyncCallNativeMethod(env, callbackPtr.get(), RESOURCE_NAME_OF_INSTALL, InstallExecuter,
OperationCompleted);
callbackPtr.release();
APP_LOGI("call Install done");
return promise;
}
void UninstallOrRecoverExecuter(napi_env env, void *data)
{
AsyncInstallCallbackInfo *asyncCallbackInfo = reinterpret_cast<AsyncInstallCallbackInfo *>(data);
if (asyncCallbackInfo == nullptr) {
APP_LOGE("asyncCallbackInfo is nullptr");
return;
}
const std::string bundleName = asyncCallbackInfo->bundleName;
InstallResult &installResult = asyncCallbackInfo->installResult;
if (bundleName.empty()) {
installResult.resultCode = static_cast<int32_t>(IStatusReceiver::ERR_RECOVER_INVALID_BUNDLE_NAME);
return;
}
auto iBundleInstaller = CommonFunc::GetBundleInstaller();
if ((iBundleInstaller == nullptr) || (iBundleInstaller->AsObject() == nullptr)) {
APP_LOGE("can not get iBundleInstaller");
installResult.resultCode = static_cast<int32_t>(IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR);
return;
}
sptr<InstallerCallback> callback = new (std::nothrow) InstallerCallback();
sptr<BundleDeathRecipient> recipient(new (std::nothrow) BundleDeathRecipient(callback));
if (callback == nullptr || recipient == nullptr) {
APP_LOGE("callback or death recipient is nullptr");
installResult.resultCode = static_cast<int32_t>(IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR);
return;
}
iBundleInstaller->AsObject()->AddDeathRecipient(recipient);
if (asyncCallbackInfo->option == InstallOption::RECOVER) {
iBundleInstaller->Recover(bundleName, asyncCallbackInfo->installParam, callback);
} else if (asyncCallbackInfo->option == InstallOption::UNINSTALL) {
iBundleInstaller->Uninstall(bundleName, asyncCallbackInfo->installParam, callback);
} else {
APP_LOGE("error install option");
installResult.resultCode = static_cast<int32_t>(IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR);
return;
}
installResult.resultMsg = callback->GetResultMsg();
APP_LOGD("InnerRecover resultMsg %{public}s", installResult.resultMsg.c_str());
installResult.resultCode = callback->GetResultCode();
APP_LOGD("InnerRecover resultCode %{public}d", installResult.resultCode);
}
void UninstallByUninstallParamExecuter(napi_env env, void* data)
{
AsyncInstallCallbackInfo *asyncCallbackInfo = reinterpret_cast<AsyncInstallCallbackInfo *>(data);
if (asyncCallbackInfo == nullptr) {
APP_LOGE("asyncCallbackInfo is nullptr");
return;
}
const std::string bundleName = asyncCallbackInfo->uninstallParam.bundleName;
InstallResult &installResult = asyncCallbackInfo->installResult;
if (bundleName.empty()) {
installResult.resultCode =
static_cast<int32_t>(IStatusReceiver::ERR_APPEXECFWK_UNINSTALL_SHARE_APP_LIBRARY_IS_NOT_EXIST);
return;
}
auto iBundleInstaller = CommonFunc::GetBundleInstaller();
if ((iBundleInstaller == nullptr) || (iBundleInstaller->AsObject() == nullptr)) {
APP_LOGE("can not get iBundleInstaller");
installResult.resultCode = static_cast<int32_t>(IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR);
return;
}
sptr<InstallerCallback> callback = new (std::nothrow) InstallerCallback();
sptr<BundleDeathRecipient> recipient(new (std::nothrow) BundleDeathRecipient(callback));
if (callback == nullptr || recipient == nullptr) {
APP_LOGE("callback or death recipient is nullptr");
installResult.resultCode = static_cast<int32_t>(IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR);
return;
}
iBundleInstaller->AsObject()->AddDeathRecipient(recipient);
iBundleInstaller->Uninstall(asyncCallbackInfo->uninstallParam, callback);
installResult.resultMsg = callback->GetResultMsg();
installResult.resultCode = callback->GetResultCode();
}
napi_value UninstallByUninstallParam(napi_env env, napi_callback_info info,
std::unique_ptr<AsyncInstallCallbackInfo> &callbackPtr)
{
NapiArg args(env, info);
if (!args.Init(ARGS_SIZE_ONE, ARGS_SIZE_TWO)) {
APP_LOGE("init param failed");
BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
return nullptr;
}
for (size_t i = 0; i < args.GetMaxArgc(); ++i) {
napi_valuetype valueType = napi_undefined;
napi_typeof(env, args[i], &valueType);
if (i == ARGS_POS_ZERO) {
if (!ParseUninstallParam(env, args[i], callbackPtr->uninstallParam)) {
APP_LOGE("parse uninstallParam failed");
BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAMETERS, CORRESPONDING_TYPE);
return nullptr;
}
} else if ((i == ARGS_POS_ONE) && (valueType == napi_function)) {
NAPI_CALL(env, napi_create_reference(env, args[i], NAPI_RETURN_ONE, &callbackPtr->callback));
break;
} else {
APP_LOGE("param check error");
BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAMETERS, CORRESPONDING_TYPE);
return nullptr;
}
}
auto promise = CommonFunc::AsyncCallNativeMethod(env, callbackPtr.get(), GetFunctionName(callbackPtr->option),
UninstallByUninstallParamExecuter, OperationCompleted);
callbackPtr.release();
return promise;
}
napi_value UninstallOrRecover(napi_env env, napi_callback_info info,
std::unique_ptr<AsyncInstallCallbackInfo> &callbackPtr)
{
APP_LOGD("UninstallOrRecover by bundleName called");
NapiArg args(env, info);
if (!args.Init(ARGS_SIZE_ONE, ARGS_SIZE_THREE)) {
APP_LOGE("init param failed");
BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
return nullptr;
}
auto argc = args.GetMaxArgc();
APP_LOGD("the number of argc is %{public}zu", argc);
if (argc < ARGS_SIZE_ONE) {
APP_LOGE("the params number is incorrect");
BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
return nullptr;
}
for (size_t i = 0; i < args.GetMaxArgc(); ++i) {
napi_valuetype valueType = napi_undefined;
napi_typeof(env, args[i], &valueType);
if (i == ARGS_POS_ZERO) {
if (!CommonFunc::ParseString(env, args[i], callbackPtr->bundleName)) {
APP_LOGE("Flags %{public}s invalid", callbackPtr->bundleName.c_str());
BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAMETERS, CORRESPONDING_TYPE);
return nullptr;
}
} else if (i == ARGS_POS_ONE) {
if (valueType == napi_function) {
NAPI_CALL(env, napi_create_reference(env, args[i], NAPI_RETURN_ONE, &callbackPtr->callback));
break;
}
if (valueType == napi_object && !ParseInstallParam(env, args[i], callbackPtr->installParam)) {
APP_LOGE("Parse installParam.hashParams failed");
BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAMETERS, CORRESPONDING_TYPE);
return nullptr;
}
} else if (i == ARGS_POS_TWO) {
if (valueType == napi_function) {
NAPI_CALL(env, napi_create_reference(env, args[i], NAPI_RETURN_ONE, &callbackPtr->callback));
break;
}
} else {
APP_LOGE("param check error");
BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAMETERS, CORRESPONDING_TYPE);
return nullptr;
}
}
auto promise = CommonFunc::AsyncCallNativeMethod(env, callbackPtr.get(), GetFunctionName(callbackPtr->option),
UninstallOrRecoverExecuter, OperationCompleted);
callbackPtr.release();
return promise;
}
napi_value Recover(napi_env env, napi_callback_info info)
{
APP_LOGI("Recover called");
std::unique_ptr<AsyncInstallCallbackInfo> callbackPtr = std::make_unique<AsyncInstallCallbackInfo>(env);
callbackPtr->option = InstallOption::RECOVER;
APP_LOGI("call Recover done");
return UninstallOrRecover(env, info, callbackPtr);
}
napi_value Uninstall(napi_env env, napi_callback_info info)
{
APP_LOGI_NOFUNC("Uninstall called");
std::unique_ptr<AsyncInstallCallbackInfo> callbackPtr = std::make_unique<AsyncInstallCallbackInfo>(env);
callbackPtr->option = InstallOption::UNINSTALL;
NapiArg args(env, info);
args.Init(ARGS_SIZE_ONE, ARGS_SIZE_THREE);
napi_valuetype firstType = napi_undefined;
napi_typeof(env, args[FIRST_PARAM], &firstType);
if (firstType == napi_object) {
return UninstallByUninstallParam(env, info, callbackPtr);
}
APP_LOGI_NOFUNC("call Uninstall done");
return UninstallOrRecover(env, info, callbackPtr);
}
napi_value BundleInstallerConstructor(napi_env env, napi_callback_info info)
{
napi_value jsthis = nullptr;
NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &jsthis, nullptr));
return jsthis;
}
* Promise and async callback
*/
napi_value UpdateBundleForSelf(napi_env env, napi_callback_info info)
{
APP_LOGI("UpdateBundleForSelf called");
NapiArg args(env, info);
if (!args.Init(ARGS_SIZE_ONE, ARGS_SIZE_THREE)) {
APP_LOGE("init param failed");
BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
return nullptr;
}
auto argc = args.GetMaxArgc();
std::unique_ptr<AsyncInstallCallbackInfo> callbackPtr = std::make_unique<AsyncInstallCallbackInfo>(env);
callbackPtr->option = InstallOption::UPDATE_BUNDLE_FOR_SELF;
for (size_t i = 0; i < argc; ++i) {
napi_valuetype valueType = napi_undefined;
napi_typeof(env, args[i], &valueType);
if (i == ARGS_POS_ZERO) {
if (!CommonFunc::ParseStringArray(env, callbackPtr->hapFiles, args[i])) {
APP_LOGE("Flags %{public}s invalid", callbackPtr->bundleName.c_str());
BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAMETERS, CORRESPONDING_TYPE);
return nullptr;
}
} else if (i == ARGS_POS_ONE) {
if (valueType == napi_function) {
NAPI_CALL(env, napi_create_reference(env, args[i], NAPI_RETURN_ONE, &callbackPtr->callback));
break;
}
if (valueType == napi_object && !ParseInstallParam(env, args[i], callbackPtr->installParam)) {
APP_LOGE("Parse installParam failed");
BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAMETERS, CORRESPONDING_TYPE);
return nullptr;
}
} else if (i == ARGS_POS_TWO) {
if (valueType == napi_function) {
NAPI_CALL(env, napi_create_reference(env, args[i], NAPI_RETURN_ONE, &callbackPtr->callback));
break;
}
} else {
APP_LOGE("param check error");
BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAMETERS, CORRESPONDING_TYPE);
return nullptr;
}
}
if (!CheckInstallParam(env, callbackPtr->installParam)) {
return nullptr;
}
if (callbackPtr->hapFiles.empty() && !callbackPtr->installParam.verifyCodeParams.empty()) {
BusinessError::ThrowError(env, ERROR_PARAM_CHECK_ERROR, PARAM_HAPS_FILE_EMPTY_ERROR);
return nullptr;
}
callbackPtr->installParam.isSelfUpdate = true;
auto promise = CommonFunc::AsyncCallNativeMethod(env, callbackPtr.get(), RESOURCE_NAME_OF_INSTALL, InstallExecuter,
OperationCompleted);
callbackPtr.release();
APP_LOGI("call UpdateBundleForSelf done");
return promise;
}
void UninstallAndRecoverExecuter(napi_env env, void *data)
{
AsyncInstallCallbackInfo *asyncCallbackInfo = reinterpret_cast<AsyncInstallCallbackInfo *>(data);
if (asyncCallbackInfo == nullptr) {
APP_LOGE("asyncCallbackInfo is nullptr");
return;
}
const std::string bundleName = asyncCallbackInfo->bundleName;
InstallResult &installResult = asyncCallbackInfo->installResult;
if (bundleName.empty()) {
installResult.resultCode = static_cast<int32_t>(IStatusReceiver::ERR_RECOVER_INVALID_BUNDLE_NAME);
return;
}
auto iBundleInstaller = CommonFunc::GetBundleInstaller();
if ((iBundleInstaller == nullptr) || (iBundleInstaller->AsObject() == nullptr)) {
APP_LOGE("can not get iBundleInstaller");
installResult.resultCode = static_cast<int32_t>(IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR);
return;
}
sptr<InstallerCallback> callback = new (std::nothrow) InstallerCallback();
sptr<BundleDeathRecipient> recipient(new (std::nothrow) BundleDeathRecipient(callback));
if (callback == nullptr || recipient == nullptr) {
APP_LOGE("callback or death recipient is nullptr");
installResult.resultCode = static_cast<int32_t>(IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR);
return;
}
iBundleInstaller->AsObject()->AddDeathRecipient(recipient);
iBundleInstaller->UninstallAndRecover(bundleName, asyncCallbackInfo->installParam, callback);
installResult.resultMsg = callback->GetResultMsg();
installResult.resultCode = callback->GetResultCode();
}
napi_value UninstallAndRecover(napi_env env, napi_callback_info info)
{
APP_LOGI("UninstallAndRecover called");
NapiArg args(env, info);
if (!args.Init(ARGS_SIZE_ONE, ARGS_SIZE_TWO)) {
APP_LOGE("init param failed");
BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
return nullptr;
}
std::unique_ptr<AsyncInstallCallbackInfo> callbackPtr = std::make_unique<AsyncInstallCallbackInfo>(env);
callbackPtr->option = InstallOption::UNINSTALL_AND_RECOVER;
for (size_t i = 0; i < args.GetArgc(); ++i) {
napi_valuetype valueType = napi_undefined;
napi_typeof(env, args[i], &valueType);
if (i == ARGS_POS_ZERO) {
if (!CommonFunc::ParseString(env, args[i], callbackPtr->bundleName)) {
APP_LOGE("bundleName %{public}s invalid", callbackPtr->bundleName.c_str());
BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
return nullptr;
}
} else if (i == ARGS_POS_ONE) {
if (valueType != napi_object || !ParseInstallParam(env, args[i], callbackPtr->installParam)) {
APP_LOGW("Parse installParam failed");
}
} else {
APP_LOGE("The number of parameters is incorrect");
BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
return nullptr;
}
}
auto promise = CommonFunc::AsyncCallNativeMethod(env, callbackPtr.get(), RESOURCE_NAME_OF_UNINSTALL_AND_RECOVER,
UninstallAndRecoverExecuter, OperationCompleted);
callbackPtr.release();
APP_LOGI("call UninstallAndRecover done");
return promise;
}
void AddExtResourceExec(napi_env env, void *data)
{
ExtResourceCallbackInfo *asyncCallbackInfo = reinterpret_cast<ExtResourceCallbackInfo *>(data);
if (asyncCallbackInfo == nullptr) {
APP_LOGE("asyncCallbackInfo is null");
return;
}
asyncCallbackInfo->err = InstallerHelper::InnerAddExtResource(
asyncCallbackInfo->bundleName, asyncCallbackInfo->filePaths);
}
void AddExtResourceComplete(napi_env env, napi_status status, void *data)
{
ExtResourceCallbackInfo *asyncCallbackInfo = reinterpret_cast<ExtResourceCallbackInfo *>(data);
if (asyncCallbackInfo == nullptr) {
APP_LOGE("asyncCallbackInfo is null");
return;
}
std::unique_ptr<ExtResourceCallbackInfo> callbackPtr {asyncCallbackInfo};
napi_value result[ARGS_POS_TWO] = {0};
if (asyncCallbackInfo->err == NO_ERROR) {
NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[0]));
} else {
result[0] = BusinessError::CreateCommonError(
env, asyncCallbackInfo->err, ADD_EXT_RESOURCE, Constants::PERMISSION_INSTALL_BUNDLE);
}
CommonFunc::NapiReturnDeferred<ExtResourceCallbackInfo>(
env, asyncCallbackInfo, result, ARGS_SIZE_ONE);
}
napi_value AddExtResource(napi_env env, napi_callback_info info)
{
APP_LOGD("AddExtResource called");
NapiArg args(env, info);
ExtResourceCallbackInfo *asyncCallbackInfo = new (std::nothrow) ExtResourceCallbackInfo(env);
if (asyncCallbackInfo == nullptr) {
APP_LOGE("asyncCallbackInfo is null");
return nullptr;
}
std::unique_ptr<ExtResourceCallbackInfo> callbackPtr {asyncCallbackInfo};
if (!args.Init(ARGS_SIZE_TWO, ARGS_SIZE_TWO)) {
APP_LOGE("param count invalid");
BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
return nullptr;
}
for (size_t i = 0; i < args.GetArgc(); ++i) {
napi_valuetype valueType = napi_undefined;
napi_typeof(env, args[i], &valueType);
if (i == ARGS_POS_ZERO) {
if (!CommonFunc::ParseString(env, args[i], asyncCallbackInfo->bundleName)) {
APP_LOGE("bundleName invalid");
BusinessError::ThrowParameterTypeError(
env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
return nullptr;
}
} else if (i == ARGS_POS_ONE) {
if (CommonFunc::ParseStringArray(env, asyncCallbackInfo->filePaths, args[i]) == nullptr) {
APP_LOGE("filePaths invalid");
BusinessError::ThrowParameterTypeError(
env, ERROR_PARAM_CHECK_ERROR, FILE_PATH, TYPE_ARRAY);
return nullptr;
}
}
}
auto promise = CommonFunc::AsyncCallNativeMethod<ExtResourceCallbackInfo>(
env, asyncCallbackInfo, "AddExtResource", AddExtResourceExec, AddExtResourceComplete);
callbackPtr.release();
APP_LOGD("call AddExtResource done");
return promise;
}
void RemoveExtResourceExec(napi_env env, void *data)
{
ExtResourceCallbackInfo *asyncCallbackInfo = reinterpret_cast<ExtResourceCallbackInfo *>(data);
if (asyncCallbackInfo == nullptr) {
APP_LOGE("asyncCallbackInfo is null");
return;
}
asyncCallbackInfo->err = InstallerHelper::InnerRemoveExtResource(
asyncCallbackInfo->bundleName, asyncCallbackInfo->moduleNames);
}
void RemoveExtResourceComplete(napi_env env, napi_status status, void *data)
{
ExtResourceCallbackInfo *asyncCallbackInfo = reinterpret_cast<ExtResourceCallbackInfo *>(data);
if (asyncCallbackInfo == nullptr) {
APP_LOGE("asyncCallbackInfo is null");
return;
}
std::unique_ptr<ExtResourceCallbackInfo> callbackPtr {asyncCallbackInfo};
napi_value result[ARGS_POS_TWO] = {0};
if (asyncCallbackInfo->err == NO_ERROR) {
NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[0]));
} else {
result[0] = BusinessError::CreateCommonError(
env, asyncCallbackInfo->err, REMOVE_EXT_RESOURCE, UNINSTALL_PERMISSION);
}
CommonFunc::NapiReturnDeferred<ExtResourceCallbackInfo>(
env, asyncCallbackInfo, result, ARGS_SIZE_ONE);
}
napi_value RemoveExtResource(napi_env env, napi_callback_info info)
{
APP_LOGD("RemoveExtResource called");
NapiArg args(env, info);
ExtResourceCallbackInfo *asyncCallbackInfo = new (std::nothrow) ExtResourceCallbackInfo(env);
if (asyncCallbackInfo == nullptr) {
APP_LOGE("asyncCallbackInfo is null");
return nullptr;
}
std::unique_ptr<ExtResourceCallbackInfo> callbackPtr {asyncCallbackInfo};
if (!args.Init(ARGS_SIZE_TWO, ARGS_SIZE_TWO)) {
APP_LOGE("param count invalid");
BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
return nullptr;
}
for (size_t i = 0; i < args.GetArgc(); ++i) {
napi_valuetype valueType = napi_undefined;
napi_typeof(env, args[i], &valueType);
if (i == ARGS_POS_ZERO) {
if (!CommonFunc::ParseString(env, args[i], asyncCallbackInfo->bundleName)) {
APP_LOGE("bundleName invalid");
BusinessError::ThrowParameterTypeError(
env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
return nullptr;
}
} else if (i == ARGS_POS_ONE) {
if (CommonFunc::ParseStringArray(env, asyncCallbackInfo->moduleNames, args[i]) == nullptr) {
APP_LOGE("moduleNames invalid");
BusinessError::ThrowParameterTypeError(
env, ERROR_PARAM_CHECK_ERROR, MODULE_NAME, TYPE_ARRAY);
return nullptr;
}
}
}
auto promise = CommonFunc::AsyncCallNativeMethod<ExtResourceCallbackInfo>(
env, asyncCallbackInfo, "RemoveExtResource", RemoveExtResourceExec, RemoveExtResourceComplete);
callbackPtr.release();
APP_LOGD("call RemoveExtResource done");
return promise;
}
void CreateAppCloneExec(napi_env env, void *data)
{
CreateAppCloneCallbackInfo *asyncCallbackInfo = reinterpret_cast<CreateAppCloneCallbackInfo *>(data);
if (asyncCallbackInfo == nullptr) {
APP_LOGE("asyncCallbackInfo is null");
return;
}
APP_LOGD("CreateAppCloneExec param: bundleName = %{public}s, userId = %{public}d, appIndex = %{public}d",
asyncCallbackInfo->bundleName.c_str(),
asyncCallbackInfo->userId,
asyncCallbackInfo->appIndex);
asyncCallbackInfo->err = InstallerHelper::InnerCreateAppClone(asyncCallbackInfo->bundleName,
asyncCallbackInfo->userId, asyncCallbackInfo->appIndex);
}
void CreateAppCloneComplete(napi_env env, napi_status status, void *data)
{
CreateAppCloneCallbackInfo *asyncCallbackInfo = reinterpret_cast<CreateAppCloneCallbackInfo *>(data);
if (asyncCallbackInfo == nullptr) {
APP_LOGE("asyncCallbackInfo is null");
return;
}
std::unique_ptr<CreateAppCloneCallbackInfo> callbackPtr {asyncCallbackInfo};
asyncCallbackInfo->err = CommonFunc::ConvertErrCode(asyncCallbackInfo->err);
APP_LOGD("CreateAppCloneComplete err is %{public}d, appIndex is %{public}d",
asyncCallbackInfo->err,
asyncCallbackInfo->appIndex);
napi_value result[ARGS_SIZE_TWO] = {0};
if (asyncCallbackInfo->err == SUCCESS) {
NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[FIRST_PARAM]));
NAPI_CALL_RETURN_VOID(env, napi_create_int32(env, asyncCallbackInfo->appIndex, &result[SECOND_PARAM]));
} else {
result[FIRST_PARAM] = BusinessError::CreateCommonError(env, asyncCallbackInfo->err,
CREATE_APP_CLONE, Constants::PERMISSION_INSTALL_CLONE_BUNDLE);
}
CommonFunc::NapiReturnDeferred<CreateAppCloneCallbackInfo>(env, asyncCallbackInfo, result, ARGS_SIZE_TWO);
}
void ParseAppCloneParam(napi_env env, napi_value args, int32_t &userId, int32_t &appIndex)
{
if (!ParseUserId(env, args, userId)) {
APP_LOGI("parse userId failed. assign a default value = %{public}d", userId);
}
if (ParseAppIndex(env, args, appIndex)) {
if (appIndex == 0) {
APP_LOGI("parse appIndex success, but appIndex is 0, assign a value: %{public}d", ILLEGAL_APP_INDEX);
appIndex = ILLEGAL_APP_INDEX;
}
} else {
APP_LOGI("parse appIndex failed. assign a default value = %{public}d", appIndex);
}
}
napi_value CreateAppClone(napi_env env, napi_callback_info info)
{
APP_LOGI("begin to CreateAppClone");
NapiArg args(env, info);
std::unique_ptr<CreateAppCloneCallbackInfo> asyncCallbackInfo = std::make_unique<CreateAppCloneCallbackInfo>(env);
if (asyncCallbackInfo == nullptr) {
APP_LOGW("asyncCallbackInfo is null");
return nullptr;
}
if (!args.Init(ARGS_SIZE_ONE, ARGS_SIZE_TWO)) {
APP_LOGW("param count invalid");
BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
return nullptr;
}
size_t argc = args.GetMaxArgc();
for (size_t i = 0; i < argc; ++i) {
napi_valuetype valueType = napi_undefined;
napi_typeof(env, args[i], &valueType);
if (i == ARGS_POS_ZERO) {
if (!CommonFunc::ParseString(env, args[i], asyncCallbackInfo->bundleName)) {
APP_LOGW("parse bundleName failed");
BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
return nullptr;
}
} else if (i == ARGS_POS_ONE) {
if (valueType == napi_object) {
ParseAppCloneParam(env, args[i], asyncCallbackInfo->userId, asyncCallbackInfo->appIndex);
}
} else {
APP_LOGW("The number of parameters is incorrect");
BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
return nullptr;
}
}
if (asyncCallbackInfo->userId == Constants::UNSPECIFIED_USERID) {
asyncCallbackInfo->userId = IPCSkeleton::GetCallingUid() / Constants::BASE_USER_RANGE;
}
auto promise = CommonFunc::AsyncCallNativeMethod<CreateAppCloneCallbackInfo>(
env, asyncCallbackInfo.get(), CREATE_APP_CLONE, CreateAppCloneExec, CreateAppCloneComplete);
asyncCallbackInfo.release();
APP_LOGI("call napi CreateAppClone done");
return promise;
}
void DestroyAppCloneExec(napi_env env, void *data)
{
CreateAppCloneCallbackInfo *asyncCallbackInfo = reinterpret_cast<CreateAppCloneCallbackInfo *>(data);
if (asyncCallbackInfo == nullptr) {
APP_LOGE("asyncCallbackInfo is null");
return;
}
APP_LOGD("DestroyAppCloneExec param: bundleName = %{public}s, userId = %{public}d, appIndex = %{public}d",
asyncCallbackInfo->bundleName.c_str(),
asyncCallbackInfo->userId,
asyncCallbackInfo->appIndex);
asyncCallbackInfo->err = InstallerHelper::InnerDestroyAppClone(asyncCallbackInfo->bundleName,
asyncCallbackInfo->userId, asyncCallbackInfo->appIndex, asyncCallbackInfo->destroyAppCloneParam);
}
void DestroyAppCloneComplete(napi_env env, napi_status status, void *data)
{
CreateAppCloneCallbackInfo *asyncCallbackInfo = reinterpret_cast<CreateAppCloneCallbackInfo *>(data);
if (asyncCallbackInfo == nullptr) {
APP_LOGE("asyncCallbackInfo is null");
return;
}
std::unique_ptr<CreateAppCloneCallbackInfo> callbackPtr {asyncCallbackInfo};
asyncCallbackInfo->err = CommonFunc::ConvertErrCode(asyncCallbackInfo->err);
APP_LOGD("DestroyAppCloneComplete err is %{public}d, appIndex is %{public}d",
asyncCallbackInfo->err,
asyncCallbackInfo->appIndex);
napi_value result[ARGS_SIZE_TWO] = {0};
if (asyncCallbackInfo->err == SUCCESS) {
NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[FIRST_PARAM]));
} else {
result[FIRST_PARAM] = BusinessError::CreateCommonError(env, asyncCallbackInfo->err,
DESTROY_APP_CLONE, Constants::PERMISSION_UNINSTALL_CLONE_BUNDLE);
}
CommonFunc::NapiReturnDeferred<CreateAppCloneCallbackInfo>(env, asyncCallbackInfo, result, ARGS_SIZE_ONE);
}
static bool ParseDestroyAppCloneParam(napi_env env, napi_value args, napi_valuetype valueType, int32_t &userId,
DestroyAppCloneParam &destroyAppCloneParam)
{
if (valueType == napi_number && !CommonFunc::ParseInt(env, args, userId)) {
APP_LOGW("parse userId failed,set this parameter to the caller userId");
} else if (valueType == napi_object) {
if (!ParseUserId(env, args, destroyAppCloneParam.userId)) {
APP_LOGW("parse userId failed,using default value");
} else {
userId = destroyAppCloneParam.userId;
}
if (!ParseParameters(env, args, destroyAppCloneParam.parameters)) {
APP_LOGW("parse parameters failed,using default value");
}
}
return true;
}
napi_value DestroyAppClone(napi_env env, napi_callback_info info)
{
APP_LOGI("begin to destroyAppClone");
NapiArg args(env, info);
std::unique_ptr<CreateAppCloneCallbackInfo> asyncCallbackInfo = std::make_unique<CreateAppCloneCallbackInfo>(env);
if (asyncCallbackInfo == nullptr) {
APP_LOGW("asyncCallbackInfo is null");
return nullptr;
}
if (!args.Init(ARGS_SIZE_TWO, ARGS_SIZE_THREE)) {
APP_LOGW("param count invalid");
BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
return nullptr;
}
size_t argc = args.GetMaxArgc();
for (size_t i = 0; i < argc; ++i) {
napi_valuetype valueType = napi_undefined;
napi_typeof(env, args[i], &valueType);
if (i == ARGS_POS_ZERO) {
if (!CommonFunc::ParseString(env, args[i], asyncCallbackInfo->bundleName)) {
APP_LOGW("parse bundleName failed");
BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
return nullptr;
}
} else if (i == ARGS_POS_ONE) {
if (!CommonFunc::ParseInt(env, args[i], asyncCallbackInfo->appIndex)) {
APP_LOGW("parse appIndex failed");
BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, APP_INDEX, TYPE_NUMBER);
return nullptr;
}
} else if (i == ARGS_POS_TWO) {
if (!ParseDestroyAppCloneParam(
env, args[i], valueType, asyncCallbackInfo->userId, asyncCallbackInfo->destroyAppCloneParam)) {
APP_LOGW("parse destroyAppCloneParam failed");
}
} else {
APP_LOGE("The number of parameters is incorrect");
BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
return nullptr;
}
}
if (asyncCallbackInfo->userId == Constants::UNSPECIFIED_USERID) {
asyncCallbackInfo->userId = IPCSkeleton::GetCallingUid() / Constants::BASE_USER_RANGE;
}
auto promise = CommonFunc::AsyncCallNativeMethod<CreateAppCloneCallbackInfo>(
env, asyncCallbackInfo.get(), DESTROY_APP_CLONE, DestroyAppCloneExec, DestroyAppCloneComplete);
asyncCallbackInfo.release();
APP_LOGI("call napi destroyAppTwin done");
return promise;
}
void InstallPreexistingAppExec(napi_env env, void *data)
{
InstallPreexistingAppCallbackInfo *asyncCallbackInfo = reinterpret_cast<InstallPreexistingAppCallbackInfo *>(data);
if (asyncCallbackInfo == nullptr) {
APP_LOGE("asyncCallbackInfo is null");
return;
}
APP_LOGD("param: bundleName = %{public}s, userId = %{public}d",
asyncCallbackInfo->bundleName.c_str(),
asyncCallbackInfo->userId);
asyncCallbackInfo->err =
InstallerHelper::InnerInstallPreexistingApp(asyncCallbackInfo->bundleName, asyncCallbackInfo->userId);
}
void InstallPreexistingAppComplete(napi_env env, napi_status status, void *data)
{
InstallPreexistingAppCallbackInfo *asyncCallbackInfo = reinterpret_cast<InstallPreexistingAppCallbackInfo *>(data);
if (asyncCallbackInfo == nullptr) {
APP_LOGE("asyncCallbackInfo is null");
return;
}
std::unique_ptr<InstallPreexistingAppCallbackInfo> callbackPtr {asyncCallbackInfo};
int32_t innerCode = static_cast<int32_t>(asyncCallbackInfo->err);
asyncCallbackInfo->err = CommonFunc::ConvertErrCode(asyncCallbackInfo->err);
APP_LOGD("err is %{public}d, innerCode is %{public}d", asyncCallbackInfo->err, innerCode);
napi_value result[ARGS_SIZE_ONE] = {0};
if (asyncCallbackInfo->err == SUCCESS) {
NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[FIRST_PARAM]));
} else {
result[FIRST_PARAM] = BusinessError::CreateInstallError(env, asyncCallbackInfo->err,
innerCode, INSTALL_PREEXISTING_APP, Constants::PERMISSION_INSTALL_BUNDLE, false);
}
CommonFunc::NapiReturnDeferred<InstallPreexistingAppCallbackInfo>(env, asyncCallbackInfo, result, ARGS_SIZE_ONE);
}
napi_value InstallPreexistingApp(napi_env env, napi_callback_info info)
{
APP_LOGI("begin");
NapiArg args(env, info);
std::unique_ptr<InstallPreexistingAppCallbackInfo> asyncCallbackInfo
= std::make_unique<InstallPreexistingAppCallbackInfo>(env);
if (asyncCallbackInfo == nullptr) {
APP_LOGW("asyncCallbackInfo is null");
return nullptr;
}
if (!args.Init(ARGS_SIZE_ONE, ARGS_SIZE_TWO)) {
APP_LOGW("param count invalid");
BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
return nullptr;
}
size_t argc = args.GetMaxArgc();
for (size_t i = 0; i < argc; ++i) {
if (i == ARGS_POS_ZERO) {
if (!CommonFunc::ParseString(env, args[i], asyncCallbackInfo->bundleName)) {
APP_LOGW("parse bundleName failed");
BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
return nullptr;
}
} else if (i == ARGS_POS_ONE) {
if (!CommonFunc::ParseInt(env, args[i], asyncCallbackInfo->userId)) {
APP_LOGW("parse userId failed");
}
} else {
APP_LOGW("The number of parameters is incorrect");
BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
return nullptr;
}
}
if (asyncCallbackInfo->userId == Constants::UNSPECIFIED_USERID) {
asyncCallbackInfo->userId = IPCSkeleton::GetCallingUid() / Constants::BASE_USER_RANGE;
}
auto promise = CommonFunc::AsyncCallNativeMethod<InstallPreexistingAppCallbackInfo>(
env, asyncCallbackInfo.get(), INSTALL_PREEXISTING_APP,
InstallPreexistingAppExec, InstallPreexistingAppComplete);
asyncCallbackInfo.release();
APP_LOGI("call napi done");
return promise;
}
void UninstallNewPreinstalledAppsExec(napi_env env, void *data)
{
UninstallNewPreinstalledAppsCallbackInfo *asyncCallbackInfo =
reinterpret_cast<UninstallNewPreinstalledAppsCallbackInfo *>(data);
if (asyncCallbackInfo == nullptr) {
APP_LOGE("asyncCallbackInfo is null");
return;
}
asyncCallbackInfo->err = InstallerHelper::InnerUninstallNewPreinstalledApps(asyncCallbackInfo->bundleNames);
}
void UninstallNewPreinstalledAppsComplete(napi_env env, napi_status status, void *data)
{
UninstallNewPreinstalledAppsCallbackInfo *asyncCallbackInfo =
reinterpret_cast<UninstallNewPreinstalledAppsCallbackInfo *>(data);
if (asyncCallbackInfo == nullptr) {
APP_LOGE("asyncCallbackInfo is null");
return;
}
std::unique_ptr<UninstallNewPreinstalledAppsCallbackInfo> callbackPtr {asyncCallbackInfo};
asyncCallbackInfo->err = CommonFunc::ConvertErrCode(asyncCallbackInfo->err);
napi_value result[ARGS_SIZE_ONE] = {0};
if (asyncCallbackInfo->err == SUCCESS) {
NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[FIRST_PARAM]));
} else {
result[FIRST_PARAM] = BusinessError::CreateCommonError(env, asyncCallbackInfo->err,
UNINSTALL_NEW_PREINSTALLED_APPS, UNINSTALL_BUNDLE_PERMISSION);
}
CommonFunc::NapiReturnDeferred<UninstallNewPreinstalledAppsCallbackInfo>(
env, asyncCallbackInfo, result, ARGS_SIZE_ONE);
}
napi_value UninstallNewPreinstalledApps(napi_env env, napi_callback_info info)
{
NapiArg args(env, info);
std::unique_ptr<UninstallNewPreinstalledAppsCallbackInfo> asyncCallbackInfo =
std::make_unique<UninstallNewPreinstalledAppsCallbackInfo>(env);
if (!args.Init(ARGS_SIZE_ONE, ARGS_SIZE_ONE)) {
APP_LOGE("param count invalid");
BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
return nullptr;
}
if (!CommonFunc::ParseStringArray(env, asyncCallbackInfo->bundleNames, args[FIRST_PARAM])) {
APP_LOGE("bundleNames invalid");
BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAMETERS, TYPE_ARRAY);
return nullptr;
}
if (asyncCallbackInfo->bundleNames.size() > Constants::MAX_UNINSTALL_PREINSTALLED_APP_NUM) {
APP_LOGE("bundleNames size exceeds the limit %{public}zu", asyncCallbackInfo->bundleNames.size());
BusinessError::ThrowError(env, ERROR_PARAM_CHECK_ERROR, PARAM_BUNDLE_NAMES_SIZE_EXCEEDS_LIMIT);
return nullptr;
}
auto promise = CommonFunc::AsyncCallNativeMethod<UninstallNewPreinstalledAppsCallbackInfo>(
env, asyncCallbackInfo.get(), UNINSTALL_NEW_PREINSTALLED_APPS,
UninstallNewPreinstalledAppsExec, UninstallNewPreinstalledAppsComplete);
asyncCallbackInfo.release();
return promise;
}
void ParseInstallPluginParam(napi_env env, napi_value args, InstallPluginParam &installPluginParam)
{
if (!ParseUserId(env, args, installPluginParam.userId)) {
APP_LOGW("parse userId failed. assign default value");
}
if (!ParseParameters(env, args, installPluginParam.parameters)) {
APP_LOGW("parse parameters failed. using default value");
}
}
void InstallPluginExec(napi_env env, void *data)
{
PluginCallbackInfo *asyncCallbackInfo = reinterpret_cast<PluginCallbackInfo *>(data);
if (asyncCallbackInfo == nullptr) {
APP_LOGE("asyncCallbackInfo is null");
return;
}
asyncCallbackInfo->err = InstallerHelper::InnerInstallPlugin(asyncCallbackInfo->hostBundleName,
asyncCallbackInfo->pluginFilePaths, asyncCallbackInfo->installPluginParam);
}
void InstallPluginComplete(napi_env env, napi_status status, void *data)
{
PluginCallbackInfo *asyncCallbackInfo = reinterpret_cast<PluginCallbackInfo *>(data);
if (asyncCallbackInfo == nullptr) {
APP_LOGE("asyncCallbackInfo is null");
return;
}
std::unique_ptr<PluginCallbackInfo> callbackPtr {asyncCallbackInfo};
asyncCallbackInfo->err = CommonFunc::ConvertErrCode(asyncCallbackInfo->err);
APP_LOGD("InstallPluginComplete err is %{public}d", asyncCallbackInfo->err);
napi_value result[ARGS_SIZE_ONE] = {0};
if (asyncCallbackInfo->err == SUCCESS) {
NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[FIRST_PARAM]));
} else {
result[FIRST_PARAM] = BusinessError::CreateCommonError(env, asyncCallbackInfo->err,
INSTALL_PLUGIN, Constants::PERMISSION_INSTALL_PLUGIN);
}
CommonFunc::NapiReturnDeferred<PluginCallbackInfo>(env, asyncCallbackInfo, result, ARGS_SIZE_ONE);
}
napi_value InstallPlugin(napi_env env, napi_callback_info info)
{
APP_LOGI("begin to InstallPlugin");
NapiArg args(env, info);
std::unique_ptr<PluginCallbackInfo> asyncCallbackInfo = std::make_unique<PluginCallbackInfo>(env);
if (!args.Init(ARGS_SIZE_TWO, ARGS_SIZE_THREE)) {
APP_LOGW("param count invalid");
BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
return nullptr;
}
size_t argc = args.GetMaxArgc();
for (size_t i = 0; i < argc; ++i) {
napi_valuetype valueType = napi_undefined;
napi_typeof(env, args[i], &valueType);
if (i == ARGS_POS_ZERO) {
if (!CommonFunc::ParseString(env, args[i], asyncCallbackInfo->hostBundleName)) {
APP_LOGW("parse hostBundleName failed");
BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
return nullptr;
}
} else if (i == ARGS_POS_ONE) {
if (!CommonFunc::ParseStringArray(env, asyncCallbackInfo->pluginFilePaths, args[i])) {
APP_LOGE("pluginFilePaths invalid");
BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, FILE_PATH, TYPE_ARRAY);
return nullptr;
}
} else if (i == ARGS_POS_TWO) {
if (valueType == napi_object) {
ParseInstallPluginParam(env, args[i], asyncCallbackInfo->installPluginParam);
}
} else {
APP_LOGW("The number of parameters is incorrect");
BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
return nullptr;
}
}
if (asyncCallbackInfo->installPluginParam.userId == Constants::UNSPECIFIED_USERID) {
asyncCallbackInfo->installPluginParam.userId = IPCSkeleton::GetCallingUid() / Constants::BASE_USER_RANGE;
}
auto promise = CommonFunc::AsyncCallNativeMethod<PluginCallbackInfo>(
env, asyncCallbackInfo.get(), INSTALL_PLUGIN, InstallPluginExec, InstallPluginComplete);
asyncCallbackInfo.release();
APP_LOGI("call napi InstallPlugin done");
return promise;
}
void UninstallPluginExec(napi_env env, void *data)
{
PluginCallbackInfo *asyncCallbackInfo = reinterpret_cast<PluginCallbackInfo *>(data);
if (asyncCallbackInfo == nullptr) {
APP_LOGE("asyncCallbackInfo is null");
return;
}
APP_LOGD("param: hostBundleName = %{public}s, pluginBundleName = %{public}s, userId = %{public}d",
asyncCallbackInfo->hostBundleName.c_str(),
asyncCallbackInfo->pluginBundleName.c_str(),
asyncCallbackInfo->installPluginParam.userId);
asyncCallbackInfo->err = InstallerHelper::InnerUninstallPlugin(asyncCallbackInfo->hostBundleName,
asyncCallbackInfo->pluginBundleName, asyncCallbackInfo->installPluginParam);
}
void UninstallPluginComplete(napi_env env, napi_status status, void *data)
{
PluginCallbackInfo *asyncCallbackInfo = reinterpret_cast<PluginCallbackInfo *>(data);
if (asyncCallbackInfo == nullptr) {
APP_LOGE("asyncCallbackInfo is null");
return;
}
std::unique_ptr<PluginCallbackInfo> callbackPtr {asyncCallbackInfo};
asyncCallbackInfo->err = CommonFunc::ConvertErrCode(asyncCallbackInfo->err);
APP_LOGD("UninstallPluginComplete err is %{public}d", asyncCallbackInfo->err);
napi_value result[ARGS_SIZE_ONE] = {0};
if (asyncCallbackInfo->err == SUCCESS) {
NAPI_CALL_RETURN_VOID(env, napi_get_null(env, &result[FIRST_PARAM]));
} else {
result[FIRST_PARAM] = BusinessError::CreateCommonError(env, asyncCallbackInfo->err,
UNINSTALL_PLUGIN, Constants::PERMISSION_UNINSTALL_PLUGIN);
}
CommonFunc::NapiReturnDeferred<PluginCallbackInfo>(env, asyncCallbackInfo, result, ARGS_SIZE_ONE);
}
napi_value UninstallPlugin(napi_env env, napi_callback_info info)
{
APP_LOGI("begin to UninstallPlugin");
NapiArg args(env, info);
std::unique_ptr<PluginCallbackInfo> asyncCallbackInfo = std::make_unique<PluginCallbackInfo>(env);
if (!args.Init(ARGS_SIZE_TWO, ARGS_SIZE_THREE)) {
APP_LOGW("param count invalid");
BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
return nullptr;
}
size_t argc = args.GetMaxArgc();
for (size_t i = 0; i < argc; ++i) {
napi_valuetype valueType = napi_undefined;
napi_typeof(env, args[i], &valueType);
if (i == ARGS_POS_ZERO) {
if (!CommonFunc::ParseString(env, args[i], asyncCallbackInfo->hostBundleName)) {
APP_LOGW("parse hostBundleName failed");
BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, BUNDLE_NAME, TYPE_STRING);
return nullptr;
}
} else if (i == ARGS_POS_ONE) {
if (!CommonFunc::ParseString(env, args[i], asyncCallbackInfo->pluginBundleName)) {
APP_LOGW("parse pluginBundleName failed");
BusinessError::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PLUGIN_BUNDLE_NAME, TYPE_STRING);
return nullptr;
}
} else if (i == ARGS_POS_TWO) {
if (valueType == napi_object) {
ParseInstallPluginParam(env, args[i], asyncCallbackInfo->installPluginParam);
}
} else {
APP_LOGW("The number of parameters is incorrect");
BusinessError::ThrowTooFewParametersError(env, ERROR_PARAM_CHECK_ERROR);
return nullptr;
}
}
if (asyncCallbackInfo->installPluginParam.userId == Constants::UNSPECIFIED_USERID) {
asyncCallbackInfo->installPluginParam.userId = IPCSkeleton::GetCallingUid() / Constants::BASE_USER_RANGE;
}
auto promise = CommonFunc::AsyncCallNativeMethod<PluginCallbackInfo>(
env, asyncCallbackInfo.get(), UNINSTALL_PLUGIN, UninstallPluginExec, UninstallPluginComplete);
asyncCallbackInfo.release();
APP_LOGI("call napi UninstallPlugin done");
return promise;
}
}
}