diff --git a/bundle.json b/bundle.json index 0917a858c4eea313fde155fc5eca9ec20e9e2654..fbe10a792dbdc0f4b8c6004177031ba2775d22e9 100644 --- a/bundle.json +++ b/bundle.json @@ -101,7 +101,8 @@ "build": { "sub_component": [ "//foundation/bundlemanager/bundle_framework:bms_target", - "//foundation/bundlemanager/bundle_framework/etc:bms_para" + "//foundation/bundlemanager/bundle_framework/etc:bms_para", + "//foundation/bundlemanager/bundle_framework/interfaces/kits/ani:ani_bms_packages" ], "inner_kits": [ { @@ -199,6 +200,22 @@ "visibility": [ "bundle_tool" ] + }, + { + "header": { + "header_base": "//foundation/bundlemanager/bundle_framework/interfaces/kits/ani/common/", + "header_files": [ + "common_fun_ani.h", + "enum_util.h" + ] + }, + "name": "//foundation/bundlemanager/bundle_framework/interfaces/kits/ani/common:bms_ani_common" + }, + { + "name": "//foundation/bundlemanager/bundle_framework/interfaces/kits/ani/bundle_manager:copy_bundleManager_ets" + }, + { + "name": "//foundation/bundlemanager/bundle_framework/interfaces/kits/ani/bundle_manager:copy_bundle_installer_ets" } ], "test": [ diff --git a/interfaces/inner_api/appexecfwk_base/include/ability_info.h b/interfaces/inner_api/appexecfwk_base/include/ability_info.h index 8df3349ffcaab7123d28b34cb877f37a9b3cef5b..40f85b6dd85e88e7447b6f114f4593d5b3fe2196 100644 --- a/interfaces/inner_api/appexecfwk_base/include/ability_info.h +++ b/interfaces/inner_api/appexecfwk_base/include/ability_info.h @@ -255,6 +255,7 @@ struct AbilityInfo : public Parcelable { std::string extensionTypeName; std::string srcPath; std::string srcLanguage = "js"; + std::string codeLanguage = Constants::CODE_LANGUAGE_1_1; std::string process; std::string uri; diff --git a/interfaces/inner_api/appexecfwk_base/include/application_info.h b/interfaces/inner_api/appexecfwk_base/include/application_info.h index 3f8c9cb2fd1292782c6d7124d746c456c6c3987e..0d14ff3ccb8e31ef438129456e55a373212e4cdf 100644 --- a/interfaces/inner_api/appexecfwk_base/include/application_info.h +++ b/interfaces/inner_api/appexecfwk_base/include/application_info.h @@ -326,6 +326,7 @@ struct ApplicationInfo : public Parcelable { std::string installSource; std::string configuration; + std::string codeLanguage; Resource iconResource; Resource labelResource; Resource descriptionResource; diff --git a/interfaces/inner_api/appexecfwk_base/include/bundle_constants.h b/interfaces/inner_api/appexecfwk_base/include/bundle_constants.h index a3254ace9276e0777bf53b2b5de5e30767250b3c..ab8fc5124e75afea2a26c01d3ab5223821b148f1 100644 --- a/interfaces/inner_api/appexecfwk_base/include/bundle_constants.h +++ b/interfaces/inner_api/appexecfwk_base/include/bundle_constants.h @@ -183,6 +183,11 @@ constexpr const char* VERIFY_UNINSTALL_RULE_VALUE = "true"; constexpr const char* SUPPORT_APP_TYPES_SEPARATOR = ","; constexpr const char* APP_DISTRIBUTION_TYPE_WHITE_LIST = "appDistributionTypeWhiteList"; + +constexpr const char* CODE_LANGUAGE = "codeLanguage"; +constexpr const char* CODE_LANGUAGE_1_1 = "1.1"; +constexpr const char* CODE_LANGUAGE_1_2 = "1.2"; +constexpr const char* CODE_LANGUAGE_HYBRID = "hybrid"; } // namespace Constants } // namespace AppExecFwk } // namespace OHOS diff --git a/interfaces/inner_api/appexecfwk_base/include/extension_ability_info.h b/interfaces/inner_api/appexecfwk_base/include/extension_ability_info.h index f6985da10745ba7cab7694b99c9970a12a4a8edf..a14c5290d6ef56ebb96d9d7d0e06afcaf47ff29a 100644 --- a/interfaces/inner_api/appexecfwk_base/include/extension_ability_info.h +++ b/interfaces/inner_api/appexecfwk_base/include/extension_ability_info.h @@ -182,6 +182,7 @@ struct ExtensionAbilityInfo : public Parcelable { std::string hapPath; std::string process; std::string customProcess; + std::string codeLanguage = Constants::CODE_LANGUAGE_1_1; std::vector permissions; std::vector appIdentifierAllowList; std::vector metadata; diff --git a/interfaces/inner_api/appexecfwk_base/include/hap_module_info.h b/interfaces/inner_api/appexecfwk_base/include/hap_module_info.h index be6b3573ff303ceb9e738d9713bf418202554e16..f3cc457831bf91b4c269d81205db15d658af631a 100644 --- a/interfaces/inner_api/appexecfwk_base/include/hap_module_info.h +++ b/interfaces/inner_api/appexecfwk_base/include/hap_module_info.h @@ -164,6 +164,7 @@ struct HapModuleInfo : public Parcelable { std::string abilitySrcEntryDelegator; std::string abilityStageSrcEntryDelegator; std::string appStartup; + std::string codeLanguage = Constants::CODE_LANGUAGE_1_1; // quick fix hqf info HqfInfo hqfInfo; diff --git a/interfaces/inner_api/appexecfwk_base/src/ability_info.cpp b/interfaces/inner_api/appexecfwk_base/src/ability_info.cpp index d3702e3e1d243556533ee24ea36944bde599262c..18c1a52e9c80c4754e55c2d33d585754af6d1dfa 100644 --- a/interfaces/inner_api/appexecfwk_base/src/ability_info.cpp +++ b/interfaces/inner_api/appexecfwk_base/src/ability_info.cpp @@ -142,6 +142,7 @@ bool AbilityInfo::ReadFromParcel(Parcel &parcel) launchMode = static_cast(parcel.ReadInt32()); srcPath = Str16ToStr8(parcel.ReadString16()); srcLanguage = Str16ToStr8(parcel.ReadString16()); + codeLanguage = parcel.ReadString(); int32_t permissionsSize; READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, permissionsSize); @@ -378,6 +379,7 @@ bool AbilityInfo::Marshalling(Parcel &parcel) const WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, static_cast(launchMode)); WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(srcPath)); WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(srcLanguage)); + WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String, parcel, codeLanguage); WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, permissions.size()); for (auto &permission : permissions) { WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(permission)); @@ -653,6 +655,7 @@ void to_json(nlohmann::json &jsonObject, const AbilityInfo &abilityInfo) {JSON_KEY_LAUNCH_MODE, abilityInfo.launchMode}, {JSON_KEY_SRC_PATH, abilityInfo.srcPath}, {JSON_KEY_SRC_LANGUAGE, abilityInfo.srcLanguage}, + {Constants::CODE_LANGUAGE, abilityInfo.codeLanguage}, {JSON_KEY_PERMISSIONS, abilityInfo.permissions}, {JSON_KEY_PROCESS, abilityInfo.process}, {JSON_KEY_DEVICE_TYPES, abilityInfo.deviceTypes}, @@ -918,6 +921,12 @@ void from_json(const nlohmann::json &jsonObject, AbilityInfo &abilityInfo) abilityInfo.srcLanguage, false, parseResult); + BMSJsonUtil::GetStrValueIfFindKey(jsonObject, + jsonObjectEnd, + Constants::CODE_LANGUAGE, + abilityInfo.codeLanguage, + false, + parseResult); GetValueIfFindKey>(jsonObject, jsonObjectEnd, JSON_KEY_PERMISSIONS, diff --git a/interfaces/inner_api/appexecfwk_base/src/application_info.cpp b/interfaces/inner_api/appexecfwk_base/src/application_info.cpp index 4037e739138aaf01bf21368b28d9d126bab9addf..b23a970f430dbe408a11ae2dcf36bb2c0237fde2 100644 --- a/interfaces/inner_api/appexecfwk_base/src/application_info.cpp +++ b/interfaces/inner_api/appexecfwk_base/src/application_info.cpp @@ -599,6 +599,7 @@ bool ApplicationInfo::ReadFromParcel(Parcel &parcel) installSource = Str16ToStr8(parcel.ReadString16()); configuration = Str16ToStr8(parcel.ReadString16()); + codeLanguage = parcel.ReadString(); cloudFileSyncEnabled = parcel.ReadBool(); applicationFlags = parcel.ReadInt32(); ubsanEnabled = parcel.ReadBool(); @@ -784,6 +785,7 @@ bool ApplicationInfo::Marshalling(Parcel &parcel) const WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(installSource)); WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(configuration)); + WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String, parcel, codeLanguage); WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, cloudFileSyncEnabled); WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, applicationFlags); WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, ubsanEnabled); @@ -1039,6 +1041,7 @@ void to_json(nlohmann::json &jsonObject, const ApplicationInfo &applicationInfo) {APPLICATION_APP_INDEX, applicationInfo.appIndex}, {APPLICATION_INSTALL_SOURCE, applicationInfo.installSource}, {APPLICATION_CONFIGURATION, applicationInfo.configuration}, + {Constants::CODE_LANGUAGE, applicationInfo.codeLanguage}, {APPLICATION_CLOUD_FILE_SYNC_ENABLED, applicationInfo.cloudFileSyncEnabled}, {APPLICATION_APPLICATION_FLAGS, applicationInfo.applicationFlags}, {APPLICATION_UBSAN_ENABLED, applicationInfo.ubsanEnabled}, @@ -1252,6 +1255,8 @@ void from_json(const nlohmann::json &jsonObject, ApplicationInfo &applicationInf applicationInfo.hwasanEnabled, false, parseResult); BMSJsonUtil::GetStrValueIfFindKey(jsonObject, jsonObjectEnd, APPLICATION_CONFIGURATION, applicationInfo.configuration, false, parseResult); + BMSJsonUtil::GetStrValueIfFindKey(jsonObject, jsonObjectEnd, Constants::CODE_LANGUAGE, + applicationInfo.codeLanguage, false, parseResult); BMSJsonUtil::GetBoolValueIfFindKey(jsonObject, jsonObjectEnd, APPLICATION_CLOUD_FILE_SYNC_ENABLED, applicationInfo.cloudFileSyncEnabled, false, parseResult); GetValueIfFindKey(jsonObject, jsonObjectEnd, APPLICATION_APPLICATION_FLAGS, diff --git a/interfaces/inner_api/appexecfwk_base/src/extension_ability_info.cpp b/interfaces/inner_api/appexecfwk_base/src/extension_ability_info.cpp index 8c4ed58986add9e4d5da9de221094dbfee16c551..bc01211fbe15d81c2738e425a376669347f1f9aa 100644 --- a/interfaces/inner_api/appexecfwk_base/src/extension_ability_info.cpp +++ b/interfaces/inner_api/appexecfwk_base/src/extension_ability_info.cpp @@ -277,6 +277,7 @@ bool ExtensionAbilityInfo::ReadFromParcel(Parcel &parcel) dataGroupIds.emplace_back(Str16ToStr8(parcel.ReadString16())); } customProcess = Str16ToStr8(parcel.ReadString16()); + codeLanguage = parcel.ReadString(); return true; } @@ -367,6 +368,7 @@ bool ExtensionAbilityInfo::Marshalling(Parcel &parcel) const WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(dataGroupId)); } WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(customProcess)); + WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String, parcel, codeLanguage); return true; } @@ -407,7 +409,8 @@ void to_json(nlohmann::json &jsonObject, const ExtensionAbilityInfo &extensionIn {DATA_GROUP_IDS, extensionInfo.dataGroupIds}, {JSON_KEY_VALID_DATA_GROUP_IDS, extensionInfo.validDataGroupIds}, {JSON_KEY_CUSTOM_PROCESS, extensionInfo.customProcess}, - {JSON_KEY_ISOLATION_PROCESS, extensionInfo.isolationProcess} + {JSON_KEY_ISOLATION_PROCESS, extensionInfo.isolationProcess}, + {Constants::CODE_LANGUAGE, extensionInfo.codeLanguage} }; } @@ -650,6 +653,12 @@ void from_json(const nlohmann::json &jsonObject, ExtensionAbilityInfo &extension extensionInfo.isolationProcess, false, parseResult); + BMSJsonUtil::GetStrValueIfFindKey(jsonObject, + jsonObjectEnd, + Constants::CODE_LANGUAGE, + extensionInfo.codeLanguage, + false, + parseResult); if (parseResult != ERR_OK) { APP_LOGE("ExtensionAbilityInfo from_json error : %{public}d", parseResult); diff --git a/interfaces/inner_api/appexecfwk_base/src/hap_module_info.cpp b/interfaces/inner_api/appexecfwk_base/src/hap_module_info.cpp index c512dc28d5743fb94e1c19741efb01847673345f..6edb7ece37dfbe37babf6060e83ef753dc1e49c4 100644 --- a/interfaces/inner_api/appexecfwk_base/src/hap_module_info.cpp +++ b/interfaces/inner_api/appexecfwk_base/src/hap_module_info.cpp @@ -505,6 +505,7 @@ bool HapModuleInfo::ReadFromParcel(Parcel &parcel) hapPath = Str16ToStr8(parcel.ReadString16()); supportedModes = parcel.ReadInt32(); appStartup = Str16ToStr8(parcel.ReadString16()); + codeLanguage = parcel.ReadString(); int32_t reqCapabilitiesSize; READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, reqCapabilitiesSize); @@ -705,6 +706,7 @@ bool HapModuleInfo::Marshalling(Parcel &parcel) const WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(hapPath)); WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, supportedModes); WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(appStartup)); + WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String, parcel, codeLanguage); WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, parcel, reqCapabilities.size()); for (auto &reqCapability : reqCapabilities) { @@ -863,7 +865,8 @@ void to_json(nlohmann::json &jsonObject, const HapModuleInfo &hapModuleInfo) {HAP_MODULE_ABILITY_SRC_ENTRY_DELEGATOR, hapModuleInfo.abilitySrcEntryDelegator}, {HAP_MODULE_ABILITY_STAGE_SRC_ENTRY_DELEGATOR, hapModuleInfo.abilityStageSrcEntryDelegator}, {HAP_MODULE_INFO_APP_STARTUP, hapModuleInfo.appStartup}, - {HAP_MODULE_INFO_HAS_INTENT, hapModuleInfo.hasIntent} + {HAP_MODULE_INFO_HAS_INTENT, hapModuleInfo.hasIntent}, + {Constants::CODE_LANGUAGE, hapModuleInfo.codeLanguage} }; } @@ -1293,6 +1296,12 @@ void from_json(const nlohmann::json &jsonObject, HapModuleInfo &hapModuleInfo) hapModuleInfo.hasIntent, false, parseResult); + BMSJsonUtil::GetStrValueIfFindKey(jsonObject, + jsonObjectEnd, + Constants::CODE_LANGUAGE, + hapModuleInfo.codeLanguage, + false, + parseResult); if (parseResult != ERR_OK) { APP_LOGW("HapModuleInfo from_json error : %{public}d", parseResult); } diff --git a/interfaces/kits/ani/BUILD.gn b/interfaces/kits/ani/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..3e5eadaa8440ba3589723415f479a36980a96ee8 --- /dev/null +++ b/interfaces/kits/ani/BUILD.gn @@ -0,0 +1,45 @@ +# Copyright (c) 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. + +import("//build/ohos.gni") +import("//foundation/bundlemanager/bundle_framework/appexecfwk.gni") + +group("ani_common") { + deps = [ "common:bms_ani_common" ] +} + +group("ani_bms_packages") { + deps = [ + # "bundle_installer:ani_bundle_installer", + # "bundle_installer:bundle_installer_etc", + "bundle_manager:ability_info_etc", + "bundle_manager:anibundlemanager", + "bundle_manager:application_info_etc", + "bundle_manager:bundle_info_etc", + "bundle_manager:bundle_manager_etc", + "bundle_manager:extension_ability_info_etc", + "bundle_manager:hap_module_info_etc", + "bundle_manager:metadata_etc", + "bundle_manager:skill_etc", + "launcher_bundle_manager:ani_launcher_bundle_manager", + "launcher_bundle_manager:launcher_bundle_manager_etc", + "resource_manager:ani_bundle_res_manager", + "resource_manager:bundle_resource_info_etc", + "resource_manager:bundle_resource_manager_etc", + "shortcut_manager:anishortcutmanager", + "shortcut_manager:shortcut_info_etc", + "shortcut_manager:shortcut_manager_etc", + "zlib:ani_zlib", + "zlib:zlib_etc", + ] +} diff --git a/interfaces/kits/ani/bundle_installer/BUILD.gn b/interfaces/kits/ani/bundle_installer/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..2d84d55b3828cb535287e2a9964bc6855ceb5505 --- /dev/null +++ b/interfaces/kits/ani/bundle_installer/BUILD.gn @@ -0,0 +1,103 @@ +# Copyright (c) 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. + +import("//build/config/components/ets_frontend/ets2abc_config.gni") +import("//build/ohos.gni") +import("//foundation/bundlemanager/bundle_framework/appexecfwk.gni") + +ohos_shared_library("ani_bundle_installer") { + branch_protector_ret = "pac_ret" + + sanitize = { + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + integer_overflow = true + ubsan = true + } + include_dirs = [ + "${kits_path}/ani/common", + "${kits_path}/ani/bundle_installer", + "${kits_path}/js/bundlemgr", + "${kits_path}/js/installer", + ] + + sources = [ + "${kits_path}/js/bundlemgr/bundle_death_recipient.cpp", + "${kits_path}/js/bundlemgr/installer_callback.cpp", + "${kits_path}/js/installer/installer_helper.cpp", + "ani_bundle_installer.cpp", + ] + + defines = [ + "APP_LOG_TAG = \"BMS\"", + "LOG_DOMAIN = 0xD001120", + ] + + cflags = [ + "-Os", + "-fstack-protector-strong", + ] + + cflags_cc = [ + "-Os", + "-fstack-protector-strong", + ] + + deps = [ + "${base_path}:appexecfwk_base", + "${common_path}:libappexecfwk_common", + "${core_path}:appexecfwk_core", + "${kits_path}/ani/common:bms_ani_common", + "${kits_path}/js/bundlemgr:bundle", + "${kits_path}/js/common:bundle_napi_common", + "${kits_path}/js/installer:installer", + ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_single", + "napi:ace_napi", + "runtime_core:ani", + ] + + subsystem_name = "bundlemanager" + part_name = "bundle_framework" +} + +generate_static_abc("bundle_installer") { + base_url = "./ets" + files = [ + "./ets/@ohos.bundle.installer.ets", + "./ets/@ohos.bundle.installerInner.ets", + ] + is_boot_abc = "True" + device_dst_file = "/system/framework/bundle_installer.abc" +} + +ohos_prebuilt_etc("bundle_installer_etc") { + source = "$target_out_dir/bundle_installer.abc" + module_install_dir = "framework" + subsystem_name = "bundlemanager" + part_name = "bundle_framework" + deps = [ ":bundle_installer" ] +} + +ohos_copy("copy_bundle_installer_etc") { + sources = [ "./ets/@ohos.bundle.installerInner.ets" ] + outputs = [ "$ohos_ets_inner_path/bundleManager/{{source_file_part}}" ] + subsystem_name = "bundlemanager" + part_name = "bundle_framework" +} diff --git a/interfaces/kits/ani/bundle_installer/ani_bundle_installer.cpp b/interfaces/kits/ani/bundle_installer/ani_bundle_installer.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5689d5a76a6dd07c6d8d9924a2cb848e8d22f271 --- /dev/null +++ b/interfaces/kits/ani/bundle_installer/ani_bundle_installer.cpp @@ -0,0 +1,337 @@ +/* + * Copyright (c) 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 +#include +#include +#include +#include +#include +#include +#include + +#include "app_log_wrapper.h" +#include "base_cb_info.h" +#include "bundle_death_recipient.h" +#include "bundle_errors.h" +#include "bundle_mgr_client.h" +#include "bundle_mgr_interface.h" +#include "bundle_mgr_proxy.h" +#include "business_error_ani.h" +#include "common_fun_ani.h" +#include "common_func.h" +#include "install_param.h" +#include "installer_callback.h" +#include "installer_helper.h" +#include "ipc_skeleton.h" + +namespace OHOS { +namespace AppExecFwk { +namespace { +constexpr uint8_t INSTALLER_METHOD_COUNTS = 11; +constexpr int32_t SPECIFIED_DISTRIBUTION_TYPE_MAX_SIZE = 128; +constexpr int32_t ADDITIONAL_INFO_MAX_SIZE = 3000; +constexpr const char* RESOURCE_NAME_OF_GET_BUNDLE_INSTALLER_SYNC = "GetBundleInstallerSync"; +constexpr const char* RESOURCE_NAME_OF_INSTALL = "Install"; +constexpr const char* RESOURCE_NAME_OF_UNINSTALL = "Uninstall"; +constexpr const char* RESOURCE_NAME_OF_RECOVER = "Recover"; +constexpr const char* RESOURCE_NAME_OF_UPDATE_BUNDLE_FOR_SELF = "UpdateBundleForSelf"; +constexpr const char* RESOURCE_NAME_OF_UNINSTALL_AND_RECOVER = "UninstallAndRecover"; +constexpr const char* INNERINSTALLER_CLASSNAME = "L@ohos/bundle/installerInner/BundleInstallerInner;"; +constexpr const char* INSTALL_PERMISSION = + "ohos.permission.INSTALL_BUNDLE or " + "ohos.permission.INSTALL_ENTERPRISE_BUNDLE or " + "ohos.permission.INSTALL_ENTERPRISE_MDM_BUNDLE or " + "ohos.permission.INSTALL_ENTERPRISE_NORMAL_BUNDLE or " + "ohos.permission.INSTALL_INTERNALTESTING_BUNDLE"; +constexpr const char* UNINSTALL_PERMISSION = "ohos.permission.INSTALL_BUNDLE or ohos.permission.UNINSTALL_BUNDLE"; +constexpr const char* RECOVER_PERMISSION = "ohos.permission.INSTALL_BUNDLE or ohos.permission.RECOVER_BUNDLE"; +constexpr const char* INSTALL_SELF_PERMISSION = "ohos.permission.INSTALL_SELF_BUNDLE"; +constexpr const char* PARAMETERS = "parameters"; +constexpr const char* CORRESPONDING_TYPE = "corresponding type"; +constexpr const char* HAPS_FILE_NEEDED = + "BusinessError 401: Parameter error. parameter hapFiles is needed for code signature"; +} // namespace +static bool g_isSystemApp = false; + +static bool CheckInstallParam(ani_env* env, InstallParam &installParam) +{ + if (installParam.specifiedDistributionType.size() > SPECIFIED_DISTRIBUTION_TYPE_MAX_SIZE) { + APP_LOGE("Parse specifiedDistributionType size failed"); + BusinessErrorAni::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"); + BusinessErrorAni::ThrowError(env, ERROR_PARAM_CHECK_ERROR, + "BusinessError 401: The size of additionalInfo is greater than 3000"); + return false; + } + return true; +} + +static void ExecuteInstall(const std::vector& hapFiles, InstallParam& installParam, + InstallResult& installResult) +{ + if (hapFiles.empty() && installParam.sharedBundleDirPaths.empty()) { + installResult.resultCode = static_cast(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(IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR); + return; + } + sptr callback = new (std::nothrow) InstallerCallback(); + sptr recipient(new (std::nothrow) BundleDeathRecipient(callback)); + if (callback == nullptr || recipient == nullptr) { + APP_LOGE("callback or death recipient is nullptr"); + installResult.resultCode = static_cast(IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR); + return; + } + iBundleInstaller->AsObject()->AddDeathRecipient(recipient); + ErrCode res = iBundleInstaller->StreamInstall(hapFiles, 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()); + return; + } + APP_LOGE("install failed due to %{public}d", res); + std::unordered_map proxyErrCodeMap; + InstallerHelper::CreateProxyErrCode(proxyErrCodeMap); + if (proxyErrCodeMap.find(res) != proxyErrCodeMap.end()) { + installResult.resultCode = proxyErrCodeMap.at(res); + } else { + installResult.resultCode = IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR; + } +} + +static void ProcessResult(ani_env* env, InstallResult& result, const InstallOption& option) +{ + InstallerHelper::ConvertInstallResult(result); + if (result.resultCode != SUCCESS) { + switch (option) { + case InstallOption::INSTALL: + BusinessErrorAni::ThrowParameterTypeError(env, result.resultCode, + RESOURCE_NAME_OF_INSTALL, INSTALL_PERMISSION); + break; + case InstallOption::RECOVER: + BusinessErrorAni::ThrowParameterTypeError(env, result.resultCode, + RESOURCE_NAME_OF_RECOVER, RECOVER_PERMISSION); + break; + case InstallOption::UNINSTALL: + BusinessErrorAni::ThrowParameterTypeError(env, result.resultCode, + RESOURCE_NAME_OF_UNINSTALL, UNINSTALL_PERMISSION); + break; + case InstallOption::UPDATE_BUNDLE_FOR_SELF: + BusinessErrorAni::ThrowParameterTypeError(env, result.resultCode, + RESOURCE_NAME_OF_UPDATE_BUNDLE_FOR_SELF, INSTALL_SELF_PERMISSION); + break; + case InstallOption::UNINSTALL_AND_RECOVER: + BusinessErrorAni::ThrowParameterTypeError(env, result.resultCode, + RESOURCE_NAME_OF_UNINSTALL_AND_RECOVER, UNINSTALL_PERMISSION); + break; + default: + break; + } + } +} + +static void AniInstall(ani_env* env, [[maybe_unused]] ani_object installerObj, + ani_array arrayObj, ani_object aniInstParam) +{ + APP_LOGI("Install"); + std::vector hapFiles; + if (!CommonFunAni::ParseStrArray(env, arrayObj, hapFiles)) { + APP_LOGE("hapFiles parse invalid"); + BusinessErrorAni::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAMETERS, CORRESPONDING_TYPE); + return; + } + InstallParam installParam; + if (!CommonFunAni::ParseInstallParam(env, aniInstParam, installParam)) { + APP_LOGE("InstallParam parse invalid"); + BusinessErrorAni::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAMETERS, CORRESPONDING_TYPE); + return; + } + if (!CheckInstallParam(env, installParam)) { + return; + } + if (hapFiles.empty() && !installParam.verifyCodeParams.empty()) { + BusinessErrorAni::ThrowError(env, ERROR_PARAM_CHECK_ERROR, HAPS_FILE_NEEDED); + return; + } + InstallResult result; + ExecuteInstall(hapFiles, installParam, result); + ProcessResult(env, result, InstallOption::INSTALL); +} + +static void AniUninstall(ani_env* env, [[maybe_unused]] ani_object installerObj, + ani_string bundleName, ani_object aniInstParam) +{ + APP_LOGI("Uninstall"); +} + +static void AniRecover(ani_env* env, [[maybe_unused]] ani_object installerObj, + ani_string bundleName, ani_object aniInstParam) +{ + APP_LOGI("Recover"); +} + +static void AniUninstallByUninstallParam(ani_env* env, [[maybe_unused]] ani_object installerObj, + ani_object aniUnInstParam) +{ + APP_LOGI("UninstallByUninstallParam"); +} + +static void AniUpdateBundleForSelf(ani_env* env, [[maybe_unused]] ani_object installerObj, + ani_array arrayObj, ani_object aniInstParam) +{ + APP_LOGI("UpdateBundleForSelf"); +} + +static void AniUninstallUpdates(ani_env* env, [[maybe_unused]] ani_object installerObj, + ani_string bundleName, ani_object aniInstParam) +{ + APP_LOGI("UninstallUpdates"); +} + +static void AniAddExtResource(ani_env* env, [[maybe_unused]] ani_object installerObj, + ani_string bundleName, ani_object filePaths) +{ + APP_LOGI("AddExtResource"); +} + +static void AniRemoveExtResource(ani_env* env, [[maybe_unused]] ani_object installerObj, + ani_string bundleName, ani_object moduleNames) +{ + APP_LOGI("RemoveExtResource"); +} + +static ani_double AniCreateAppClone(ani_env* env, [[maybe_unused]] ani_object installerObj, + ani_string bundleName, ani_object aniCrtAppCloneParam) +{ + APP_LOGI("CreateAppClone"); + return (ani_double)0; +} + +static void AniDestroyAppClone(ani_env* env, [[maybe_unused]] ani_object installerObj, + ani_string bundleName, ani_double appIndex, ani_double userId) +{ + APP_LOGI("DestroyAppClone"); +} + +static void AniInstallPreexistingApp(ani_env* env, [[maybe_unused]] ani_object installerObj, + ani_string bundleName, ani_double userId) +{ + APP_LOGI("InstallPreexistingApp"); +} + +static ani_object AniGetBundleInstallerSync(ani_env* env) +{ + APP_LOGI("GetBundleInstallerSync"); + 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"); + BusinessErrorAni::ThrowParameterTypeError(env, ERROR_NOT_SYSTEM_APP, + RESOURCE_NAME_OF_GET_BUNDLE_INSTALLER_SYNC, INSTALL_PERMISSION); + return nullptr; + } + g_isSystemApp = true; + ani_class installerClz = CommonFunAni::CreateClassByName(env, INNERINSTALLER_CLASSNAME); + RETURN_NULL_IF_NULL(installerClz); + return CommonFunAni::CreateNewObjectByClass(env, installerClz); +} + +static void GetInstallerMethods(std::array &installerMethods) +{ + installerMethods = { + ani_native_function { "installNative", + "Lescompat/Array;L@ohos/bundle/installer/installer/InstallParam;:V", + reinterpret_cast(AniInstall) }, + ani_native_function { "uninstallNative", + "Lstd/core/String;L@ohos/bundle/installer/installer/InstallParam;:V", + reinterpret_cast(AniUninstall) }, + ani_native_function { "recoverNative", + "Lstd/core/String;L@ohos/bundle/installer/installer/InstallParam;:V", + reinterpret_cast(AniRecover) }, + ani_native_function { "uninstallByOwnParam", + "L@ohos/bundle/installer/installer/UninstallParam;:V", + reinterpret_cast(AniUninstallByUninstallParam) }, + ani_native_function { "updateBundleForSelfNative", + "Lescompat/Array;L@ohos/bundle/installer/installer/InstallParam;:V", + reinterpret_cast(AniUpdateBundleForSelf) }, + ani_native_function { "uninstallUpdatesNative", + "Lstd/core/String;L@ohos/bundle/installer/installer/InstallParam;:V", + reinterpret_cast(AniUninstallUpdates) }, + ani_native_function { "addExtResourceNative", + "Lstd/core/String;Lescompat/Array;:V", + reinterpret_cast(AniAddExtResource) }, + ani_native_function { "removeExtResourceNative", + "Lstd/core/String;Lescompat/Array;:V", + reinterpret_cast(AniRemoveExtResource) }, + ani_native_function { "createAppCloneNative", + "Lstd/core/String;L@ohos/bundle/installer/installer/CreateAppCloneParam;:D", + reinterpret_cast(AniCreateAppClone) }, + ani_native_function { "destroyAppCloneNative", + "Lstd/core/String;DD:V", + reinterpret_cast(AniDestroyAppClone) }, + ani_native_function { "installPreexistingAppNative", + "Lstd/core/String;D:V", + reinterpret_cast(AniInstallPreexistingApp) }, + }; +} + +extern "C" { +ANI_EXPORT ani_status ANI_Constructor(ani_vm* vm, uint32_t* result) +{ + APP_LOGI("bundle_installer ANI_Constructor called"); + ani_env* env; + ani_status res = vm->GetEnv(ANI_VERSION_1, &env); + RETURN_ANI_STATUS_IF_NOT_OK(res, "Unsupported ANI_VERSION_1"); + static const char* nsName = "L@ohos/bundle/installer/installer;"; + ani_namespace kitNs; + res = env->FindNamespace(nsName, &kitNs); + RETURN_ANI_STATUS_IF_NOT_OK(res, "Not found nameSpace L@ohos/bundle/installer/installer;"); + std::array methods = { + ani_native_function { "getBundleInstallerSync", ":L@ohos/bundle/installer/installer/BundleInstaller;", + reinterpret_cast(AniGetBundleInstallerSync) }, + }; + res = env->Namespace_BindNativeFunctions(kitNs, methods.data(), methods.size()); + RETURN_ANI_STATUS_IF_NOT_OK(res, "Cannot bind native methods"); + APP_LOGI("BundleInstaller class binding.."); + ani_class installerClz; + res = env->FindClass(INNERINSTALLER_CLASSNAME, &installerClz); + RETURN_ANI_STATUS_IF_NOT_OK(res, "Not found clsName"); + std::array installerMethods; + GetInstallerMethods(installerMethods); + res = env->Class_BindNativeMethods(installerClz, installerMethods.data(), installerMethods.size()); + RETURN_ANI_STATUS_IF_NOT_OK(res, "Cannot bind native methods to clsName"); + *result = ANI_VERSION_1; + APP_LOGI("bundle_installer ANI_Constructor finished"); + return ANI_OK; +} +} + +} // namespace AppExecFwk +} // namespace OHOS + \ No newline at end of file diff --git a/interfaces/kits/ani/bundle_installer/ets/@ohos.bundle.installer.ets b/interfaces/kits/ani/bundle_installer/ets/@ohos.bundle.installer.ets new file mode 100644 index 0000000000000000000000000000000000000000..b9f3107c51fe2f88981b066151d4fa60cd181894 --- /dev/null +++ b/interfaces/kits/ani/bundle_installer/ets/@ohos.bundle.installer.ets @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2022 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. + */ + +/** + * @file + * @kit AbilityKit + */ + +import { AsyncCallback, BusinessError } from '@ohos.base'; + +namespace installer { + loadLibrary("ani_bundle_installer.z"); + + function getBundleInstaller(callback: AsyncCallback): void { + let execFun = (): BundleInstaller => { + return installer.getBundleInstallerSync(); + }; + let p1 = taskpool.execute(execFun); + p1.then((e: NullishType) => { + let installer: BundleInstaller = e as BundleInstaller; + let r: BusinessError = { code: 0, name: "noerror", message: "noerror", data: undefined }; + callback(r, installer); + }, (err: Object): void => { + }); + } + + function getBundleInstaller(): Promise { + let p = new Promise((resolve: (bundleInstaller: BundleInstaller) => void, reject: (error: Object) => void) => { + let execFun = (): BundleInstaller => { + return installer.getBundleInstallerSync(); + }; + let p1 = taskpool.execute(execFun); + p1.then((e: NullishType) => { + let installer: BundleInstaller = e as BundleInstaller; + resolve(installer); + }, (err: Object): void => { + let br = err as BusinessError; + reject(br); + }); + }); + return p; + } + + export native function getBundleInstallerSync(): BundleInstaller; + + interface BundleInstaller { + + install(hapFilePaths: Array, installParam: InstallParam, callback: AsyncCallback): void; + + install(hapFilePaths: Array, callback: AsyncCallback): void; + + install(hapFilePaths: Array, installParam?: InstallParam): Promise; + + uninstall(bundleName: string, installParam: InstallParam, callback: AsyncCallback): void; + + uninstall(bundleName: string, callback: AsyncCallback): void; + + uninstall(bundleName: string, installParam?: InstallParam): Promise; + + recover(bundleName: string, installParam: InstallParam, callback: AsyncCallback): void; + + recover(bundleName: string, callback: AsyncCallback): void; + + recover(bundleName: string, installParam?: InstallParam): Promise; + + uninstall(uninstallParam: UninstallParam, callback: AsyncCallback): void; + + uninstall(uninstallParam: UninstallParam): Promise; + + updateBundleForSelf(hapFilePaths: Array, installParam: InstallParam, callback: AsyncCallback): void; + + updateBundleForSelf(hapFilePaths: Array, callback: AsyncCallback): void; + + updateBundleForSelf(hapFilePaths: Array, installParam?: InstallParam): Promise; + + uninstallUpdates(bundleName: string, installParam?: InstallParam): Promise; + + addExtResource(bundleName: string, filePaths: Array): Promise; + + removeExtResource(bundleName: string, moduleNames: Array): Promise; + + createAppClone(bundleName: string, createAppCloneParam?: CreateAppCloneParam): Promise; + + destroyAppClone(bundleName: string, appIndex: number, userId?: number): Promise; + + installPreexistingApp(bundleName: string, userId?: number): Promise; + } + + export interface HashParam { + moduleName: string; + hashValue: string; + } + + export interface VerifyCodeParam { + moduleName: string; + signatureFilePath: string; + } + + export interface PGOParam { + moduleName: string; + pgoFilePath: string; + } + + export interface InstallParam { + userId?: number; + installFlag?: number; + isKeepData?: boolean; + hashParams?: Array; + crowdtestDeadline?: number; + sharedBundleDirPaths?: Array; + specifiedDistributionType?: string; + additionalInfo?: string; + verifyCodeParams?: Array; + pgoParams?: Array; + } + + export interface UninstallParam { + bundleName: string; + versionCode?: number; + } + + export interface CreateAppCloneParam { + userId?: number; + appIndex?: number; + } +} + +export default installer; diff --git a/interfaces/kits/ani/bundle_installer/ets/@ohos.bundle.installerInner.ets b/interfaces/kits/ani/bundle_installer/ets/@ohos.bundle.installerInner.ets new file mode 100644 index 0000000000000000000000000000000000000000..aacf298e467590d110877f74a3522b761a70b427 --- /dev/null +++ b/interfaces/kits/ani/bundle_installer/ets/@ohos.bundle.installerInner.ets @@ -0,0 +1,358 @@ +/* + * Copyright (c) 2022 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. + */ + +/** + * @file + * @kit AbilityKit + */ + +import { AsyncCallback, BusinessError } from '@ohos.base'; +import installer from '@ohos.bundle.installer'; + +export class HashParamInner implements installer.HashParam { + moduleName: string = ""; + hashValue: string = ""; +} + +export class VerifyCodeParamInner implements installer.VerifyCodeParam { + moduleName: string = ""; + signatureFilePath: string = ""; +} + +export class PGOParamInner implements installer.PGOParam { + moduleName: string = ""; + pgoFilePath: string = ""; +} + +export class InstallParamInner implements installer.InstallParam { + userId?: number; + installFlag?: number; + isKeepData?: boolean; + hashParams?: Array; + crowdtestDeadline?: number; + sharedBundleDirPaths?: Array; + specifiedDistributionType?: string; + additionalInfo?: string; + verifyCodeParams?: Array; + pgoParams?: Array; +} + +export class UninstallParamInner implements installer.UninstallParam { + bundleName: string = ""; + versionCode?: number; +} + +export class CreateAppCloneParamInner implements installer.CreateAppCloneParam { + userId?: number; + appIndex?: number; +} + +export class BundleInstallerInner implements installer.BundleInstaller { + native installNative(hapFilePaths: Array, installParam: installer.InstallParam): void; + native uninstallNative(bundleName: string, installParam: installer.InstallParam): void; + native recoverNative(bundleName: string, installParam: installer.InstallParam): void; + native uninstallByOwnParam(uninstallParam: installer.UninstallParam): void; + native updateBundleForSelfNative(hapFilePaths: Array, installParam: installer.InstallParam): void; + native uninstallUpdatesNative(bundleName: string, installParam: installer.InstallParam): void; + native addExtResourceNative(bundleName: string, filePaths: Array): void; + native removeExtResourceNative(bundleName: string, moduleNames: Array): void; + native createAppCloneNative(bundleName: string, createAppCloneParam: installer.CreateAppCloneParam): number; + native destroyAppCloneNative(bundleName: string, appIndex: number, userId: number): void; + native installPreexistingAppNative(bundleName: string, userId: number): void; + + install(hapFilePaths: Array, installParam?: installer.InstallParam): Promise { + let emptyParam = new InstallParamInner(); + let params = installParam ?? emptyParam; + let p = new Promise((resolve: (v:undefined) => void, reject: (error: BusinessError) => void):void => { + let execFun = ():NullishType=>{ this.installNative(hapFilePaths, params); } + let p1 = taskpool.execute(execFun); + p1.then(():void => { + resolve(undefined); + }, (err: BusinessError): void => { + reject(err); + }); + }); + return p; + } + + install(hapFilePaths: Array, installParam: installer.InstallParam, callback: AsyncCallback): void { + let p = new Promise((resolve: (v:undefined) => void, reject: (error: BusinessError) => void):void => { + let execFun = ():NullishType=>{ this.installNative(hapFilePaths, installParam); } + + let p1 = taskpool.execute(execFun); + p1.then(() => { + let r = new BusinessError(); + callback(r, undefined); + }, (err: BusinessError): void => { + callback(err, undefined); + }); + }); + } + + install(hapFilePaths: Array, callback: AsyncCallback): void { + let emptyParam = new InstallParamInner(); + let p = new Promise((resolve: (v:undefined) => void, reject: (error: BusinessError) => void):void => { + let execFun = ():NullishType=>{ this.installNative(hapFilePaths, emptyParam); } + + let p1 = taskpool.execute(execFun); + p1.then(() => { + let r = new BusinessError(); + callback(r, undefined); + }, (err: BusinessError): void => { + callback(err, undefined); + }); + }); + } + + uninstall(bundleName: string, installParam?: installer.InstallParam): Promise { + let emptyParam = new InstallParamInner(); + let params = installParam ?? emptyParam; + let p = new Promise((resolve: (v:undefined) => void, reject: (error: BusinessError) => void):void => { + let execFun = ():NullishType=>{ this.uninstallNative(bundleName, params); } + let p1 = taskpool.execute(execFun); + p1.then(():void => { + resolve(undefined); + }, (err: BusinessError): void => { + reject(err); + }); + }); + return p; + } + + uninstall(bundleName: string, installParam: installer.InstallParam, callback: AsyncCallback): void { + let p = new Promise((resolve: (v:undefined) => void, reject: (error: BusinessError) => void):void => { + let execFun = ():NullishType=>{ this.uninstallNative(bundleName, installParam); } + + let p1 = taskpool.execute(execFun); + p1.then(() => { + let r = new BusinessError(); + callback(r, undefined); + }, (err: BusinessError): void => { + callback(err, undefined); + }); + }); + } + + uninstall(bundleName: string, callback: AsyncCallback): void { + let emptyParam = new InstallParamInner(); + let p = new Promise((resolve: (v:undefined) => void, reject: (error: BusinessError) => void):void => { + let execFun = ():NullishType=>{ this.uninstallNative(bundleName, emptyParam); } + + let p1 = taskpool.execute(execFun); + p1.then(() => { + let r = new BusinessError(); + callback(r, undefined); + }, (err: BusinessError): void => { + callback(err, undefined); + }); + }); + } + + recover(bundleName: string, installParam?: installer.InstallParam): Promise { + let emptyParam = new InstallParamInner(); + let params = installParam ?? emptyParam; + let p = new Promise((resolve: (v:undefined) => void, reject: (error: BusinessError) => void):void => { + let execFun = ():NullishType=>{ this.recoverNative(bundleName, params); } + let p1 = taskpool.execute(execFun); + p1.then(():void => { + resolve(undefined); + }, (err: BusinessError): void => { + reject(err); + }); + }); + return p; + } + + recover(bundleName: string, installParam: installer.InstallParam, callback: AsyncCallback): void { + let p = new Promise((resolve: (v:undefined) => void, reject: (error: BusinessError) => void):void => { + let execFun = ():NullishType=>{ this.recoverNative(bundleName, installParam); } + + let p1 = taskpool.execute(execFun); + p1.then(() => { + let r = new BusinessError(); + callback(r, undefined); + }, (err: BusinessError): void => { + callback(err, undefined); + }); + }); + } + + recover(bundleName: string, callback: AsyncCallback): void { + let emptyParam = new InstallParamInner(); + let p = new Promise((resolve: (v:undefined) => void, reject: (error: BusinessError) => void):void => { + let execFun = ():NullishType=>{ this.recoverNative(bundleName, emptyParam); } + let p1 = taskpool.execute(execFun); + p1.then(() => { + let r = new BusinessError(); + callback(r, undefined); + }, (err: BusinessError): void => { + callback(err, undefined); + }); + }); + } + + uninstall(uninstallParam: installer.UninstallParam): Promise { + let p = new Promise((resolve: (v:undefined) => void, reject: (error: BusinessError) => void):void => { + let execFun = ():NullishType=>{ this.uninstallByOwnParam(uninstallParam); } + let p1 = taskpool.execute(execFun); + p1.then(():void => { + resolve(undefined); + }, (err: BusinessError): void => { + reject(err); + }); + }); + return p; + } + + uninstall(uninstallParam: installer.UninstallParam, callback: AsyncCallback): void { + let p = new Promise((resolve: (v:undefined) => void, reject: (error: BusinessError) => void):void => { + let execFun = ():NullishType=>{ this.uninstallByOwnParam(uninstallParam); } + let p1 = taskpool.execute(execFun); + p1.then(() => { + let r = new BusinessError(); + callback(r, undefined); + }, (err: BusinessError): void => { + callback(err, undefined); + }); + }); + } + + updateBundleForSelf(hapFilePaths: Array, installParam?: installer.InstallParam): Promise { + let emptyParam = new InstallParamInner(); + let params = installParam ?? emptyParam; + let p = new Promise((resolve: (v:undefined) => void, reject: (error: BusinessError) => void):void => { + let execFun = ():NullishType=>{ this.updateBundleForSelfNative(hapFilePaths, params); } + let p1 = taskpool.execute(execFun); + p1.then(():void => { + resolve(undefined); + }, (err: BusinessError): void => { + reject(err); + }); + }); + return p; + } + + updateBundleForSelf(hapFilePaths: Array, installParam: installer.InstallParam, callback: AsyncCallback): void { + let p = new Promise((resolve: (v:undefined) => void, reject: (error: BusinessError) => void):void => { + let execFun = ():NullishType=>{ this.updateBundleForSelfNative(hapFilePaths, installParam); } + let p1 = taskpool.execute(execFun); + p1.then(() => { + let r = new BusinessError(); + callback(r, undefined); + }, (err: BusinessError): void => { + callback(err, undefined); + }); + }); + } + + updateBundleForSelf(hapFilePaths: Array, callback: AsyncCallback): void { + let emptyParam = new InstallParamInner(); + let p = new Promise((resolve: (v:undefined) => void, reject: (error: BusinessError) => void):void => { + let execFun = ():NullishType=>{ this.updateBundleForSelfNative(hapFilePaths, emptyParam); } + + let p1 = taskpool.execute(execFun); + p1.then(() => { + let r = new BusinessError(); + callback(r, undefined); + }, (err: BusinessError): void => { + callback(err, undefined); + }); + }); + } + + uninstallUpdates(bundleName: string, installParam?: installer.InstallParam): Promise { + let emptyParam = new InstallParamInner(); + let params = installParam ?? emptyParam; + let p = new Promise((resolve: (v:undefined) => void, reject: (error: BusinessError) => void):void => { + let execFun = ():NullishType=>{ this.uninstallUpdatesNative(bundleName, params); } + let p1 = taskpool.execute(execFun); + p1.then(():void => { + resolve(undefined); + }, (err: BusinessError): void => { + reject(err); + }); + }); + return p; + } + + addExtResource(bundleName: string, filePaths: Array): Promise { + let p = new Promise((resolve: (v:undefined) => void, reject: (error: BusinessError) => void):void => { + let execFun = ():NullishType=>{ this.addExtResourceNative(bundleName, filePaths); } + let p1 = taskpool.execute(execFun); + p1.then(():void => { + resolve(undefined); + }, (err: BusinessError): void => { + reject(err); + }); + }); + return p; + } + + removeExtResource(bundleName: string, moduleNames: Array): Promise { + let p = new Promise((resolve: (v:undefined) => void, reject: (error: BusinessError) => void):void => { + let execFun = ():NullishType=>{ this.removeExtResourceNative(bundleName, moduleNames); } + let p1 = taskpool.execute(execFun); + p1.then(():void => { + resolve(undefined); + }, (err: BusinessError): void => { + reject(err); + }); + }); + return p; + } + + createAppClone(bundleName: string, createAppCloneParam?: installer.CreateAppCloneParam): Promise { + let emptyParam = new CreateAppCloneParamInner(); + let params = createAppCloneParam ?? emptyParam; + let p = new Promise((resolve: (v:number) => void, reject: (error: BusinessError) => void):void => { + let execFun = ():number=>{ return this.createAppCloneNative(bundleName, emptyParam); } + let p1 = taskpool.execute(execFun); + p1.then((e: NullishType) => { + resolve(e as number); + }, (err: BusinessError): void => { + reject(err); + }); + }); + return p; + } + + destroyAppClone(bundleName: string, appIndex: number, userId?: number): Promise { + let userIdNum = userId ?? -500; + let p = new Promise((resolve: (v:undefined) => void, reject: (error: BusinessError) => void):void => { + let execFun = ():NullishType=>{ this.destroyAppCloneNative(bundleName, appIndex, userIdNum); } + let p1 = taskpool.execute(execFun); + p1.then(():void => { + resolve(undefined); + }, (err: BusinessError): void => { + reject(err); + }); + }); + return p; + } + + installPreexistingApp(bundleName: string, userId?: number): Promise { + let userIdNum = userId ?? -500; + let p = new Promise((resolve: (v:undefined) => void, reject: (error: BusinessError) => void):void => { + let execFun = ():NullishType=>{ this.installPreexistingAppNative(bundleName, userIdNum); } + let p1 = taskpool.execute(execFun); + p1.then(():void => { + resolve(undefined); + }, (err: BusinessError): void => { + reject(err); + }); + }); + return p; + } +} \ No newline at end of file diff --git a/interfaces/kits/ani/bundle_manager/BUILD.gn b/interfaces/kits/ani/bundle_manager/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..e9d52c93e745c848b46b2c5dee91a71f285eea5d --- /dev/null +++ b/interfaces/kits/ani/bundle_manager/BUILD.gn @@ -0,0 +1,228 @@ +# Copyright (c) 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. + +import("//build/config/components/ets_frontend/ets2abc_config.gni") +import("//build/ohos.gni") +import("//foundation/bundlemanager/bundle_framework/appexecfwk.gni") + +ohos_shared_library("anibundlemanager") { + branch_protector_ret = "pac_ret" + + sanitize = { + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + integer_overflow = true + ubsan = true + } + include_dirs = [ + "${inner_api_path}/appexecfwk_core/include", + "${kits_path}/ani/bundle_manager", + "${kits_path}/ani/common", + "${kits_path}/js/common", + ] + sources = [ "ani_bundle_manager.cpp" ] + + defines = [ + "APP_LOG_TAG = \"BMS\"", + "LOG_DOMAIN = 0xD001120", + ] + + deps = [ + "${base_path}:appexecfwk_base", + "${common_path}:libappexecfwk_common", + "${core_path}:appexecfwk_core", + "${kits_path}/ani/common:bms_ani_common", + "${kits_path}/js/common:bundle_napi_common", + ] + + cflags = [ + "-Os", + "-fstack-protector-strong", + ] + + cflags_cc = [ + "-Os", + "-fstack-protector-strong", + ] + + external_deps = [ + "ability_base:want", + "c_utils:utils", + "common_event_service:cesfwk_core", + "common_event_service:cesfwk_innerkits", + "hilog:libhilog", + "ipc:ipc_core", + "napi:ace_napi", + "runtime_core:ani", + "runtime_core:ani_helpers", + "samgr:samgr_proxy", + ] + + subsystem_name = "bundlemanager" + part_name = "bundle_framework" +} + +generate_static_abc("bundle_manager") { + base_url = "./ets" + files = [ "./ets/@ohos.bundle.bundleManager.ets" ] + is_boot_abc = "True" + device_dst_file = "/system/framework/bundle_manager.abc" +} + +ohos_prebuilt_etc("bundle_manager_etc") { + source = "$target_out_dir/bundle_manager.abc" + module_install_dir = "framework" + subsystem_name = "bundlemanager" + part_name = "bundle_framework" + deps = [ ":bundle_manager" ] +} + +generate_static_abc("bundle_info") { + base_url = "./ets" + files = [ + "./ets/bundleManager/BundleInfo.ets", + "./ets/bundleManager/BundleInfoInner.ets", + ] + is_boot_abc = "True" + device_dst_file = "/system/framework/bundle_info.abc" +} + +ohos_prebuilt_etc("bundle_info_etc") { + source = "$target_out_dir/bundle_info.abc" + module_install_dir = "framework" + subsystem_name = "bundlemanager" + part_name = "bundle_framework" + deps = [ ":bundle_info" ] +} + +generate_static_abc("application_info") { + base_url = "./ets" + files = [ + "./ets/bundleManager/ApplicationInfo.ets", + "./ets/bundleManager/ApplicationInfoInner.ets", + ] + is_boot_abc = "True" + device_dst_file = "/system/framework/application_info.abc" + external_dependencies = [ "resource_management:copy_resourceManager_ets" ] +} + +ohos_prebuilt_etc("application_info_etc") { + source = "$target_out_dir/application_info.abc" + module_install_dir = "framework" + subsystem_name = "bundlemanager" + part_name = "bundle_framework" + deps = [ ":application_info" ] +} + +generate_static_abc("ability_info") { + base_url = "./ets" + files = [ + "./ets/bundleManager/AbilityInfo.ets", + "./ets/bundleManager/AbilityInfoInner.ets", + ] + is_boot_abc = "True" + device_dst_file = "/system/framework/ability_info.abc" +} + +ohos_prebuilt_etc("ability_info_etc") { + source = "$target_out_dir/ability_info.abc" + module_install_dir = "framework" + subsystem_name = "bundlemanager" + part_name = "bundle_framework" + deps = [ ":ability_info" ] +} + +generate_static_abc("extension_ability_info") { + base_url = "./ets" + files = [ + "./ets/bundleManager/ExtensionAbilityInfo.ets", + "./ets/bundleManager/ExtensionAbilityInfoInner.ets", + ] + is_boot_abc = "True" + device_dst_file = "/system/framework/extension_ability_info.abc" +} + +ohos_prebuilt_etc("extension_ability_info_etc") { + source = "$target_out_dir/extension_ability_info.abc" + module_install_dir = "framework" + subsystem_name = "bundlemanager" + part_name = "bundle_framework" + deps = [ ":extension_ability_info" ] +} + +generate_static_abc("hap_module_info") { + base_url = "./ets" + files = [ + "./ets/bundleManager/HapModuleInfo.ets", + "./ets/bundleManager/HapModuleInfoInner.ets", + ] + is_boot_abc = "True" + device_dst_file = "/system/framework/hap_module_info.abc" +} + +ohos_prebuilt_etc("hap_module_info_etc") { + source = "$target_out_dir/hap_module_info.abc" + module_install_dir = "framework" + subsystem_name = "bundlemanager" + part_name = "bundle_framework" + deps = [ ":hap_module_info" ] +} + +generate_static_abc("metadata") { + base_url = "./ets" + files = [ + "./ets/bundleManager/Metadata.ets", + "./ets/bundleManager/MetadataInner.ets", + ] + is_boot_abc = "True" + device_dst_file = "/system/framework/metadata.abc" +} + +ohos_prebuilt_etc("metadata_etc") { + source = "$target_out_dir/metadata.abc" + module_install_dir = "framework" + subsystem_name = "bundlemanager" + part_name = "bundle_framework" + deps = [ ":metadata" ] +} + +generate_static_abc("skill") { + base_url = "./ets" + files = [ + "./ets/bundleManager/Skill.ets", + "./ets/bundleManager/SkillInner.ets", + ] + is_boot_abc = "True" + device_dst_file = "/system/framework/skill.abc" +} + +ohos_prebuilt_etc("skill_etc") { + source = "$target_out_dir/skill.abc" + module_install_dir = "framework" + subsystem_name = "bundlemanager" + part_name = "bundle_framework" + deps = [ ":skill" ] +} + +ohos_copy("copy_bundleManager_ets") { + sources = [ + "./ets/bundleManager/AbilityInfoInner.ets", + "./ets/bundleManager/ApplicationInfoInner.ets", + "./ets/bundleManager/ExtensionAbilityInfoInner.ets", + ] + outputs = [ "$ohos_ets_inner_path/bundleManager/{{source_file_part}}" ] + subsystem_name = "bundlemanager" + part_name = "bundle_framework" +} diff --git a/interfaces/kits/ani/bundle_manager/ani_bundle_manager.cpp b/interfaces/kits/ani/bundle_manager/ani_bundle_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a6d5c178afa698d9f044524625ece1214e9b60fb --- /dev/null +++ b/interfaces/kits/ani/bundle_manager/ani_bundle_manager.cpp @@ -0,0 +1,348 @@ +/* + * Copyright (c) 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "ani_bundle_manager.h" +#include +#include "app_log_wrapper.h" +#include "bundle_errors.h" +#include "bundle_mgr_client.h" +#include "bundle_mgr_interface.h" +#include "bundle_mgr_proxy.h" +#include "business_error_ani.h" +#include "common_fun_ani.h" +#include "common_func.h" +#include "ipc_skeleton.h" + +namespace OHOS { +namespace AppExecFwk { +namespace { +constexpr const char* BUNDLE_FLAGS = "bundleFlags"; +constexpr const char* APPLICATION_FLAGS = "applicationFlags"; +constexpr const char* ERR_MSG_BUNDLE_SERVICE_EXCEPTION = "Bundle manager service is excepted."; +const std::string IS_APPLICATION_ENABLED_SYNC = "IsApplicationEnabledSync"; +const std::string GET_BUNDLE_INFO_FOR_SELF_SYNC = "GetBundleInfoForSelfSync"; +const std::string GET_BUNDLE_INFO_SYNC = "GetBundleInfoSync"; +const std::string GET_APPLICATION_INFO_SYNC = "GetApplicationInfoSync"; +const std::string BUNDLE_PERMISSIONS = "ohos.permission.GET_BUNDLE_INFO or ohos.permission.GET_BUNDLE_INFO_PRIVILEGED"; +const std::string GET_BUNDLE_INFO = "GetBundleInfo"; +constexpr const char* GET_APPLICATION_INFO = "GetApplicationInfo"; +static ani_vm* g_vm; +static std::mutex g_aniClearCacheListenerMutex; +static std::shared_ptr g_aniClearCacheListener; +static std::shared_mutex g_aniCacheMutex; +static std::unordered_map g_aniCache; +constexpr int32_t EMPTY_USER_ID = -500; +} // namespace + +static void CheckToCache( + ani_env* env, const int32_t uid, const int32_t callingUid, const ANIQuery& query, ani_object aniObject) +{ + RETURN_IF_NULL(aniObject); + if (uid != callingUid) { + return; + } + + ani_ref info = nullptr; + ani_status status = env->GlobalReference_Create(aniObject, &info); + if (status == ANI_OK) { + std::unique_lock lock(g_aniCacheMutex); + g_aniCache[query] = info; + } +} + +static ani_boolean isApplicationEnabledSync(ani_env* env, ani_string aniBundleName) +{ + bool isEnable = false; + std::string bundleName = CommonFunAni::AniStrToString(env, aniBundleName); + if (bundleName.empty()) { + APP_LOGE("BundleName is empty"); + BusinessErrorAni::ThrowParameterTypeError( + env, ERROR_PARAM_CHECK_ERROR, Constants::BUNDLE_NAME, CommonFunAniNS::TYPE_STRING); + return isEnable; + } + auto iBundleMgr = CommonFunc::GetBundleMgr(); + if (iBundleMgr == nullptr) { + APP_LOGE("GetBundleMgr failed"); + BusinessErrorAni::ThrowError(env, ERROR_BUNDLE_SERVICE_EXCEPTION, ERR_MSG_BUNDLE_SERVICE_EXCEPTION); + return isEnable; + } + ErrCode ret = iBundleMgr->IsApplicationEnabled(bundleName, isEnable); + if (ret != ERR_OK) { + APP_LOGE("IsApplicationEnabled failed ret: %{public}d", ret); + BusinessErrorAni::ThrowParameterTypeError( + env, CommonFunc::ConvertErrCode(ret), IS_APPLICATION_ENABLED_SYNC, ""); + } + return isEnable; +} + +static ani_object getBundleInfoForSelfSync(ani_env* env, ani_double bundleFlags) +{ + int32_t bundleFlagsInt = 0; + if (!CommonFunAni::TryCastDoubleTo(bundleFlags, &bundleFlagsInt)) { + APP_LOGE("Cast bundleFlags failed"); + BusinessErrorAni::ThrowParameterTypeError( + env, ERROR_PARAM_CHECK_ERROR, BUNDLE_FLAGS, CommonFunAniNS::TYPE_INT); + return nullptr; + } + auto iBundleMgr = CommonFunc::GetBundleMgr(); + if (iBundleMgr == nullptr) { + APP_LOGE("GetBundleMgr failed"); + BusinessErrorAni::ThrowError(env, ERROR_BUNDLE_SERVICE_EXCEPTION, ERR_MSG_BUNDLE_SERVICE_EXCEPTION); + return nullptr; + } + const auto uid = IPCSkeleton::GetCallingUid(); + std::string bundleName = std::to_string(uid); + int32_t userId = uid / Constants::BASE_USER_RANGE; + const ANIQuery query(bundleName, GET_BUNDLE_INFO, bundleFlagsInt, userId); + if (!CommonFunc::CheckBundleFlagWithPermission(bundleFlagsInt)) { + std::shared_lock lock(g_aniCacheMutex); + auto item = g_aniCache.find(query); + if (item != g_aniCache.end()) { + return reinterpret_cast(item->second); + } + } + + BundleInfo bundleInfo; + ErrCode ret = iBundleMgr->GetBundleInfoForSelf(bundleFlagsInt, bundleInfo); + if (ret != ERR_OK) { + APP_LOGE("GetBundleInfoForSelf failed ret: %{public}d", ret); + BusinessErrorAni::ThrowParameterTypeError( + env, CommonFunc::ConvertErrCode(ret), GET_BUNDLE_INFO_FOR_SELF_SYNC, BUNDLE_PERMISSIONS); + return nullptr; + } + + ani_object objectBundleInfo = CommonFunAni::ConvertBundleInfo(env, bundleInfo, bundleFlagsInt); + if (!CommonFunc::CheckBundleFlagWithPermission(bundleFlagsInt)) { + CheckToCache(env, bundleInfo.uid, uid, query, objectBundleInfo); + } + + return objectBundleInfo; +} + +static ani_object getBundleInfoSync(ani_env* env, + ani_string aniBundleName, ani_double bundleFlags, ani_double userId) +{ + int32_t bundleFlagsInt = 0; + if (!CommonFunAni::TryCastDoubleTo(bundleFlags, &bundleFlagsInt)) { + APP_LOGE("Cast bundleFlags failed"); + BusinessErrorAni::ThrowParameterTypeError( + env, ERROR_PARAM_CHECK_ERROR, BUNDLE_FLAGS, CommonFunAniNS::TYPE_INT); + return nullptr; + } + int32_t userIdInt = 0; + if (!CommonFunAni::TryCastDoubleTo(userId, &userIdInt)) { + APP_LOGE("Cast userId failed"); + BusinessErrorAni::ThrowParameterTypeError( + env, ERROR_PARAM_CHECK_ERROR, Constants::USER_ID, CommonFunAniNS::TYPE_INT); + return nullptr; + } + int32_t callingUid = IPCSkeleton::GetCallingUid(); + if (userIdInt == EMPTY_USER_ID) { + userIdInt = callingUid / Constants::BASE_USER_RANGE; + } + std::string bundleName = CommonFunAni::AniStrToString(env, aniBundleName); + if (bundleName.empty()) { + APP_LOGE("Bundle name is empty."); + BusinessErrorAni::ThrowParameterTypeError( + env, ERROR_PARAM_CHECK_ERROR, Constants::BUNDLE_NAME, CommonFunAniNS::TYPE_STRING); + return nullptr; + } + + ANIQuery query(bundleName, GET_BUNDLE_INFO, bundleFlagsInt, userIdInt); + if (!CommonFunc::CheckBundleFlagWithPermission(bundleFlagsInt)) { + std::shared_lock lock(g_aniCacheMutex); + auto item = g_aniCache.find(query); + if (item != g_aniCache.end()) { + APP_LOGD("Get bundle info from global cache."); + return reinterpret_cast(item->second); + } + } + + auto iBundleMgr = CommonFunc::GetBundleMgr(); + if (iBundleMgr == nullptr) { + APP_LOGE("Get bundle mgr failed"); + BusinessErrorAni::ThrowError(env, ERROR_BUNDLE_SERVICE_EXCEPTION, ERR_MSG_BUNDLE_SERVICE_EXCEPTION); + return nullptr; + } + BundleInfo bundleInfo; + ErrCode ret = iBundleMgr->GetBundleInfoV9(bundleName, bundleFlagsInt, bundleInfo, userIdInt); + if (ret != ERR_OK) { + APP_LOGE("GetBundleInfoV9 failed ret: %{public}d", ret); + BusinessErrorAni::ThrowParameterTypeError( + env, CommonFunc::ConvertErrCode(ret), GET_BUNDLE_INFO_SYNC, BUNDLE_PERMISSIONS); + return nullptr; + } + + ani_object objectBundleInfo = CommonFunAni::ConvertBundleInfo(env, bundleInfo, bundleFlagsInt); + if (!CommonFunc::CheckBundleFlagWithPermission(bundleFlagsInt)) { + CheckToCache(env, bundleInfo.uid, callingUid, query, objectBundleInfo); + } + + return objectBundleInfo; +} + +static ani_object getApplicationInfoSync(ani_env* env, + ani_string aniBundleName, ani_double applicationFlags, ani_double userId) +{ + int32_t applicationFlagsInt = 0; + if (!CommonFunAni::TryCastDoubleTo(applicationFlags, &applicationFlagsInt)) { + APP_LOGE("Cast applicationFlags failed"); + BusinessErrorAni::ThrowParameterTypeError( + env, ERROR_PARAM_CHECK_ERROR, APPLICATION_FLAGS, CommonFunAniNS::TYPE_INT); + return nullptr; + } + int32_t userIdInt = 0; + if (!CommonFunAni::TryCastDoubleTo(userId, &userIdInt)) { + APP_LOGE("Cast userId failed"); + BusinessErrorAni::ThrowParameterTypeError( + env, ERROR_PARAM_CHECK_ERROR, Constants::USER_ID, CommonFunAniNS::TYPE_INT); + return nullptr; + } + std::string bundleName = CommonFunAni::AniStrToString(env, aniBundleName); + if (bundleName.empty()) { + APP_LOGE("BundleName is empty"); + BusinessErrorAni::ThrowParameterTypeError( + env, ERROR_PARAM_CHECK_ERROR, Constants::BUNDLE_NAME, CommonFunAniNS::TYPE_STRING); + return nullptr; + } + int32_t callingUid = IPCSkeleton::GetCallingUid(); + if (userIdInt == EMPTY_USER_ID) { + userIdInt = callingUid / Constants::BASE_USER_RANGE; + } + + const ANIQuery query(bundleName, GET_APPLICATION_INFO, applicationFlagsInt, userIdInt); + { + std::shared_lock lock(g_aniCacheMutex); + auto item = g_aniCache.find(query); + if (item != g_aniCache.end()) { + return reinterpret_cast(item->second); + } + } + + auto iBundleMgr = CommonFunc::GetBundleMgr(); + if (iBundleMgr == nullptr) { + APP_LOGE("nullptr iBundleMgr"); + BusinessErrorAni::ThrowError(env, ERROR_BUNDLE_SERVICE_EXCEPTION, ERR_MSG_BUNDLE_SERVICE_EXCEPTION); + return nullptr; + } + ApplicationInfo appInfo; + ErrCode ret = iBundleMgr->GetApplicationInfoV9(bundleName, applicationFlagsInt, userIdInt, appInfo); + if (ret != ERR_OK) { + APP_LOGE("GetApplicationInfoV9 failed ret: %{public}d,userIdInt: %{public}d", ret, userIdInt); + BusinessErrorAni::ThrowParameterTypeError( + env, CommonFunc::ConvertErrCode(ret), GET_APPLICATION_INFO_SYNC, BUNDLE_PERMISSIONS); + return nullptr; + } + + ani_object objectApplicationInfo = CommonFunAni::ConvertApplicationInfo(env, appInfo); + CheckToCache(env, appInfo.uid, callingUid, query, objectApplicationInfo); + + return objectApplicationInfo; +} + +extern "C" { +ANI_EXPORT ani_status ANI_Constructor(ani_vm* vm, uint32_t* result) +{ + APP_LOGI("ANI_Constructor called"); + ani_env* env; + ani_status res = vm->GetEnv(ANI_VERSION_1, &env); + RETURN_ANI_STATUS_IF_NOT_OK(res, "Unsupported ANI_VERSION_1"); + + auto nsName = arkts::ani_signature::Builder::BuildNamespace({"@ohos", "bundle", "bundleManager", "bundleManager"}); + ani_namespace kitNs; + res = env->FindNamespace(nsName.Descriptor().c_str(), &kitNs); + RETURN_ANI_STATUS_IF_NOT_OK(res, "Not found nameSpace L@ohos/bundle/bundleManager/bundleManager;"); + + std::array methods = { + ani_native_function { "isApplicationEnabledSync", "Lstd/core/String;:Z", + reinterpret_cast(isApplicationEnabledSync) }, + ani_native_function { "getBundleInfoForSelfSync", "D:LbundleManager/BundleInfo/BundleInfo;", + reinterpret_cast(getBundleInfoForSelfSync) }, + ani_native_function { "getBundleInfoSync", "Lstd/core/String;DD:LbundleManager/BundleInfo/BundleInfo;", + reinterpret_cast(getBundleInfoSync) }, + ani_native_function { "getApplicationInfoSync", + "Lstd/core/String;DD:LbundleManager/ApplicationInfo/ApplicationInfo;", + reinterpret_cast(getApplicationInfoSync) }, + }; + + res = env->Namespace_BindNativeFunctions(kitNs, methods.data(), methods.size()); + RETURN_ANI_STATUS_IF_NOT_OK(res, "Cannot bind native methods"); + + *result = ANI_VERSION_1; + + RegisterANIClearCacheListenerAndEnv(vm); + + APP_LOGI("ANI_Constructor finished"); + + return ANI_OK; +} +} + +void ANIClearCacheListener::DoClearCache() +{ + std::unique_lock lock(g_aniCacheMutex); + ani_env* env = nullptr; + ani_option interopEnabled { "--interop=disable", nullptr }; + ani_options aniArgs { 1, &interopEnabled }; + g_vm->AttachCurrentThread(&aniArgs, ANI_VERSION_1, &env); + for (auto& item : g_aniCache) { + env->GlobalReference_Delete(item.second); + } + g_vm->DetachCurrentThread(); + g_aniCache.clear(); +} + +void ANIClearCacheListener::HandleCleanEnv(void* data) +{ + DoClearCache(); +} + +ANIClearCacheListener::ANIClearCacheListener(const EventFwk::CommonEventSubscribeInfo& subscribeInfo) + : EventFwk::CommonEventSubscriber(subscribeInfo) +{} + +void ANIClearCacheListener::OnReceiveEvent(const EventFwk::CommonEventData& data) +{ + DoClearCache(); +} + +void RegisterANIClearCacheListenerAndEnv(ani_vm* vm) +{ + std::lock_guard lock(g_aniClearCacheListenerMutex); + if (g_aniClearCacheListener != nullptr) { + return; + } + EventFwk::MatchingSkills matchingSkills; + matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_ADDED); + matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_CHANGED); + matchingSkills.AddEvent(EventFwk::CommonEventSupport::COMMON_EVENT_PACKAGE_REMOVED); + EventFwk::CommonEventSubscribeInfo subscribeInfo(matchingSkills); + g_aniClearCacheListener = std::make_shared(subscribeInfo); + (void)EventFwk::CommonEventManager::SubscribeCommonEvent(g_aniClearCacheListener); + g_vm = vm; +} +} // namespace AppExecFwk +} // namespace OHOS diff --git a/interfaces/kits/ani/bundle_manager/ani_bundle_manager.h b/interfaces/kits/ani/bundle_manager/ani_bundle_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..ce3d64dbec8b81bb642470ecfd17bff498451047 --- /dev/null +++ b/interfaces/kits/ani/bundle_manager/ani_bundle_manager.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 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. + */ + +#ifndef BUNDLE_FRAMEWORK_INTERFACES_KITS_ANI_BUNDLE_MANAGER_H +#define BUNDLE_FRAMEWORK_INTERFACES_KITS_ANI_BUNDLE_MANAGER_H + +#include + +#include "ani.h" +#include "bundle_mgr_interface.h" +#include "common_event_manager.h" +#include "common_event_subscriber.h" +#include "common_event_support.h" + +namespace OHOS { +namespace AppExecFwk { +class ANIClearCacheListener final : public OHOS::EventFwk::CommonEventSubscriber { +public: + explicit ANIClearCacheListener(const OHOS::EventFwk::CommonEventSubscribeInfo& subscribeInfo); + virtual ~ANIClearCacheListener() = default; + void OnReceiveEvent(const OHOS::EventFwk::CommonEventData& data) override; + static void HandleCleanEnv(void* data); + +private: + static void DoClearCache(); +}; + +struct ANIQuery { + std::string bundleName_; + std::string interfaceType_; + int32_t flags_ = 0; + int32_t userId_ = OHOS::AppExecFwk::Constants::UNSPECIFIED_USERID; + ANIQuery(const std::string& bundleName, const std::string& interfaceType, int32_t flags, int32_t userId) + : bundleName_(bundleName), interfaceType_(interfaceType), flags_(flags), userId_(userId) + {} + + bool operator==(const ANIQuery& query) const + { + return bundleName_ == query.bundleName_ && interfaceType_ == query.interfaceType_ && flags_ == query.flags_ && + userId_ == query.userId_; + } +}; + +struct ANIQueryHash { + size_t operator()(const ANIQuery& query) const + { + return std::hash()(query.bundleName_) ^ std::hash()(query.interfaceType_) ^ + std::hash()(query.flags_) ^ std::hash()(query.userId_); + } +}; + +void RegisterANIClearCacheListenerAndEnv(ani_vm* vm); + +} // namespace AppExecFwk +} // namespace OHOS +#endif \ No newline at end of file diff --git a/interfaces/kits/ani/bundle_manager/ets/@ohos.bundle.bundleManager.ets b/interfaces/kits/ani/bundle_manager/ets/@ohos.bundle.bundleManager.ets new file mode 100644 index 0000000000000000000000000000000000000000..9d88c2533dbe9640c7a7b97857aadfface50e796 --- /dev/null +++ b/interfaces/kits/ani/bundle_manager/ets/@ohos.bundle.bundleManager.ets @@ -0,0 +1,273 @@ +/* + * Copyright (c) 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. + */ + +import { BundleInfo } from 'bundleManager.BundleInfo'; +import { AsyncCallback, BusinessError } from '@ohos.base'; +import { ApplicationInfo } from 'bundleManager.ApplicationInfo'; +import { BundleInfoInner } from './bundleManager/BundleInfoInner'; + +namespace bundleManager { + + loadLibrary("anibundlemanager.z"); + + enum BundleFlag { + GET_BUNDLE_INFO_DEFAULT = 0x00000000, + GET_BUNDLE_INFO_WITH_APPLICATION = 0x00000001, + GET_BUNDLE_INFO_WITH_HAP_MODULE = 0x00000002, + GET_BUNDLE_INFO_WITH_ABILITY = 0x00000004, + GET_BUNDLE_INFO_WITH_EXTENSION_ABILITY = 0x00000008, + GET_BUNDLE_INFO_WITH_REQUESTED_PERMISSION = 0x00000010, + GET_BUNDLE_INFO_WITH_METADATA = 0x00000020, + GET_BUNDLE_INFO_WITH_DISABLE = 0x00000040, + GET_BUNDLE_INFO_WITH_SIGNATURE_INFO = 0x00000080, + GET_BUNDLE_INFO_WITH_MENU = 0x00000100, + GET_BUNDLE_INFO_WITH_ROUTER_MAP = 0x00000200, + GET_BUNDLE_INFO_WITH_SKILL = 0x00000800, + GET_BUNDLE_INFO_ONLY_WITH_LAUNCHER_ABILITY = 0x00001000, + GET_BUNDLE_INFO_OF_ANY_USER = 0x00002000, + GET_BUNDLE_INFO_EXCLUDE_CLONE = 0x00004000, + } + + enum ApplicationFlag { + GET_APPLICATION_INFO_DEFAULT = 0x00000000, + GET_APPLICATION_INFO_WITH_PERMISSION = 0x00000001, + GET_APPLICATION_INFO_WITH_METADATA = 0x00000002, + GET_APPLICATION_INFO_WITH_DISABLE = 0x00000004 + } + + enum AbilityFlag { + GET_ABILITY_INFO_DEFAULT = 0x00000000, + GET_ABILITY_INFO_WITH_PERMISSION = 0x00000001, + GET_ABILITY_INFO_WITH_APPLICATION = 0x00000002, + GET_ABILITY_INFO_WITH_METADATA = 0x00000004, + GET_ABILITY_INFO_WITH_DISABLE = 0x00000008, + GET_ABILITY_INFO_ONLY_SYSTEM_APP = 0x00000010, + GET_ABILITY_INFO_WITH_APP_LINKING = 0x00000040, + GET_ABILITY_INFO_WITH_SKILL = 0x00000080, + } + + enum ExtensionAbilityFlag { + GET_EXTENSION_ABILITY_INFO_DEFAULT = 0x00000000, + GET_EXTENSION_ABILITY_INFO_WITH_PERMISSION = 0x00000001, + GET_EXTENSION_ABILITY_INFO_WITH_APPLICATION = 0x00000002, + GET_EXTENSION_ABILITY_INFO_WITH_METADATA = 0x00000004, + GET_EXTENSION_ABILITY_INFO_WITH_SKILL = 0x00000010, + } + + export enum ExtensionAbilityType { + FORM = 0, + WORK_SCHEDULER = 1, + INPUT_METHOD = 2, + SERVICE = 3, + ACCESSIBILITY = 4, + DATA_SHARE = 5, + FILE_SHARE = 6, + STATIC_SUBSCRIBER = 7, + WALLPAPER = 8, + BACKUP = 9, + WINDOW = 10, + ENTERPRISE_ADMIN = 11, + THUMBNAIL = 13, + PREVIEW = 14, + PRINT = 15, + SHARE = 16, + PUSH = 17, + DRIVER = 18, + ACTION = 19, + ADS_SERVICE = 20, + EMBEDDED_UI = 21, + INSIGHT_INTENT_UI = 22, + FENCE = 24, + ASSET_ACCELERATION = 26, + FORM_EDIT = 27, + DISTRIBUTED = 28, + UNSPECIFIED = 255 + } + + export enum PermissionGrantState { + PERMISSION_DENIED = -1, + PERMISSION_GRANTED = 0 + } + + export enum SupportWindowMode { + FULL_SCREEN = 0, + SPLIT = 1, + FLOATING = 2 + } + + export enum LaunchType { + SINGLETON = 0, + MULTITON = 1, + SPECIFIED = 2 + } + + export enum DisplayOrientation { + UNSPECIFIED, + LANDSCAPE, + PORTRAIT, + FOLLOW_RECENT, + LANDSCAPE_INVERTED, + PORTRAIT_INVERTED, + AUTO_ROTATION, + AUTO_ROTATION_LANDSCAPE, + AUTO_ROTATION_PORTRAIT, + AUTO_ROTATION_RESTRICTED, + AUTO_ROTATION_LANDSCAPE_RESTRICTED, + AUTO_ROTATION_PORTRAIT_RESTRICTED, + LOCKED, + AUTO_ROTATION_UNSPECIFIED, + FOLLOW_DESKTOP + } + + export enum ModuleType { + ENTRY = 1, + FEATURE = 2, + SHARED = 3 + } + + export enum BundleType { + APP = 0, + ATOMIC_SERVICE = 1 + } + + export enum CompatiblePolicy { + BACKWARD_COMPATIBILITY = 1 + } + + export enum ProfileType { + INTENT_PROFILE = 1 + } + + export enum AppDistributionType { + APP_GALLERY = 1, + ENTERPRISE = 2, + ENTERPRISE_NORMAL = 3, + ENTERPRISE_MDM = 4, + OS_INTEGRATION = 5, + CROWDTESTING = 6, + NONE = 7 + } + + export enum MultiAppModeType { + UNSPECIFIED = 0, + MULTI_INSTANCE = 1, + APP_CLONE = 2, + } + + export enum ApplicationInfoFlag { + FLAG_INSTALLED = 0x00000001, + FLAG_OTHER_INSTALLED = 0x00000010, + FLAG_PREINSTALLED_APP = 0x00000020, + FLAG_PREINSTALLED_APP_UPDATE = 0x00000040, + } + + export native function isApplicationEnabledSync(bundleName: string): boolean; + + export native function getBundleInfoForSelfSync(bundleFlags: number): BundleInfo; + + export native function getBundleInfoSync(bundleName: string, bundleFlags: number, userId: number) : BundleInfo; + + export native function getApplicationInfoSync(bundleName: string, applicationFlags: number, userId: number): ApplicationInfo; + + function getBundleInfoForSelf(bundleFlags: number, callback: AsyncCallback):void { + let execFun = (): BundleInfo => { + return bundleManager.getBundleInfoForSelfSync(bundleFlags); + }; + let p1 = taskpool.execute(execFun); + p1.then((e: NullishType) => { + let resultBundleInfo: BundleInfo = e as BundleInfo; + let r = new BusinessError(); + callback(r, resultBundleInfo); + }, (err: BusinessError): void => { + let resultBundleInfo = new BundleInfoInner(); + callback(err, resultBundleInfo); + }); + } + + function getBundleInfoForSelf(bundleFlags: number):Promise { + let p = new Promise((resolve: (bundleInfo: BundleInfo) => void, reject: (error: BusinessError) => void) => { + let execFun = (): BundleInfo => { + return bundleManager.getBundleInfoForSelfSync(bundleFlags); + }; + let p1 = taskpool.execute(execFun); + p1.then((e: NullishType) => { + let resultBundleInfo: BundleInfo = e as BundleInfo; + resolve(resultBundleInfo); + }, (err: BusinessError): void => { + reject(err); + }); + } + ); + return p; + } + + function getBundleInfoSync(bundleName: string, bundleFlags: number): BundleInfo { + return bundleManager.getBundleInfoSync(bundleName, bundleFlags, -500); + } + + function getBundleInfo(bundleName: string, bundleFlags: number, userId?: number): Promise { + let p = new Promise((resolve: (bundleInfo: BundleInfo) => void, reject: (error: BusinessError) => void) => { + let userIdInfo: number = userId ?? -500; + let execFun = (): BundleInfo => { + return bundleManager.getBundleInfoSync(bundleName, bundleFlags, userIdInfo); + }; + let p1 = taskpool.execute(execFun); + p1.then((e: NullishType) => { + let resultBundleInfo: BundleInfo = e as BundleInfo; + resolve(resultBundleInfo); + }, (err: BusinessError): void => { + reject(err); + }); + } + ); + return p; + } + + function getBundleInfo(bundleName: string, bundleFlags: number, callback: AsyncCallback): void { + let execFun = (): BundleInfo => { + return bundleManager.getBundleInfoSync(bundleName, bundleFlags); + }; + let p1 = taskpool.execute(execFun); + p1.then((e: NullishType) => { + let resultBundleInfo: BundleInfo = e as BundleInfo; + let r = new BusinessError(); + callback(r, resultBundleInfo); + },(err: BusinessError): void => { + let resultBundleInfo = new BundleInfoInner(); + callback(err, resultBundleInfo); + }); + } + + function getBundleInfo(bundleName: string, bundleFlags: number, userId: number, callback: AsyncCallback): void { + let execFun = (): BundleInfo => { + return bundleManager.getBundleInfoSync(bundleName, bundleFlags, userId); + }; + let p1 = taskpool.execute(execFun); + p1.then((e: NullishType) => { + let resultBundleInfo: BundleInfo = e as BundleInfo; + let r = new BusinessError(); + callback(r, resultBundleInfo); + },(err: BusinessError): void => { + let resultBundleInfo = new BundleInfoInner(); + callback(err, resultBundleInfo); + }); + } + + function getApplicationInfoSync(bundleName: string, applicationFlags: number): ApplicationInfo { + return bundleManager.getApplicationInfoSync(bundleName, applicationFlags, -500); + } +} + +export default bundleManager; diff --git a/interfaces/kits/ani/bundle_manager/ets/bundleManager/AbilityInfo.ets b/interfaces/kits/ani/bundle_manager/ets/bundleManager/AbilityInfo.ets new file mode 100644 index 0000000000000000000000000000000000000000..e9f0d462096511c79701d235407b17a6c8318aa7 --- /dev/null +++ b/interfaces/kits/ani/bundle_manager/ets/bundleManager/AbilityInfo.ets @@ -0,0 +1,55 @@ +/* + * Copyright (c) 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. + */ + +import { ApplicationInfo } from 'bundleManager.ApplicationInfo'; +import { Metadata } from 'bundleManager.Metadata'; +import { Skill } from 'bundleManager.Skill'; +import bundleManager from '@ohos.bundle.bundleManager'; + +export interface AbilityInfo { + readonly bundleName: string; + readonly moduleName: string; + readonly name: string; + readonly label: string; + readonly labelId: number; + readonly description: string; + readonly descriptionId: number; + readonly icon: string; + readonly iconId: number; + readonly process: string; + readonly exported: boolean; + readonly orientation: bundleManager.DisplayOrientation; + readonly launchType: bundleManager.LaunchType; + readonly permissions: Array; + readonly deviceTypes: Array; + readonly applicationInfo: ApplicationInfo; + readonly metadata: Array; + readonly enabled: boolean; + readonly supportWindowModes: Array; + readonly windowSize: WindowSize; + readonly excludeFromDock: boolean; + readonly skills: Array; + readonly appIndex: number; + readonly orientationId: number; +} + +export interface WindowSize { + readonly maxWindowRatio: number; + readonly minWindowRatio: number; + readonly maxWindowWidth: number; + readonly minWindowWidth: number; + readonly maxWindowHeight: number; + readonly minWindowHeight: number; +} diff --git a/interfaces/kits/ani/bundle_manager/ets/bundleManager/AbilityInfoInner.ets b/interfaces/kits/ani/bundle_manager/ets/bundleManager/AbilityInfoInner.ets new file mode 100644 index 0000000000000000000000000000000000000000..fa4f2c7c437ac9bf3c6b299434c59a8ff3c79ff8 --- /dev/null +++ b/interfaces/kits/ani/bundle_manager/ets/bundleManager/AbilityInfoInner.ets @@ -0,0 +1,57 @@ +/* + * Copyright (c) 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. + */ + +import { ApplicationInfo } from 'bundleManager.ApplicationInfo'; +import { Metadata } from 'bundleManager.Metadata'; +import { Skill } from 'bundleManager.Skill'; +import bundleManager from '@ohos.bundle.bundleManager'; +import { AbilityInfo, WindowSize } from 'bundleManager.AbilityInfo'; +import { ApplicationInfoInner } from './ApplicationInfoInner'; + +export class AbilityInfoInner implements AbilityInfo { + readonly bundleName: string = ""; + readonly moduleName: string = ""; + readonly name: string = ""; + readonly label: string = ""; + readonly labelId: number; + readonly description: string = ""; + readonly descriptionId: number; + readonly icon: string = ""; + readonly iconId: number; + readonly process: string = ""; + readonly exported: boolean; + readonly orientation: bundleManager.DisplayOrientation = bundleManager.DisplayOrientation.UNSPECIFIED; + readonly launchType: bundleManager.LaunchType = bundleManager.LaunchType.SINGLETON; + readonly permissions: Array = new Array; + readonly deviceTypes: Array = new Array; + readonly applicationInfo: ApplicationInfo = new ApplicationInfoInner; + readonly metadata: Array = new Array; + readonly enabled: boolean; + readonly supportWindowModes: Array = new Array; + readonly windowSize: WindowSize = new WindowSizeInner; + readonly excludeFromDock: boolean; + readonly skills: Array = new Array; + readonly appIndex: number; + readonly orientationId: number; +} + +export class WindowSizeInner implements WindowSize { + readonly maxWindowRatio: number; + readonly minWindowRatio: number; + readonly maxWindowWidth: number; + readonly minWindowWidth: number; + readonly maxWindowHeight: number; + readonly minWindowHeight: number; +} diff --git a/interfaces/kits/ani/bundle_manager/ets/bundleManager/ApplicationInfo.ets b/interfaces/kits/ani/bundle_manager/ets/bundleManager/ApplicationInfo.ets new file mode 100644 index 0000000000000000000000000000000000000000..49789ed0bfdb2330013620e5fe85a233f1c5da02 --- /dev/null +++ b/interfaces/kits/ani/bundle_manager/ets/bundleManager/ApplicationInfo.ets @@ -0,0 +1,69 @@ +/* + * Copyright (c) 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. + */ + +import { Metadata } from 'bundleManager.Metadata'; +import { Resource } from 'global.resource'; +import bundleManager from '@ohos.bundle.bundleManager'; + +export interface ApplicationInfo { + readonly name: string; + readonly description: string; + readonly descriptionId: number; + readonly enabled: boolean; + readonly label: string; + readonly labelId: number; + readonly icon: string; + readonly iconId: number; + readonly process: string; + readonly permissions: Array; + readonly codePath: string; + readonly metadataArray: Array; + readonly removable: boolean; + readonly accessTokenId: number; + readonly uid: number; + readonly iconResource: Resource; + readonly labelResource: Resource; + readonly descriptionResource: Resource; + readonly appDistributionType: string; + readonly appProvisionType: string; + readonly systemApp: boolean; + readonly bundleType: bundleManager.BundleType; + readonly debug: boolean; + readonly dataUnclearable: boolean; + readonly nativeLibraryPath: string; + readonly multiAppMode: MultiAppMode; + readonly appIndex: number; + readonly installSource: string; + readonly releaseType: string; + readonly cloudFileSyncEnabled: boolean; + readonly flags?: number; +} + +export interface ModuleMetadata { + readonly moduleName: string; + readonly metadata: Array; +} + +export interface MultiAppMode { + readonly multiAppModeType: bundleManager.MultiAppModeType; + readonly maxCount: number; +} + +export interface PreinstalledApplicationInfo { + readonly bundleName: string; + readonly moduleName: string; + readonly iconId: number; + readonly labelId: number; +} \ No newline at end of file diff --git a/interfaces/kits/ani/bundle_manager/ets/bundleManager/ApplicationInfoInner.ets b/interfaces/kits/ani/bundle_manager/ets/bundleManager/ApplicationInfoInner.ets new file mode 100644 index 0000000000000000000000000000000000000000..3aa7ca936453379703394ceb6f2d905f68b4f9c0 --- /dev/null +++ b/interfaces/kits/ani/bundle_manager/ets/bundleManager/ApplicationInfoInner.ets @@ -0,0 +1,71 @@ +/* + * Copyright (c) 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. + */ + +import { Metadata } from 'bundleManager.Metadata'; +import { Resource } from 'global.resource'; +import bundleManager from '@ohos.bundle.bundleManager'; +import { ApplicationInfo, ModuleMetadata, MultiAppMode, PreinstalledApplicationInfo } from 'bundleManager.ApplicationInfo'; +import { ResourceInner } from 'global.resourceInner'; + +export class ApplicationInfoInner implements ApplicationInfo { + readonly name: string = ""; + readonly description: string = ""; + readonly descriptionId: number; + readonly enabled: boolean; + readonly label: string = ""; + readonly labelId: number; + readonly icon: string = ""; + readonly iconId: number; + readonly process: string = ""; + readonly permissions: Array = new Array; + readonly codePath: string = ""; + readonly metadataArray: Array = new Array; + readonly removable: boolean; + readonly accessTokenId: number; + readonly uid: number; + readonly iconResource: Resource = new ResourceInner; + readonly labelResource: Resource = new ResourceInner; + readonly descriptionResource: Resource = new ResourceInner; + readonly appDistributionType: string = ""; + readonly appProvisionType: string = ""; + readonly systemApp: boolean; + readonly bundleType: bundleManager.BundleType = bundleManager.BundleType.APP; + readonly debug: boolean; + readonly dataUnclearable: boolean; + readonly nativeLibraryPath: string = ""; + readonly multiAppMode: MultiAppMode = new MultiAppModeInner; + readonly appIndex: number; + readonly installSource: string = ""; + readonly releaseType: string = ""; + readonly cloudFileSyncEnabled: boolean; + readonly flags?: number|undefined; +} + +export class ModuleMetadataInner implements ModuleMetadata { + readonly moduleName: string = ""; + readonly metadata: Array = new Array; +} + +export class MultiAppModeInner implements MultiAppMode { + readonly multiAppModeType: bundleManager.MultiAppModeType = bundleManager.MultiAppModeType.UNSPECIFIED; + readonly maxCount: number; +} + +export class PreinstalledApplicationInfoInner implements PreinstalledApplicationInfo { + readonly bundleName: string = ""; + readonly moduleName: string = ""; + readonly iconId: number; + readonly labelId: number; +} diff --git a/interfaces/kits/ani/bundle_manager/ets/bundleManager/BundleInfo.ets b/interfaces/kits/ani/bundle_manager/ets/bundleManager/BundleInfo.ets new file mode 100644 index 0000000000000000000000000000000000000000..63841555ba33a1394a5dc85f99fef57702c05fc7 --- /dev/null +++ b/interfaces/kits/ani/bundle_manager/ets/bundleManager/BundleInfo.ets @@ -0,0 +1,62 @@ +/* + * Copyright (c) 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. + */ + +import { ApplicationInfo } from 'bundleManager.ApplicationInfo'; +import { HapModuleInfo, RouterItem } from 'bundleManager.HapModuleInfo'; +import bundleManager from '@ohos.bundle.bundleManager'; + +export interface BundleInfo { + readonly name: string; + readonly vendor: string; + readonly versionCode: number; + readonly versionName: string; + readonly minCompatibleVersionCode: number; + readonly targetVersion: number; + readonly appInfo: ApplicationInfo; + readonly hapModulesInfo: Array; + readonly reqPermissionDetails: Array; + readonly permissionGrantStates: Array; + readonly signatureInfo: SignatureInfo; + readonly installTime: number; + readonly updateTime: number; + readonly routerMap: Array; + readonly appIndex: number; + readonly firstInstallTime?: number; +} + +export interface ReqPermissionDetail { + name: string; + moduleName: string; + reason: string; + reasonId: number; + usedScene: UsedScene; +} + +export interface UsedScene { + abilities: Array; + when: string; +} + +export interface SignatureInfo { + readonly appId: string; + readonly fingerprint: string; + readonly appIdentifier: string; + readonly certificate?: string; +} + +export interface AppCloneIdentity { + readonly bundleName: string; + readonly appIndex: number; +} \ No newline at end of file diff --git a/interfaces/kits/ani/bundle_manager/ets/bundleManager/BundleInfoInner.ets b/interfaces/kits/ani/bundle_manager/ets/bundleManager/BundleInfoInner.ets new file mode 100644 index 0000000000000000000000000000000000000000..7d57600e4a32b80d7a5bbf2d43c48b069ac80ed5 --- /dev/null +++ b/interfaces/kits/ani/bundle_manager/ets/bundleManager/BundleInfoInner.ets @@ -0,0 +1,64 @@ +/* + * Copyright (c) 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. + */ + +import { ApplicationInfo } from 'bundleManager.ApplicationInfo'; +import { HapModuleInfo, RouterItem } from 'bundleManager.HapModuleInfo'; +import bundleManager from '@ohos.bundle.bundleManager'; +import { BundleInfo, ReqPermissionDetail, UsedScene, SignatureInfo, AppCloneIdentity } from 'bundleManager.BundleInfo'; +import { ApplicationInfoInner } from './ApplicationInfoInner'; + +export class BundleInfoInner implements BundleInfo { + readonly name: string = ""; + readonly vendor: string = ""; + readonly versionCode: number; + readonly versionName: string = ""; + readonly minCompatibleVersionCode: number; + readonly targetVersion: number; + readonly appInfo: ApplicationInfo = new ApplicationInfoInner; + readonly hapModulesInfo: Array = new Array; + readonly reqPermissionDetails: Array = new Array; + readonly permissionGrantStates: Array = new Array; + readonly signatureInfo: SignatureInfo = new SignatureInfoInner; + readonly routerMap: Array = new Array; + readonly installTime: number; + readonly updateTime: number; + readonly appIndex: number; + readonly firstInstallTime?: number; +} + +export class ReqPermissionDetailInner implements ReqPermissionDetail { + name: string = ""; + moduleName: string = ""; + reason: string = ""; + reasonId: number; + usedScene: UsedScene = new UsedSceneInner; +} + +export class UsedSceneInner implements UsedScene { + abilities: Array = new Array; + when: string = ""; +} + +export class SignatureInfoInner implements SignatureInfo { + readonly appId: string = ""; + readonly fingerprint: string = ""; + readonly appIdentifier: string = ""; + readonly certificate?: string | undefined = ""; +} + +export class AppCloneIdentityInner implements AppCloneIdentity { + readonly bundleName: string = ""; + readonly appIndex: number; +} \ No newline at end of file diff --git a/interfaces/kits/ani/bundle_manager/ets/bundleManager/ExtensionAbilityInfo.ets b/interfaces/kits/ani/bundle_manager/ets/bundleManager/ExtensionAbilityInfo.ets new file mode 100644 index 0000000000000000000000000000000000000000..0e54076f5acb8a422a01f72067ae6dd30f24ca04 --- /dev/null +++ b/interfaces/kits/ani/bundle_manager/ets/bundleManager/ExtensionAbilityInfo.ets @@ -0,0 +1,40 @@ +/* + * Copyright (c) 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. + */ + +import { ApplicationInfo } from 'bundleManager.ApplicationInfo'; +import { Metadata } from 'bundleManager.Metadata'; +import bundleManager from '@ohos.bundle.bundleManager'; +import { Skill } from 'bundleManager.Skill'; + +export interface ExtensionAbilityInfo { + readonly bundleName: string; + readonly moduleName: string; + readonly name: string; + readonly labelId: number; + readonly descriptionId: number; + readonly iconId: number; + readonly exported: boolean; + readonly extensionAbilityType: bundleManager.ExtensionAbilityType; + readonly extensionAbilityTypeName: string; + readonly permissions: Array; + readonly applicationInfo: ApplicationInfo; + readonly metadata: Array; + readonly enabled: boolean; + readonly readPermission: string; + readonly writePermission: string; + readonly skills: Array; + readonly appIndex: number; +} + diff --git a/interfaces/kits/ani/bundle_manager/ets/bundleManager/ExtensionAbilityInfoInner.ets b/interfaces/kits/ani/bundle_manager/ets/bundleManager/ExtensionAbilityInfoInner.ets new file mode 100644 index 0000000000000000000000000000000000000000..0ed1bc765a8971d9a0220fac84867074df0308c0 --- /dev/null +++ b/interfaces/kits/ani/bundle_manager/ets/bundleManager/ExtensionAbilityInfoInner.ets @@ -0,0 +1,42 @@ +/* + * Copyright (c) 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. + */ + +import { ApplicationInfo } from 'bundleManager.ApplicationInfo'; +import { Metadata } from 'bundleManager.Metadata'; +import bundleManager from '@ohos.bundle.bundleManager'; +import { Skill } from 'bundleManager.Skill'; +import { ExtensionAbilityInfo } from 'bundleManager.ExtensionAbilityInfo' +import { ApplicationInfoInner } from './ApplicationInfoInner'; + +export class ExtensionAbilityInfoInner implements ExtensionAbilityInfo { + readonly bundleName: string = ""; + readonly moduleName: string = ""; + readonly name: string = ""; + readonly labelId: number; + readonly descriptionId: number; + readonly iconId: number; + readonly exported: boolean; + readonly extensionAbilityType: bundleManager.ExtensionAbilityType = bundleManager.ExtensionAbilityType.UNSPECIFIED; + readonly extensionAbilityTypeName: string = ""; + readonly permissions: Array = new Array; + readonly applicationInfo: ApplicationInfo = new ApplicationInfoInner; + readonly metadata: Array = new Array; + readonly enabled: boolean; + readonly readPermission: string = ""; + readonly writePermission: string = ""; + readonly skills: Array = new Array; + readonly appIndex: number; +} + diff --git a/interfaces/kits/ani/bundle_manager/ets/bundleManager/HapModuleInfo.ets b/interfaces/kits/ani/bundle_manager/ets/bundleManager/HapModuleInfo.ets new file mode 100644 index 0000000000000000000000000000000000000000..acf816284373a3a1de99bdca9117c2471ce7e839 --- /dev/null +++ b/interfaces/kits/ani/bundle_manager/ets/bundleManager/HapModuleInfo.ets @@ -0,0 +1,66 @@ +/* + * Copyright (c) 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. + */ + +import { AbilityInfo } from 'bundleManager.AbilityInfo'; +import { ExtensionAbilityInfo } from 'bundleManager.ExtensionAbilityInfo'; +import { Metadata } from 'bundleManager.Metadata'; +import bundleManager from '@ohos.bundle.bundleManager'; + +export interface HapModuleInfo { + readonly name: string; + readonly icon: string; + readonly iconId: number; + readonly label: string; + readonly labelId: number; + readonly description: string; + readonly descriptionId: number; + readonly mainElementName: string; + readonly abilitiesInfo: Array; + readonly extensionAbilitiesInfo: Array; + readonly metadata: Array; + readonly deviceTypes: Array; + readonly installationFree: boolean; + readonly hashValue: string; + readonly type: bundleManager.ModuleType; + readonly dependencies: Array; + readonly preloads: Array; + readonly fileContextMenuConfig: string; + readonly routerMap: Array; + readonly nativeLibraryPath: string; + readonly codePath: string; +} + +export interface Dependency { + readonly moduleName: string; + readonly bundleName: string; + readonly versionCode: number; +} + +export interface PreloadItem { + readonly moduleName: string; +} + +export interface RouterItem { + readonly name: string; + readonly pageSourceFile: string; + readonly buildFunction: string; + readonly customData: string; + readonly data: Array; +} + +export interface DataItem { + readonly key: string; + readonly value: string; +} \ No newline at end of file diff --git a/interfaces/kits/ani/bundle_manager/ets/bundleManager/HapModuleInfoInner.ets b/interfaces/kits/ani/bundle_manager/ets/bundleManager/HapModuleInfoInner.ets new file mode 100644 index 0000000000000000000000000000000000000000..4022bb7ffb0dca165b4f8a518b9e2bc639b7e185 --- /dev/null +++ b/interfaces/kits/ani/bundle_manager/ets/bundleManager/HapModuleInfoInner.ets @@ -0,0 +1,67 @@ +/* + * Copyright (c) 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. + */ + +import { AbilityInfo } from 'bundleManager.AbilityInfo'; +import { ExtensionAbilityInfo } from 'bundleManager.ExtensionAbilityInfo'; +import { Metadata } from 'bundleManager.Metadata'; +import bundleManager from '@ohos.bundle.bundleManager'; +import { HapModuleInfo, Dependency, PreloadItem, RouterItem, DataItem } from 'bundleManager.HapModuleInfo' + +export class HapModuleInfoInner implements HapModuleInfo { + readonly name: string = ""; + readonly icon: string = ""; + readonly iconId: number; + readonly label: string = ""; + readonly labelId: number; + readonly description: string = ""; + readonly descriptionId: number; + readonly mainElementName: string = ""; + readonly abilitiesInfo: Array = new Array; + readonly extensionAbilitiesInfo: Array = new Array; + readonly metadata: Array = new Array; + readonly deviceTypes: Array = new Array; + readonly installationFree: boolean; + readonly hashValue: string = ""; + readonly type: bundleManager.ModuleType = bundleManager.ModuleType.ENTRY; + readonly dependencies: Array = new Array; + readonly preloads: Array = new Array; + readonly fileContextMenuConfig: string = ""; + readonly routerMap: Array = new Array; + readonly nativeLibraryPath: string = ""; + readonly codePath: string = ""; +} + +export class DependencyInner implements Dependency { + readonly moduleName: string = ""; + readonly bundleName: string = ""; + readonly versionCode: number; +} + +export class PreloadItemInner implements PreloadItem { + readonly moduleName: string = ""; +} + +export class RouterItemInner implements RouterItem { + readonly name: string = ""; + readonly pageSourceFile: string = ""; + readonly buildFunction: string = ""; + readonly customData: string = ""; + readonly data: Array = new Array; +} + +export class DataItemInner implements DataItem { + readonly key: string = ""; + readonly value: string = ""; +} \ No newline at end of file diff --git a/interfaces/kits/ani/bundle_manager/ets/bundleManager/Metadata.ets b/interfaces/kits/ani/bundle_manager/ets/bundleManager/Metadata.ets new file mode 100644 index 0000000000000000000000000000000000000000..8005f976a3de3bb15dc7536885f58482e016a4f8 --- /dev/null +++ b/interfaces/kits/ani/bundle_manager/ets/bundleManager/Metadata.ets @@ -0,0 +1,21 @@ +/* + * Copyright (c) 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. + */ + +export interface Metadata { + name: string; + value: string; + resource: string; + readonly valueId?: number; +} diff --git a/interfaces/kits/ani/bundle_manager/ets/bundleManager/MetadataInner.ets b/interfaces/kits/ani/bundle_manager/ets/bundleManager/MetadataInner.ets new file mode 100644 index 0000000000000000000000000000000000000000..4fa5d528ec70c3fe235ab90b5e0f85881a0a5b7c --- /dev/null +++ b/interfaces/kits/ani/bundle_manager/ets/bundleManager/MetadataInner.ets @@ -0,0 +1,23 @@ +/* + * Copyright (c) 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. + */ + +import { Metadata } from 'bundleManager.Metadata' + +export class MetadataInner implements Metadata { + name: string = ""; + value: string = ""; + resource: string = ""; + readonly valueId?: number; +} diff --git a/interfaces/kits/ani/bundle_manager/ets/bundleManager/Skill.ets b/interfaces/kits/ani/bundle_manager/ets/bundleManager/Skill.ets new file mode 100644 index 0000000000000000000000000000000000000000..9fa231ab73a153fbf8940da8fc416f1a338ca72b --- /dev/null +++ b/interfaces/kits/ani/bundle_manager/ets/bundleManager/Skill.ets @@ -0,0 +1,34 @@ +/* + * Copyright (c) 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. + */ + +export interface Skill { + readonly actions: Array; + readonly entities: Array; + readonly uris: Array; + readonly domainVerify: boolean; +} + +export interface SkillUri { + readonly scheme: string; + readonly host: string; + readonly port: number; + readonly path: string; + readonly pathStartWith: string; + readonly pathRegex: string; + readonly type: string; + readonly utd: string; + readonly maxFileSupported: number; + readonly linkFeature: string; +} diff --git a/interfaces/kits/ani/bundle_manager/ets/bundleManager/SkillInner.ets b/interfaces/kits/ani/bundle_manager/ets/bundleManager/SkillInner.ets new file mode 100644 index 0000000000000000000000000000000000000000..0cb6db443e34c8d8e63a3492f86afc15283e183e --- /dev/null +++ b/interfaces/kits/ani/bundle_manager/ets/bundleManager/SkillInner.ets @@ -0,0 +1,36 @@ +/* + * Copyright (c) 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. + */ + +import { Skill, SkillUri } from 'bundleManager.Skill' + +export class SkillInner implements Skill { + readonly actions: Array = new Array; + readonly entities: Array = new Array; + readonly uris: Array = new Array; + readonly domainVerify: boolean; +} + +export class SkillUriInner implements SkillUri { + readonly scheme: string = ""; + readonly host: string = ""; + readonly port: number; + readonly path: string = ""; + readonly pathStartWith: string = ""; + readonly pathRegex: string = ""; + readonly type: string = ""; + readonly utd: string = ""; + readonly maxFileSupported: number; + readonly linkFeature: string = ""; +} diff --git a/interfaces/kits/ani/common/BUILD.gn b/interfaces/kits/ani/common/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..74c6ecafed5bad1977ac0e5b8411424d254c4a6e --- /dev/null +++ b/interfaces/kits/ani/common/BUILD.gn @@ -0,0 +1,76 @@ +# Copyright (c) 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. + +import("//build/ohos.gni") +import("../../../../appexecfwk.gni") + +config("bms_ani_common_config") { + include_dirs = [ + "./", + "${kits_path}/js/common", + ] +} + +ohos_shared_library("bms_ani_common") { + branch_protector_ret = "pac_ret" + sanitize = { + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + integer_overflow = true + ubsan = true + } + + sources = [ + "business_error_ani.cpp", + "common_fun_ani.cpp", + ] + + cflags = [ + "-Os", + "-fstack-protector-strong", + ] + + cflags_cc = [ + "-Os", + "-fstack-protector-strong", + ] + + deps = [ + "${base_path}:appexecfwk_base", + "${common_path}:libappexecfwk_common", + "${core_path}:appexecfwk_core", + "${kits_path}/js/common:bundle_napi_common", + ] + + defines = [ + "APP_LOG_TAG = \"BMS\"", + "LOG_DOMAIN = 0xD001120", + ] + + public_configs = [ ":bms_ani_common_config" ] + + external_deps = [ + "ability_base:want", + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_core", + "runtime_core:ani", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + ] + + subsystem_name = "bundlemanager" + part_name = "bundle_framework" +} diff --git a/interfaces/kits/ani/common/business_error_ani.cpp b/interfaces/kits/ani/common/business_error_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..a1cdca7fc5e6b0a642678eab5b7f56c782561acc --- /dev/null +++ b/interfaces/kits/ani/common/business_error_ani.cpp @@ -0,0 +1,403 @@ +/* +* Copyright (c) 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 +#include + +#include "app_log_wrapper.h" +#include "bundle_errors.h" +#include "business_error_ani.h" +#include "napi_constants.h" +#include "common_fun_ani.h" + +namespace OHOS { +namespace AppExecFwk { +namespace { +constexpr const char* ERR_MSG_BUSINESS_ERROR = "BusinessError $: "; +constexpr const char* ERR_MSG_PERMISSION_DENIED_ERROR = + "Permission denied. An attempt was made to $ forbidden by permission: $."; +constexpr const char* ERR_MSG_NOT_SYSTEM_APP = + "Permission denied. Non-system APP calling system API"; +constexpr const char* ERR_MSG_PARAM_TYPE_ERROR = "Parameter error. The type of $ must be $."; +constexpr const char* ERR_MSG_ABILITY_NOT_SUPPORTED = + "Capability not supported. Function $ can not work correctly due to limited device capabilities."; +constexpr const char* ERR_MSG_BUNDLE_NOT_EXIST = "The specified bundle is not found."; +constexpr const char* ERR_MSG_MODULE_NOT_EXIST = "The specified module is not found."; +constexpr const char* ERR_MSG_ABILITY_NOT_EXIST = "The specified ability is not found."; +constexpr const char* ERR_MSG_INVALID_USER_ID = "The specified user id is not found."; +constexpr const char* ERR_MSG_APPID_NOT_EXIST = "The specified appId is an empty string."; +constexpr const char* ERR_MSG_PERMISSION_NOT_EXIST = "The specified permission is not found."; +constexpr const char* ERR_MSG_DEVICE_ID_NOT_EXIST = "The specified deviceId is not found."; +constexpr const char* ERR_MSG_INVALID_APP_INDEX = "The specified app index is invalid."; +constexpr const char* ERR_MSG_INSTALL_PARSE_FAILED = "Failed to install the hap since the hap fails to be parsed."; +constexpr const char* ERR_MSG_INSTALL_VERIFY_SIGNATURE_FAILED = + "Failed to install the hap since the hap signature fails to be verified."; +constexpr const char* ERR_MSG_INSTALL_HAP_FILEPATH_INVALID = + "Failed to install the hap since the path of the hap is invalid or too large size."; +constexpr const char* ERR_MSG_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT = + "Failed to install haps since the configuration information of multi haps is inconsistent."; +constexpr const char* ERR_MSG_INSTALL_NO_DISK_SPACE_LEFT = + "Failed to install the hap since the system disk space is insufficient."; +constexpr const char* ERR_MSG_INSTALL_VERSION_DOWNGRADE = + "Failed to install the hap since the version of the newly installed hap is too early."; +constexpr const char* ERR_MSG_INSTALL_DEPENDENT_MODULE_NOT_EXIST = + "Failed to install the HAP or HSP because the dependent module does not exist."; +constexpr const char* ERR_MSG_INSTALL_SHARE_APP_LIBRARY_NOT_ALLOWED = + "Failed to install the HSP due to the lack of required permission."; +constexpr const char* ERR_MSG_UNINSTALL_PREINSTALL_APP_FAILED = "The preinstalled app cannot be uninstalled."; +constexpr const char* ERR_MSG_BUNDLE_NOT_PREINSTALLED = + "Failed to uninstall updates because the HAP is not pre-installed."; +constexpr const char* ERR_ZLIB_SRC_FILE_INVALID_MSG = "The Input source file is invalid."; +constexpr const char* ERR_ZLIB_DEST_FILE_INVALID_MSG = "The Input destination file is invalid."; +constexpr const char* ERR_MSG_PARAM_NUMBER_ERROR = + "BusinessError 401: Parameter error. The number of parameters is incorrect."; +constexpr const char* ERR_MSG_BUNDLE_SERVICE_EXCEPTION = "Bundle manager service is excepted."; +constexpr const char* ERROR_MSG_BUNDLE_IS_DISABLED = "The specified bundle is disabled."; +constexpr const char* ERROR_MSG_ABILITY_IS_DISABLED = "The specified ability is disabled."; +constexpr const char* ERROR_MSG_PROFILE_NOT_EXIST = "The specified profile is not found in the HAP."; +constexpr const char* ERROR_INVALID_UID_MSG = "The specified uid is invalid."; +constexpr const char* ERROR_INVALID_HAP_PATH_MSG = "The input source file is invalid."; +constexpr const char* ERROR_DEFAULT_APP_NOT_EXIST_MSG = "The specified default app does not exist."; +constexpr const char* ERROR_INVALID_TYPE_MSG = "The specified type is invalid."; +constexpr const char* ERROR_MSG_DISTRIBUTED_SERVICE_NOT_RUNNING = "The distributed service is not running."; +constexpr const char* ERROR_ABILITY_AND_TYPE_MISMATCH_MSG = "The specified ability and type do not match."; +constexpr const char* ERROR_MSG_CLEAR_CACHE_FILES_UNSUPPORTED = + "The specified bundle does not support clearing cache files."; +constexpr const char* ERROR_MSG_INSTALL_HAP_OVERLAY_CHECK_FAILED = + "Failed to install the HAP because the overlay check of the HAP failed."; +constexpr const char* ERROR_MSG_SPECIFIED_BUNDLE_NOT_OVERLAY_BUNDLE = + "The specified bundleName is not overlay bundle."; +constexpr const char* ERROR_MSG_SPECIFIED_MODULE_NOT_OVERLAY_MODULE = + "The specified moduleName is not overlay module."; +constexpr const char* ERROR_MSG_SPECIFIED_MODULE_IS_OVERLAY_MODULE = + "The specified moduleName is overlay module."; +constexpr const char* ERROR_MSG_SPECIFIED_BUNDLE_IS_OVERLAY_BUNDLE = + "The specified bundle is overlay bundle."; +constexpr const char* ERROR_MSG_SHARE_APP_LIBRARY_IS_RELIED = + "The version of the shared bundle is dependent on other applications."; +constexpr const char* ERROR_MSG_SHARE_APP_LIBRARY_IS_NOT_EXIST = + "The specified shared library is not exist"; +constexpr const char* ERR_MSG_UNINSTALL_SHARED_LIBRARY = + "The specified bundle is shared library"; +constexpr const char* ERR_MSG_DISALLOW_INSTALL = + "Failed to install the HAP because the installation is forbidden by enterprise device management."; +constexpr const char* ERR_MSG_WRONG_PROXY_DATA_URI = + "The uri in data proxy is wrong"; +constexpr const char* ERR_MSG_WRONG_PROXY_DATA_PERMISSION = + "The apl of required permission in non-system data proxy should be system_basic or system_core"; +constexpr const char* ERR_MSG_WRONG_MODE_ISOLATION = + "Failed to install the HAP because the isolationMode configured is not supported"; +constexpr const char* ERR_MSG_DISALLOW_UNINSTALL = + "Failed to uninstall the HAP because the uninstall is forbidden by enterprise device management."; +constexpr const char* ERR_MSG_ALREADY_EXIST = + "Failed to install the HAP because the VersionCode to be updated is not greater than the current VersionCode"; +constexpr const char* ERR_ZLIB_SRC_FILE_FORMAT_ERROR_OR_DAMAGED_MSG = + "The input source file is not in ZIP format or is damaged."; +constexpr const char* ERR_MSG_CODE_SIGNATURE_FAILED = + "Failed to install the HAP because the code signature verification failed."; +constexpr const char* ERR_MSG_SELF_UPDATE_NOT_MDM = + "Failed to install the HAP because the distribution type of the caller application is not enterprise_mdm."; +constexpr const char* ERR_MSG_SELF_UPDATE_BUNDLENAME_NOT_SAME = + "Failed to install the HAP because the bundleName is different from the bundleName of the caller application."; +constexpr const char* ERR_MSG_ENTERPRISE_BUNDLE_NOT_ALLOWED = + "Failed to install the HAP because an enterprise normal/MDM bundle cannot be installed on non-enterprise devices."; +constexpr const char* ERR_MSG_INSTALL_EXISTED_ENTERPRISE_BUNDLE_NOT_ALLOWED = + "It is not allowed to install the enterprise bundle."; +constexpr const char* ERR_MSG_DEBUG_BUNDLE_NOT_ALLOWED = + "Failed to install the HAP because a debug bundle can be installed only in developer mode."; +constexpr const char* ERR_MSG_ERROR_VERIFY_ABC = "Failed to verify the abc file."; +constexpr const char* ERR_MSG_ERROR_DELETE_ABC = "Failed to delete the abc file."; +constexpr const char* ERR_MSG_ERROR_EXT_RESOURCE_ADD_ERROR = "Failed to add extended resources."; +constexpr const char* ERR_MSG_ERROR_EXT_RESOURCE_REMOVE_ERROR = "Failed to remove extended resources."; +constexpr const char* ERR_MSG_ERROR_EXT_RESOURCE_GET_ERROR = "Failed to obtain extended resources."; +constexpr const char* ERR_MSG_ERROR_DYNAMIC_ICON_ENABLE_ERROR = "Failed to enable the dynamic icon."; +constexpr const char* ERR_MSG_ERROR_DYNAMIC_ICON_DISABLE_ERROR = "Failed to disable the dynamic icon."; +constexpr const char* ERR_MSG_ERROR_DYNAMIC_ICON_GET_ERROR = "Failed to obtain the dynamic icon."; +constexpr const char* ERROR_MSG_NOT_APP_GALLERY_CALL = "The caller is not AppGallery."; +constexpr const char* ERROR_MSG_INSTALL_PERMISSION_CHECK_ERROR = + "Failed to install the HAP because the HAP requests wrong permissions."; +constexpr const char* ERR_MSG_INVALID_LINK = "The specified link is invalid."; +constexpr const char* ERR_MSG_SCHEME_NOT_IN_QUERYSCHEMES = + "The scheme of the specified link is not in the querySchemes."; +constexpr const char* ERR_MSG_INVALID_DEVELOPER_ID = + "The specified developerId is invalid."; +constexpr const char* ERR_MSG_ENUM_EROOR = + "Parameter error. The value of $ is not a valid enum $."; +constexpr const char* ERR_MSG_BUNDLE_CAN_NOT_BE_UNINSTALLED = + "The specified application cannot be uninstalled."; +constexpr const char* ERR_MSG_START_SHORTCUT = + "The ability specified by want in the ShortcutInfo struct cannot be started."; +constexpr const char* ERR_MSG_INSTALL_FAILED_CONTROLLED = + "Failed to install the HAP because the device has been controlled."; +constexpr const char* ERR_MSG_NATIVE_INSTALL_FAILED = + "Failed to install the HAP because installing the native package failed."; +constexpr const char* ERR_MSG_NATIVE_UNINSTALL_FAILED = + "Failed to uninstall the HAP because uninstalling the native package failed."; +constexpr const char* ERR_MSG_INVALID_APPINDEX = + "The appIndex is invalid."; +constexpr const char* ERR_MSG_APP_NOT_SUPPORTED_MULTI_TYPE = + "The app does not support the creation of an appClone instance."; +constexpr const char* ERR_MSG_SHORTCUT_ID_ILLEGAL = + "The specified shortcut id is illegal."; +constexpr const char* ERR_MSG_INSTALL_FAILED_INCONSISTENT_SIGNATURE = + "Failed to install the HAP because an application with the same bundle name " + "but different signature information exists on the device."; + +static std::unordered_map ERR_MSG_MAP = { + { ERROR_PERMISSION_DENIED_ERROR, ERR_MSG_PERMISSION_DENIED_ERROR }, + { ERROR_NOT_SYSTEM_APP, ERR_MSG_NOT_SYSTEM_APP }, + { ERROR_PARAM_CHECK_ERROR, ERR_MSG_PARAM_TYPE_ERROR }, + { ERROR_SYSTEM_ABILITY_NOT_FOUND, ERR_MSG_ABILITY_NOT_SUPPORTED }, + { ERROR_BUNDLE_NOT_EXIST, ERR_MSG_BUNDLE_NOT_EXIST }, + { ERROR_MODULE_NOT_EXIST, ERR_MSG_MODULE_NOT_EXIST }, + { ERROR_ABILITY_NOT_EXIST, ERR_MSG_ABILITY_NOT_EXIST }, + { ERROR_INVALID_USER_ID, ERR_MSG_INVALID_USER_ID }, + { ERROR_INVALID_APPID, ERR_MSG_APPID_NOT_EXIST }, + { ERROR_INVALID_APPINDEX, ERR_MSG_INVALID_APP_INDEX }, + { ERROR_PERMISSION_NOT_EXIST, ERR_MSG_PERMISSION_NOT_EXIST }, + { ERROR_DEVICE_ID_NOT_EXIST, ERR_MSG_DEVICE_ID_NOT_EXIST }, + { ERROR_INSTALL_PARSE_FAILED, ERR_MSG_INSTALL_PARSE_FAILED }, + { ERROR_INSTALL_VERIFY_SIGNATURE_FAILED, ERR_MSG_INSTALL_VERIFY_SIGNATURE_FAILED }, + { ERROR_INSTALL_HAP_FILEPATH_INVALID, ERR_MSG_INSTALL_HAP_FILEPATH_INVALID }, + { ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT, ERR_MSG_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { ERROR_INSTALL_NO_DISK_SPACE_LEFT, ERR_MSG_INSTALL_NO_DISK_SPACE_LEFT }, + { ERROR_INSTALL_VERSION_DOWNGRADE, ERR_MSG_INSTALL_VERSION_DOWNGRADE }, + { ERROR_INSTALL_DEPENDENT_MODULE_NOT_EXIST, ERR_MSG_INSTALL_DEPENDENT_MODULE_NOT_EXIST }, + { ERROR_INSTALL_SHARE_APP_LIBRARY_NOT_ALLOWED, ERR_MSG_INSTALL_SHARE_APP_LIBRARY_NOT_ALLOWED }, + { ERROR_UNINSTALL_PREINSTALL_APP_FAILED, ERR_MSG_UNINSTALL_PREINSTALL_APP_FAILED }, + { ERROR_BUNDLE_NOT_PREINSTALLED, ERR_MSG_BUNDLE_NOT_PREINSTALLED }, + { ERROR_BUNDLE_SERVICE_EXCEPTION, ERR_MSG_BUNDLE_SERVICE_EXCEPTION }, + { ERR_ZLIB_SRC_FILE_INVALID, ERR_ZLIB_SRC_FILE_INVALID_MSG }, + { ERR_ZLIB_DEST_FILE_INVALID, ERR_ZLIB_DEST_FILE_INVALID_MSG }, + { ERROR_BUNDLE_IS_DISABLED, ERROR_MSG_BUNDLE_IS_DISABLED }, + { ERROR_ABILITY_IS_DISABLED, ERROR_MSG_ABILITY_IS_DISABLED }, + { ERROR_PROFILE_NOT_EXIST, ERROR_MSG_PROFILE_NOT_EXIST }, + { ERROR_INVALID_UID, ERROR_INVALID_UID_MSG }, + { ERROR_INVALID_HAP_PATH, ERROR_INVALID_HAP_PATH_MSG }, + { ERROR_DEFAULT_APP_NOT_EXIST, ERROR_DEFAULT_APP_NOT_EXIST_MSG }, + { ERROR_INVALID_TYPE, ERROR_INVALID_TYPE_MSG }, + { ERROR_DISTRIBUTED_SERVICE_NOT_RUNNING, ERROR_MSG_DISTRIBUTED_SERVICE_NOT_RUNNING }, + { ERROR_ABILITY_AND_TYPE_MISMATCH, ERROR_ABILITY_AND_TYPE_MISMATCH_MSG }, + { ERROR_CLEAR_CACHE_FILES_UNSUPPORTED, ERROR_MSG_CLEAR_CACHE_FILES_UNSUPPORTED }, + { ERROR_INSTALL_HAP_OVERLAY_CHECK_FAILED, ERROR_MSG_INSTALL_HAP_OVERLAY_CHECK_FAILED }, + { ERROR_SPECIFIED_MODULE_NOT_OVERLAY_MODULE, ERROR_MSG_SPECIFIED_MODULE_NOT_OVERLAY_MODULE }, + { ERROR_SPECIFIED_BUNDLE_NOT_OVERLAY_BUNDLE, ERROR_MSG_SPECIFIED_BUNDLE_NOT_OVERLAY_BUNDLE }, + { ERROR_SPECIFIED_MODULE_IS_OVERLAY_MODULE, ERROR_MSG_SPECIFIED_MODULE_IS_OVERLAY_MODULE }, + { ERROR_SPECIFIED_BUNDLE_IS_OVERLAY_BUNDLE, ERROR_MSG_SPECIFIED_BUNDLE_IS_OVERLAY_BUNDLE }, + { ERROR_UNINSTALL_SHARE_APP_LIBRARY_IS_RELIED, ERROR_MSG_SHARE_APP_LIBRARY_IS_RELIED }, + { ERROR_UNINSTALL_SHARE_APP_LIBRARY_IS_NOT_EXIST, ERROR_MSG_SHARE_APP_LIBRARY_IS_NOT_EXIST }, + { ERROR_UNINSTALL_BUNDLE_IS_SHARED_BUNDLE, ERR_MSG_UNINSTALL_SHARED_LIBRARY }, + { ERROR_DISALLOW_INSTALL, ERR_MSG_DISALLOW_INSTALL }, + { ERROR_INSTALL_WRONG_DATA_PROXY_URI, ERR_MSG_WRONG_PROXY_DATA_URI }, + { ERROR_INSTALL_WRONG_DATA_PROXY_PERMISSION, ERR_MSG_WRONG_PROXY_DATA_PERMISSION }, + { ERROR_INSTALL_WRONG_MODE_ISOLATION, ERR_MSG_WRONG_MODE_ISOLATION }, + { ERROR_DISALLOW_UNINSTALL, ERR_MSG_DISALLOW_UNINSTALL }, + { ERROR_INSTALL_ALREADY_EXIST, ERR_MSG_ALREADY_EXIST }, + { ERR_ZLIB_SRC_FILE_FORMAT_ERROR_OR_DAMAGED, ERR_ZLIB_SRC_FILE_FORMAT_ERROR_OR_DAMAGED_MSG }, + { ERROR_INSTALL_CODE_SIGNATURE_FAILED, ERR_MSG_CODE_SIGNATURE_FAILED }, + { ERROR_INSTALL_SELF_UPDATE_NOT_MDM, ERR_MSG_SELF_UPDATE_NOT_MDM}, + { ERROR_INSTALL_SELF_UPDATE_BUNDLENAME_NOT_SAME, ERR_MSG_SELF_UPDATE_BUNDLENAME_NOT_SAME}, + { ERROR_INSTALL_ENTERPRISE_BUNDLE_NOT_ALLOWED, ERR_MSG_ENTERPRISE_BUNDLE_NOT_ALLOWED }, + { ERROR_INSTALL_EXISTED_ENTERPRISE_NOT_ALLOWED_ERROR, ERR_MSG_INSTALL_EXISTED_ENTERPRISE_BUNDLE_NOT_ALLOWED }, + { ERROR_INSTALL_DEBUG_BUNDLE_NOT_ALLOWED, ERR_MSG_DEBUG_BUNDLE_NOT_ALLOWED}, + { ERROR_VERIFY_ABC, ERR_MSG_ERROR_VERIFY_ABC}, + { ERROR_NOT_APP_GALLERY_CALL, ERROR_MSG_NOT_APP_GALLERY_CALL}, + { ERROR_DELETE_ABC, ERR_MSG_ERROR_DELETE_ABC}, + { ERROR_ADD_EXTEND_RESOURCE, ERR_MSG_ERROR_EXT_RESOURCE_ADD_ERROR}, + { ERROR_REMOVE_EXTEND_RESOURCE, ERR_MSG_ERROR_EXT_RESOURCE_REMOVE_ERROR}, + { ERROR_GET_EXTEND_RESOURCE, ERR_MSG_ERROR_EXT_RESOURCE_GET_ERROR}, + { ERROR_ENABLE_DYNAMIC_ICON, ERR_MSG_ERROR_DYNAMIC_ICON_ENABLE_ERROR}, + { ERROR_DISABLE_DYNAMIC_ICON, ERR_MSG_ERROR_DYNAMIC_ICON_DISABLE_ERROR}, + { ERROR_GET_DYNAMIC_ICON, ERR_MSG_ERROR_DYNAMIC_ICON_GET_ERROR}, + { ERROR_INSTALL_PERMISSION_CHECK_ERROR, ERROR_MSG_INSTALL_PERMISSION_CHECK_ERROR}, + { ERROR_INVALID_LINK, ERR_MSG_INVALID_LINK }, + { ERROR_SCHEME_NOT_IN_QUERYSCHEMES, ERR_MSG_SCHEME_NOT_IN_QUERYSCHEMES }, + { ERROR_INVALID_DEVELOPERID, ERR_MSG_INVALID_DEVELOPER_ID }, + { ERROR_BUNDLE_CAN_NOT_BE_UNINSTALLED, ERR_MSG_BUNDLE_CAN_NOT_BE_UNINSTALLED }, + { ERROR_START_SHORTCUT_ERROR, ERR_MSG_START_SHORTCUT }, + { ERROR_INSTALL_FAILED_CONTROLLED, ERR_MSG_INSTALL_FAILED_CONTROLLED }, + { ERROR_INSTALL_NATIVE_FAILED, ERR_MSG_NATIVE_INSTALL_FAILED }, + { ERROR_UNINSTALL_NATIVE_FAILED, ERR_MSG_NATIVE_UNINSTALL_FAILED }, + { ERROR_INVALID_APPINDEX, ERR_MSG_INVALID_APPINDEX }, + { ERROR_APP_NOT_SUPPORTED_MULTI_TYPE, ERR_MSG_APP_NOT_SUPPORTED_MULTI_TYPE }, + { ERROR_SHORTCUT_ID_ILLEGAL_ERROR, ERR_MSG_SHORTCUT_ID_ILLEGAL }, + { ERROR_INSTALL_FAILED_INCONSISTENT_SIGNATURE, ERR_MSG_INSTALL_FAILED_INCONSISTENT_SIGNATURE } +}; + +constexpr const char* BUSINESS_ERROR_CLASS = "L@ohos/base/BusinessError;"; +} // namespace + +void BusinessErrorAni::ThrowError(ani_env *env, int32_t err, const std::string &msg) +{ + if (env == nullptr) { + return; + } + ani_object error = CreateError(env, err, msg); + ThrowError(env, error); +} + +ani_object BusinessErrorAni::WrapError(ani_env *env, const std::string &msg) +{ + if (env == nullptr) { + return nullptr; + } + ani_class cls = nullptr; + ani_method method = nullptr; + ani_object obj = nullptr; + + ani_string aniMsg = nullptr; + if (!CommonFunAni::StringToAniStr(env, msg, aniMsg)) { + APP_LOGE("StringToAniStr failed"); + return nullptr; + } + + ani_ref undefRef; + env->GetUndefined(&undefRef); + + ani_status status = env->FindClass("Lescompat/Error;", &cls); + if (status != ANI_OK) { + APP_LOGE("FindClass : %{public}d", status); + return nullptr; + } + status = env->Class_FindMethod(cls, "", "Lstd/core/String;Lescompat/ErrorOptions;:V", &method); + if (status != ANI_OK) { + APP_LOGE("Class_FindMethod : %{public}d", status); + return nullptr; + } + status = env->Object_New(cls, method, &obj, aniMsg, undefRef); + if (status != ANI_OK) { + APP_LOGE("Object_New : %{public}d", status); + return nullptr; + } + return obj; +} + +ani_object BusinessErrorAni::CreateError(ani_env *env, int32_t code, const std::string& msg) +{ + if (env == nullptr) { + return nullptr; + } + ani_class cls = nullptr; + ani_method method = nullptr; + ani_object obj = nullptr; + ani_status status = env->FindClass(BUSINESS_ERROR_CLASS, &cls); + if (status != ANI_OK) { + APP_LOGE("FindClass : %{public}d", status); + return nullptr; + } + status = env->Class_FindMethod(cls, "", "DLescompat/Error;:V", &method); + if (status != ANI_OK) { + APP_LOGE("Class_FindMethod : %{public}d", status); + return nullptr; + } + ani_object error = WrapError(env, msg); + if (error == nullptr) { + APP_LOGE("WrapError failed"); + return nullptr; + } + ani_double dCode(code); + status = env->Object_New(cls, method, &obj, dCode, error); + if (status != ANI_OK) { + APP_LOGE("Object_New : %{public}d", status); + return nullptr; + } + return obj; +} + +void BusinessErrorAni::ThrowParameterTypeError(ani_env *env, int32_t err, + const std::string ¶meter, const std::string &type) +{ + if (env == nullptr) { + return; + } + ani_object error = CreateCommonError(env, err, parameter, type); + ThrowError(env, error); +} + +void BusinessErrorAni::ThrowTooFewParametersError(ani_env *env, int32_t err) +{ + if (env == nullptr) { + return; + } + ThrowError(env, err, ERR_MSG_PARAM_NUMBER_ERROR); +} + +ani_object BusinessErrorAni::CreateCommonError( + ani_env *env, int32_t err, const std::string &functionName, const std::string &permissionName) +{ + if (env == nullptr) { + return nullptr; + } + std::string errMessage = ERR_MSG_BUSINESS_ERROR; + auto iter = errMessage.find("$"); + if (iter != std::string::npos) { + errMessage = errMessage.replace(iter, 1, std::to_string(err)); + } + if (ERR_MSG_MAP.find(err) != ERR_MSG_MAP.end()) { + errMessage += ERR_MSG_MAP[err]; + } + iter = errMessage.find("$"); + if (iter != std::string::npos) { + errMessage = errMessage.replace(iter, 1, functionName); + iter = errMessage.find("$"); + if (iter != std::string::npos) { + errMessage = errMessage.replace(iter, 1, permissionName); + } + } + return CreateError(env, err, errMessage); +} + +void BusinessErrorAni::ThrowEnumError(ani_env *env, + const std::string ¶meter, const std::string &type) +{ + if (env == nullptr) { + return; + } + ani_object error = CreateEnumError(env, parameter, type); + ThrowError(env, error); +} + +ani_object BusinessErrorAni::CreateEnumError(ani_env *env, + const std::string ¶meter, const std::string &enumClass) +{ + if (env == nullptr) { + return nullptr; + } + std::string errMessage = ERR_MSG_BUSINESS_ERROR; + auto iter = errMessage.find("$"); + if (iter != std::string::npos) { + errMessage = errMessage.replace(iter, 1, std::to_string(ERROR_PARAM_CHECK_ERROR)); + } + errMessage += ERR_MSG_ENUM_EROOR; + iter = errMessage.find("$"); + if (iter != std::string::npos) { + errMessage = errMessage.replace(iter, 1, parameter); + iter = errMessage.find("$"); + if (iter != std::string::npos) { + errMessage = errMessage.replace(iter, 1, enumClass); + } + } + return CreateError(env, ERROR_PARAM_CHECK_ERROR, errMessage); +} + +void BusinessErrorAni::ThrowError(ani_env *env, ani_object err) +{ + if (err == nullptr) { + APP_LOGE("err is nullptr"); + return; + } + env->ThrowError(static_cast(err)); +} +} // namespace AppExecFwk +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/ani/common/business_error_ani.h b/interfaces/kits/ani/common/business_error_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..7816a578c0dde2022e0ede2131d2fb229662aaef --- /dev/null +++ b/interfaces/kits/ani/common/business_error_ani.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 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. + */ + +#ifndef BUNDLE_FRAMEWORK_INTERFACES_KITS_ANI_BUSINESS_ERROR_H +#define BUNDLE_FRAMEWORK_INTERFACES_KITS_ANI_BUSINESS_ERROR_H + +#include +#include "appexecfwk_errors.h" +#include "bundle_errors.h" + +namespace OHOS { +namespace AppExecFwk { +class BusinessErrorAni { +public: + static ani_object WrapError(ani_env *env, const std::string &msg); + static ani_object CreateError(ani_env *env, int32_t code, const std::string &msg); + static ani_object CreateCommonError( + ani_env *env, int32_t err, const std::string &functionName = "", const std::string &permissionName = ""); + static ani_object CreateEnumError(ani_env *env, const std::string ¶meter, const std::string &enumClass); + static void ThrowTooFewParametersError(ani_env *env, int32_t err); + static void ThrowParameterTypeError(ani_env *env, int32_t err, + const std::string ¶meter, const std::string &type); + static void ThrowEnumError(ani_env *env, const std::string ¶meter, const std::string &type); + static void ThrowError(ani_env *env, int32_t err, const std::string &msg = ""); +private: + static void ThrowError(ani_env *env, ani_object err); +}; +} // namespace AppExecFwk +} // namespace OHOS +#endif \ No newline at end of file diff --git a/interfaces/kits/ani/common/common_fun_ani.cpp b/interfaces/kits/ani/common/common_fun_ani.cpp new file mode 100644 index 0000000000000000000000000000000000000000..62e2a274f0bc18194e83e3465509cb8510fca82c --- /dev/null +++ b/interfaces/kits/ani/common/common_fun_ani.cpp @@ -0,0 +1,1625 @@ +/* + * Copyright (c) 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 +#include + +#include "app_log_wrapper.h" +#include "common_fun_ani.h" + +namespace OHOS { +namespace AppExecFwk { +namespace { +constexpr const char* CLASSNAME_ABILITYINFO = "LbundleManager/AbilityInfoInner/AbilityInfoInner;"; +constexpr const char* CLASSNAME_EXTENSIONABILITYINFO = + "LbundleManager/ExtensionAbilityInfoInner/ExtensionAbilityInfoInner;"; +constexpr const char* CLASSNAME_WINDOWSIZE = "LbundleManager/AbilityInfoInner/WindowSizeInner;"; +constexpr const char* CLASSNAME_APPLICATIONINFO = "LbundleManager/ApplicationInfoInner/ApplicationInfoInner;"; +constexpr const char* CLASSNAME_MODULEMETADATA = "LbundleManager/ApplicationInfoInner/ModuleMetadataInner;"; +constexpr const char* CLASSNAME_MULTIAPPMODE = "LbundleManager/ApplicationInfoInner/MultiAppModeInner;"; +constexpr const char* CLASSNAME_BUNDLEINFO = "LbundleManager/BundleInfoInner/BundleInfoInner;"; +constexpr const char* CLASSNAME_PERMISSION = "LbundleManager/BundleInfoInner/ReqPermissionDetailInner;"; +constexpr const char* CLASSNAME_USEDSCENE = "LbundleManager/BundleInfoInner/UsedSceneInner;"; +constexpr const char* CLASSNAME_SIGNATUREINFO = "LbundleManager/BundleInfoInner/SignatureInfoInner;"; +constexpr const char* CLASSNAME_METADATA = "LbundleManager/MetadataInner/MetadataInner;"; +constexpr const char* CLASSNAME_RESOURCE = "Lglobal/resourceInner/ResourceInner;"; +constexpr const char* CLASSNAME_ROUTERITEM = "LbundleManager/HapModuleInfoInner/RouterItemInner;"; +constexpr const char* CLASSNAME_PRELOADITEM = "LbundleManager/HapModuleInfoInner/PreloadItemInner;"; +constexpr const char* CLASSNAME_DEPENDENCY = "LbundleManager/HapModuleInfoInner/DependencyInner;"; +constexpr const char* CLASSNAME_HAPMODULEINFO = "LbundleManager/HapModuleInfoInner/HapModuleInfoInner;"; +constexpr const char* CLASSNAME_DATAITEM = "LbundleManager/HapModuleInfoInner/DataItemInner;"; +constexpr const char* CLASSNAME_ELEMENTNAME = "LbundleManager/ElementNameInner/ElementNameInner;"; +constexpr const char* CLASSNAME_CUSTOMIZEDATA = "LbundleManager/customizeDataInner/CustomizeDataInner;"; +constexpr const char* CLASSNAME_SKILL = "LbundleManager/SkillInner/SkillInner;"; +constexpr const char* CLASSNAME_SKILLURI = "LbundleManager/SkillInner/SkillUriInner;"; +constexpr const char* CLASSNAME_BUNDLERESINFO = "LbundleManager/BundleResourceInfoInner/BundleResourceInfoInner;"; +constexpr const char* CLASSNAME_SHORTCUTINFO = "LbundleManager/ShortcutInfo/ShortcutInfoInner;"; +constexpr const char* CLASSNAME_SHORTCUTWANT = "LbundleManager/ShortcutInfo/ShortcutWantInner;"; +constexpr const char* CLASSNAME_SHORTCUT_PARAMETERITEM = "LbundleManager/ShortcutInfo/ParameterItemInner;"; + +constexpr const char* PROPERTYNAME_NAME = "name"; +constexpr const char* PROPERTYNAME_VENDOR = "vendor"; +constexpr const char* PROPERTYNAME_VERSIONCODE = "versionCode"; +constexpr const char* PROPERTYNAME_VERSIONNAME = "versionName"; +constexpr const char* PROPERTYNAME_MINCOMPATIBLEVERSIONCODE = "minCompatibleVersionCode"; +constexpr const char* PROPERTYNAME_TARGETVERSION = "targetVersion"; +constexpr const char* PROPERTYNAME_APPINFO = "appInfo"; +constexpr const char* PROPERTYNAME_HAPMODULESINFO = "hapModulesInfo"; +constexpr const char* PROPERTYNAME_REQPERMISSIONDETAILS = "reqPermissionDetails"; +constexpr const char* PROPERTYNAME_PERMISSIONGRANTSTATES = "permissionGrantStates"; +constexpr const char* PROPERTYNAME_SIGNATUREINFO = "signatureInfo"; +constexpr const char* PROPERTYNAME_INSTALLTIME = "installTime"; +constexpr const char* PROPERTYNAME_UPDATETIME = "updateTime"; +constexpr const char* PROPERTYNAME_FIRSTINSTALLTIME = "firstInstallTime"; +constexpr const char* PROPERTYNAME_ROUTERMAP = "routerMap"; +constexpr const char* PROPERTYNAME_APPINDEX = "appIndex"; +constexpr const char* PROPERTYNAME_KEY = "key"; +constexpr const char* PROPERTYNAME_VALUE = "value"; +constexpr const char* PROPERTYNAME_RESOURCE = "resource"; +constexpr const char* PROPERTYNAME_VALUEID = "valueId"; +constexpr const char* PROPERTYNAME_MAXCOUNT = "maxCount"; +constexpr const char* PROPERTYNAME_MULTIAPPMODETYPE = "multiAppModeType"; +constexpr const char* PROPERTYNAME_MODULENAME = "moduleName"; +constexpr const char* PROPERTYNAME_METADATA = "metadata"; +constexpr const char* PROPERTYNAME_DESCRIPTION = "description"; +constexpr const char* PROPERTYNAME_DESCRIPTIONID = "descriptionId"; +constexpr const char* PROPERTYNAME_ENABLED = "enabled"; +constexpr const char* PROPERTYNAME_LABEL = "label"; +constexpr const char* PROPERTYNAME_LABELID = "labelId"; +constexpr const char* PROPERTYNAME_ICON = "icon"; +constexpr const char* PROPERTYNAME_ICONID = "iconId"; +constexpr const char* PROPERTYNAME_PROCESS = "process"; +constexpr const char* PROPERTYNAME_PERMISSIONS = "permissions"; +constexpr const char* PROPERTYNAME_CODEPATH = "codePath"; +constexpr const char* PROPERTYNAME_METADATAARRAY = "metadataArray"; +constexpr const char* PROPERTYNAME_REMOVABLE = "removable"; +constexpr const char* PROPERTYNAME_ACCESSTOKENID = "accessTokenId"; +constexpr const char* PROPERTYNAME_UID = "uid"; +constexpr const char* PROPERTYNAME_ICONRESOURCE = "iconResource"; +constexpr const char* PROPERTYNAME_LABELRESOURCE = "labelResource"; +constexpr const char* PROPERTYNAME_DESCRIPTIONRESOURCE = "descriptionResource"; +constexpr const char* PROPERTYNAME_APPDISTRIBUTIONTYPE = "appDistributionType"; +constexpr const char* PROPERTYNAME_APPPROVISIONTYPE = "appProvisionType"; +constexpr const char* PROPERTYNAME_SYSTEMAPP = "systemApp"; +constexpr const char* PROPERTYNAME_BUNDLETYPE = "bundleType"; +constexpr const char* PROPERTYNAME_DEBUG = "debug"; +constexpr const char* PROPERTYNAME_DATAUNCLEARABLE = "dataUnclearable"; +constexpr const char* PROPERTYNAME_NATIVELIBRARYPATH = "nativeLibraryPath"; +constexpr const char* PROPERTYNAME_MULTIAPPMODE = "multiAppMode"; +constexpr const char* PROPERTYNAME_INSTALLSOURCE = "installSource"; +constexpr const char* PROPERTYNAME_RELEASETYPE = "releaseType"; +constexpr const char* PROPERTYNAME_CLOUDFILESYNCENABLED = "cloudFileSyncEnabled"; +constexpr const char* PROPERTYNAME_FLAGS = "flags"; +constexpr const char* PROPERTYNAME_BUNDLENAME = "bundleName"; +constexpr const char* PROPERTYNAME_EXPORTED = "exported"; +constexpr const char* PROPERTYNAME_TYPE = "type"; +constexpr const char* PROPERTYNAME_ORIENTATION = "orientation"; +constexpr const char* PROPERTYNAME_LAUNCHTYPE = "launchType"; +constexpr const char* PROPERTYNAME_READPERMISSION = "readPermission"; +constexpr const char* PROPERTYNAME_WRITEPERMISSION = "writePermission"; +constexpr const char* PROPERTYNAME_URI = "uri"; +constexpr const char* PROPERTYNAME_DEVICETYPES = "deviceTypes"; +constexpr const char* PROPERTYNAME_APPLICATIONINFO = "applicationInfo"; +constexpr const char* PROPERTYNAME_SUPPORTWINDOWMODES = "supportWindowModes"; +constexpr const char* PROPERTYNAME_WINDOWSIZE = "windowSize"; +constexpr const char* PROPERTYNAME_EXCLUDEFROMDOCK = "excludeFromDock"; +constexpr const char* PROPERTYNAME_SKILLS = "skills"; +constexpr const char* PROPERTYNAME_ORIENTATIONID = "orientationId"; +constexpr const char* PROPERTYNAME_MAXWINDOWRATIO = "maxWindowRatio"; +constexpr const char* PROPERTYNAME_MINWINDOWRATIO = "minWindowRatio"; +constexpr const char* PROPERTYNAME_MAXWINDOWWIDTH = "maxWindowWidth"; +constexpr const char* PROPERTYNAME_MINWINDOWWIDTH = "minWindowWidth"; +constexpr const char* PROPERTYNAME_MAXWINDOWHEIGHT = "maxWindowHeight"; +constexpr const char* PROPERTYNAME_MINWINDOWHEIGHT = "minWindowHeight"; +constexpr const char* PROPERTYNAME_EXTENSIONABILITYTYPE = "extensionAbilityType"; +constexpr const char* PROPERTYNAME_EXTENSIONABILITYTYPENAME = "extensionAbilityTypeName"; +constexpr const char* PROPERTYNAME_ID = "id"; +constexpr const char* PROPERTYNAME_APPID = "appId"; +constexpr const char* PROPERTYNAME_FINGERPRINT = "fingerprint"; +constexpr const char* PROPERTYNAME_APPIDENTIFIER = "appIdentifier"; +constexpr const char* PROPERTYNAME_CERTIFICATE = "certificate"; +constexpr const char* PROPERTYNAME_PAGESOURCEFILE = "pageSourceFile"; +constexpr const char* PROPERTYNAME_BUILDFUNCTION = "buildFunction"; +constexpr const char* PROPERTYNAME_CUSTOMDATA = "customData"; +constexpr const char* PROPERTYNAME_DATA = "data"; +constexpr const char* PROPERTYNAME_REASON = "reason"; +constexpr const char* PROPERTYNAME_REASONID = "reasonId"; +constexpr const char* PROPERTYNAME_USEDSCENE = "usedScene"; +constexpr const char* PROPERTYNAME_WHEN = "when"; +constexpr const char* PROPERTYNAME_ABILITIES = "abilities"; +constexpr const char* PROPERTYNAME_MAINELEMENTNAME = "mainElementName"; +constexpr const char* PROPERTYNAME_ABILITIESINFO = "abilitiesInfo"; +constexpr const char* PROPERTYNAME_EXTENSIONABILITIESINFO = "extensionAbilitiesInfo"; +constexpr const char* PROPERTYNAME_INSTALLATIONFREE = "installationFree"; +constexpr const char* PROPERTYNAME_HASHVALUE = "hashValue"; +constexpr const char* PROPERTYNAME_DEPENDENCIES = "dependencies"; +constexpr const char* PROPERTYNAME_PRELOADS = "preloads"; +constexpr const char* PROPERTYNAME_FILECONTEXTMENUCONFIG = "fileContextMenuConfig"; +constexpr const char* PROPERTYNAME_DEVICEID = "deviceId"; +constexpr const char* PROPERTYNAME_ABILITYNAME = "abilityName"; +constexpr const char* PROPERTYNAME_SHORTNAME = "shortName"; +constexpr const char* PROPERTYNAME_EXTRA = "extra"; +constexpr const char* PROPERTYNAME_SCHEME = "scheme"; +constexpr const char* PROPERTYNAME_HOST = "host"; +constexpr const char* PROPERTYNAME_PORT = "port"; +constexpr const char* PROPERTYNAME_PATH = "path"; +constexpr const char* PROPERTYNAME_PATHSTARTWITH = "pathStartWith"; +constexpr const char* PROPERTYNAME_PATHREGEX = "pathRegex"; +constexpr const char* PROPERTYNAME_UTD = "utd"; +constexpr const char* PROPERTYNAME_MAXFILESUPPORTED = "maxFileSupported"; +constexpr const char* PROPERTYNAME_LINKFEATURE = "linkFeature"; +constexpr const char* PROPERTYNAME_ACTIONS = "actions"; +constexpr const char* PROPERTYNAME_ENTITIES = "entities"; +constexpr const char* PROPERTYNAME_URIS = "uris"; +constexpr const char* PROPERTYNAME_DOMAINVERIFY = "domainVerify"; +constexpr const char* PROPERTYNAME_HOSTABILITY = "hostAbility"; +constexpr const char* PROPERTYNAME_WANTS = "wants"; +constexpr const char* PROPERTYNAME_SOURCETYPE = "sourceType"; +constexpr const char* PROPERTYNAME_TARGETBUNDLE = "targetBundle"; +constexpr const char* PROPERTYNAME_TARGETMODULE = "targetModule"; +constexpr const char* PROPERTYNAME_TARGETABILITY = "targetAbility"; +constexpr const char* PROPERTYNAME_PARAMETERS = "parameters"; +constexpr const char* PROPERTYNAME_HASHPARAMS = "hashParams"; +constexpr const char* PROPERTYNAME_PGOFILEPATH = "pgoFilePath"; +constexpr const char* PROPERTYNAME_PGOPARAMS = "pgoParams"; +constexpr const char* PROPERTYNAME_USERID = "userId"; +constexpr const char* PROPERTYNAME_SPECIFIEDDISTRIBUTIONTYPE = "specifiedDistributionType"; +constexpr const char* PROPERTYNAME_ISKEEPDATA = "isKeepData"; +constexpr const char* PROPERTYNAME_INSTALLFLAG = "installFlag"; +constexpr const char* PROPERTYNAME_CROWDTESTDEADLINE = "crowdtestDeadline"; +constexpr const char* PROPERTYNAME_SHAREDBUNDLEDIRPATHS = "sharedBundleDirPaths"; +constexpr const char* PROPERTYNAME_ADDITIONALINFO = "additionalInfo"; + +constexpr const char* PATH_PREFIX = "/data/app/el1/bundle/public"; +constexpr const char* CODE_PATH_PREFIX = "/data/storage/el1/bundle/"; +} // namespace + +std::string CommonFunAni::AniStrToString(ani_env* env, ani_string aniStr) +{ + if (env == nullptr || aniStr == nullptr) { + return ""; + } + + ani_size strSize = 0; + ani_status status = env->String_GetUTF8Size(aniStr, &strSize); + if (status != ANI_OK) { + APP_LOGE("String_GetUTF8Size failed %{public}d", status); + return ""; + } + + std::string buffer; + buffer.resize(strSize + 1); + ani_size retSize; + status = env->String_GetUTF8(aniStr, buffer.data(), buffer.size(), &retSize); + if (status != ANI_OK || retSize < 0) { + APP_LOGE("String_GetUTF8SubString failed %{public}d", status); + return ""; + } + + buffer.resize(retSize); + return buffer; +} + +ani_class CommonFunAni::CreateClassByName(ani_env* env, const std::string& className) +{ + RETURN_NULL_IF_NULL(env); + + ani_class cls = nullptr; + ani_status status = env->FindClass(className.c_str(), &cls); + if (status != ANI_OK) { + APP_LOGE("FindClass failed %{public}d", status); + return nullptr; + } + return cls; +} + +ani_object CommonFunAni::CreateNewObjectByClass(ani_env* env, ani_class cls) +{ + RETURN_NULL_IF_NULL(env); + + ani_method method = nullptr; + ani_status status = env->Class_FindMethod(cls, "", ":V", &method); + if (status != ANI_OK) { + APP_LOGE("Class_FindMethod failed %{public}d", status); + return nullptr; + } + + ani_object object = nullptr; + status = env->Object_New(cls, method, &object); + if (status != ANI_OK) { + APP_LOGE("Object_New failed %{public}d", status); + return nullptr; + } + return object; +} + +ani_object CommonFunAni::ConvertBundleInfo(ani_env* env, const BundleInfo& bundleInfo, int32_t flags) +{ + RETURN_NULL_IF_NULL(env); + + ani_class cls = CreateClassByName(env, CLASSNAME_BUNDLEINFO); + RETURN_NULL_IF_NULL(cls); + + ani_object object = CreateNewObjectByClass(env, cls); + RETURN_NULL_IF_NULL(object); + + ani_string string = nullptr; + + // name: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, bundleInfo.name, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_NAME, string)); + + // vendor: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, bundleInfo.vendor, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_VENDOR, string)); + + // versionCode: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_VERSIONCODE, bundleInfo.versionCode)); + + // versionName: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, bundleInfo.versionName, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_VERSIONNAME, string)); + + // minCompatibleVersionCode: number + RETURN_NULL_IF_FALSE( + CallSetter(env, cls, object, PROPERTYNAME_MINCOMPATIBLEVERSIONCODE, bundleInfo.minCompatibleVersionCode)); + + // targetVersion: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_TARGETVERSION, bundleInfo.targetVersion)); + + // appInfo: ApplicationInfo + if ((static_cast(flags) & static_cast(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION)) == + static_cast(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_APPLICATION)) { + ani_object aObject = ConvertApplicationInfo(env, bundleInfo.applicationInfo); + RETURN_NULL_IF_NULL(aObject); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_APPINFO, aObject)); + } else { + RETURN_NULL_IF_FALSE(CallSetterNull(env, cls, object, PROPERTYNAME_APPINFO)); + } + + // hapModulesInfo: Array + ani_object aHapModuleInfosObject = ConvertAniArray(env, bundleInfo.hapModuleInfos, ConvertHapModuleInfo); + RETURN_NULL_IF_NULL(aHapModuleInfosObject); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_HAPMODULESINFO, aHapModuleInfosObject)); + + // reqPermissionDetails: Array + ani_object aPermissionArrayObject = ConvertAniArray(env, bundleInfo.reqPermissionDetails, ConvertRequestPermission); + RETURN_NULL_IF_NULL(aPermissionArrayObject); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_REQPERMISSIONDETAILS, aPermissionArrayObject)); + + // permissionGrantStates: Array + ani_object aPermissionGrantStates = ConvertAniArrayEnum( + env, bundleInfo.reqPermissionStates, EnumUtils::EnumNativeToETS_BundleManager_PermissionGrantState); + RETURN_NULL_IF_NULL(aPermissionGrantStates); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_PERMISSIONGRANTSTATES, aPermissionGrantStates)); + + // signatureInfo: SignatureInfo + if ((static_cast(flags) & static_cast(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_SIGNATURE_INFO)) == + static_cast(GetBundleInfoFlag::GET_BUNDLE_INFO_WITH_SIGNATURE_INFO)) { + ani_object aniSignatureInfoObj = ConvertSignatureInfo(env, bundleInfo.signatureInfo); + RETURN_NULL_IF_NULL(aniSignatureInfoObj); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_SIGNATUREINFO, aniSignatureInfoObj)); + } else { + RETURN_NULL_IF_FALSE(CallSetterNull(env, cls, object, PROPERTYNAME_SIGNATUREINFO)); + } + + // installTime: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_INSTALLTIME, bundleInfo.installTime)); + + // updateTime: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_UPDATETIME, bundleInfo.updateTime)); + + // routerMap: Array + ani_object aRouterMapObject = ConvertAniArray(env, bundleInfo.routerArray, ConvertRouterItem); + RETURN_NULL_IF_NULL(aRouterMapObject); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_ROUTERMAP, aRouterMapObject)); + + // appIndex: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_APPINDEX, bundleInfo.appIndex)); + + // firstInstallTime?: number + RETURN_NULL_IF_FALSE( + CallSetterOptional(env, cls, object, PROPERTYNAME_FIRSTINSTALLTIME, bundleInfo.firstInstallTime)); + + return object; +} + +ani_object CommonFunAni::ConvertMetadata(ani_env* env, const Metadata& metadata) +{ + RETURN_NULL_IF_NULL(env); + + ani_class cls = CreateClassByName(env, CLASSNAME_METADATA); + RETURN_NULL_IF_NULL(cls); + + ani_object object = CreateNewObjectByClass(env, cls); + RETURN_NULL_IF_NULL(object); + + ani_string string = nullptr; + + // name: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, metadata.name, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_NAME, string)); + + // value: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, metadata.value, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_VALUE, string)); + + // resource: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, metadata.resource, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_RESOURCE, string)); + + // valueId?: number + RETURN_NULL_IF_FALSE(CallSetterOptional(env, cls, object, PROPERTYNAME_VALUEID, metadata.valueId)); + + return object; +} + +ani_object CommonFunAni::ConvertMultiAppMode(ani_env* env, const MultiAppModeData& multiAppMode) +{ + RETURN_NULL_IF_NULL(env); + + ani_class cls = CreateClassByName(env, CLASSNAME_MULTIAPPMODE); + RETURN_NULL_IF_NULL(cls); + + ani_object object = CreateNewObjectByClass(env, cls); + RETURN_NULL_IF_NULL(object); + + // maxCount: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_MAXCOUNT, multiAppMode.maxCount)); + + // multiAppModeType: bundleManager.MultiAppModeType + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_MULTIAPPMODETYPE, + EnumUtils::EnumNativeToETS_BundleManager_MultiAppModeType( + env, static_cast(multiAppMode.multiAppModeType)))); + + return object; +} + +ani_object CommonFunAni::ConvertModuleMetaInfosItem( + ani_env* env, const std::pair>& item) +{ + RETURN_NULL_IF_NULL(env); + + ani_class cls = CreateClassByName(env, CLASSNAME_MODULEMETADATA); + RETURN_NULL_IF_NULL(cls); + + ani_object object = CreateNewObjectByClass(env, cls); + RETURN_NULL_IF_NULL(object); + + ani_string string = nullptr; + + // moduleName: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, item.first, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_MODULENAME, string)); + + // metadata: Array + ani_object aMetadataObject = ConvertAniArray(env, item.second, ConvertMetadata); + RETURN_NULL_IF_NULL(aMetadataObject); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_METADATA, aMetadataObject)); + + return object; +} + +ani_object CommonFunAni::ConvertApplicationInfo(ani_env* env, const ApplicationInfo& appInfo) +{ + RETURN_NULL_IF_NULL(env); + + ani_class cls = CreateClassByName(env, CLASSNAME_APPLICATIONINFO); + RETURN_NULL_IF_NULL(cls); + + ani_object object = CreateNewObjectByClass(env, cls); + RETURN_NULL_IF_NULL(object); + + ani_string string = nullptr; + + // name: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, appInfo.name, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_NAME, string)); + + // description: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, appInfo.description, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_DESCRIPTION, string)); + + // descriptionId: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_DESCRIPTIONID, appInfo.descriptionId)); + + // enabled: boolean + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_ENABLED, BoolToAniBoolean(appInfo.enabled))); + + // label: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, appInfo.label, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_LABEL, string)); + + // labelId: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_LABELID, appInfo.labelId)); + + // icon: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, appInfo.iconPath, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_ICON, string)); + + // iconId: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_ICONID, appInfo.iconId)); + + // process: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, appInfo.process, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_PROCESS, string)); + + // permissions: Array + ani_ref aPermissions = ConvertAniArrayString(env, appInfo.permissions); + RETURN_NULL_IF_NULL(aPermissions); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_PERMISSIONS, aPermissions)); + + // codePath: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, appInfo.codePath, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_CODEPATH, string)); + + // metadataArray: Array + ani_object aMetadataArrayObject = ConvertAniArray(env, appInfo.metadata, ConvertModuleMetaInfosItem); + RETURN_NULL_IF_NULL(aMetadataArrayObject); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_METADATAARRAY, aMetadataArrayObject)); + + // removable: boolean + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_REMOVABLE, BoolToAniBoolean(appInfo.removable))); + + // accessTokenId: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_ACCESSTOKENID, appInfo.accessTokenId)); + + // uid: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_UID, appInfo.uid)); + + // iconResource: Resource + ani_object aIconResource = ConvertResource(env, appInfo.iconResource); + RETURN_NULL_IF_NULL(aIconResource); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_ICONRESOURCE, aIconResource)); + + // labelResource: Resource + ani_object aLabelResource = ConvertResource(env, appInfo.labelResource); + RETURN_NULL_IF_NULL(aLabelResource); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_LABELRESOURCE, aLabelResource)); + + // descriptionResource: Resource + ani_object aDescriptionResource = ConvertResource(env, appInfo.descriptionResource); + RETURN_NULL_IF_NULL(aDescriptionResource); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_DESCRIPTIONRESOURCE, aDescriptionResource)); + + // appDistributionType: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, appInfo.appDistributionType, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_APPDISTRIBUTIONTYPE, string)); + + // appProvisionType: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, appInfo.appProvisionType, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_APPPROVISIONTYPE, string)); + + // systemApp: boolean + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_SYSTEMAPP, BoolToAniBoolean(appInfo.isSystemApp))); + + // bundleType: bundleManager.BundleType + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_BUNDLETYPE, + EnumUtils::EnumNativeToETS_BundleManager_BundleType(env, static_cast(appInfo.bundleType)))); + + // debug: boolean + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_DEBUG, BoolToAniBoolean(appInfo.debug))); + + // dataUnclearable: boolean + RETURN_NULL_IF_FALSE( + CallSetter(env, cls, object, PROPERTYNAME_DATAUNCLEARABLE, BoolToAniBoolean(!appInfo.userDataClearable))); + + // nativeLibraryPath: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, appInfo.nativeLibraryPath, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_NATIVELIBRARYPATH, string)); + + // multiAppMode: MultiAppMode + ani_object aniMultiAppModeObj = ConvertMultiAppMode(env, appInfo.multiAppMode); + RETURN_NULL_IF_NULL(aniMultiAppModeObj); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_MULTIAPPMODE, aniMultiAppModeObj)); + + // appIndex: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_APPINDEX, appInfo.appIndex)); + + // installSource: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, appInfo.installSource, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_INSTALLSOURCE, string)); + + // releaseType: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, appInfo.apiReleaseType, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_RELEASETYPE, string)); + + // cloudFileSyncEnabled: boolean + RETURN_NULL_IF_FALSE(CallSetter( + env, cls, object, PROPERTYNAME_CLOUDFILESYNCENABLED, BoolToAniBoolean(appInfo.cloudFileSyncEnabled))); + + // flags?: number + RETURN_NULL_IF_FALSE(CallSetterOptional(env, cls, object, PROPERTYNAME_FLAGS, appInfo.flags)); + + return object; +} + +ani_object CommonFunAni::ConvertAbilityInfo(ani_env* env, const AbilityInfo& abilityInfo) +{ + RETURN_NULL_IF_NULL(env); + + ani_class cls = CreateClassByName(env, CLASSNAME_ABILITYINFO); + RETURN_NULL_IF_NULL(cls); + + ani_object object = CreateNewObjectByClass(env, cls); + RETURN_NULL_IF_NULL(object); + + ani_string string = nullptr; + + // bundleName: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, abilityInfo.bundleName, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_BUNDLENAME, string)); + + // moduleName: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, abilityInfo.moduleName, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_MODULENAME, string)); + + // name: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, abilityInfo.name, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_NAME, string)); + + // label: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, abilityInfo.label, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_LABEL, string)); + + // labelId: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_LABELID, abilityInfo.labelId)); + + // description: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, abilityInfo.description, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_DESCRIPTION, string)); + + // descriptionId: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_DESCRIPTIONID, abilityInfo.descriptionId)); + + // icon: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, abilityInfo.iconPath, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_ICON, string)); + + // iconId: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_ICONID, abilityInfo.iconId)); + + // process: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, abilityInfo.process, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_PROCESS, string)); + + // exported: boolean + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_EXPORTED, BoolToAniBoolean(abilityInfo.visible))); + + // orientation: bundleManager.DisplayOrientation + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_ORIENTATION, + EnumUtils::EnumNativeToETS_BundleManager_DisplayOrientation( + env, static_cast(abilityInfo.orientation)))); + + // launchType: bundleManager.LaunchType + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_LAUNCHTYPE, + EnumUtils::EnumNativeToETS_BundleManager_LaunchType(env, static_cast(abilityInfo.launchMode)))); + + // permissions: Array + ani_ref aPermissions = ConvertAniArrayString(env, abilityInfo.permissions); + RETURN_NULL_IF_NULL(aPermissions); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_PERMISSIONS, aPermissions)); + + // deviceTypes: Array + ani_ref aDeviceTypes = ConvertAniArrayString(env, abilityInfo.deviceTypes); + RETURN_NULL_IF_NULL(aDeviceTypes); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_DEVICETYPES, aDeviceTypes)); + + // applicationInfo: ApplicationInfo + ani_object aObject = ConvertApplicationInfo(env, abilityInfo.applicationInfo); + RETURN_NULL_IF_NULL(aObject); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_APPLICATIONINFO, aObject)); + + // metadata: Array + ani_object aMetadataObject = ConvertAniArray(env, abilityInfo.metadata, ConvertMetadata); + RETURN_NULL_IF_NULL(aMetadataObject); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_METADATA, aMetadataObject)); + + // enabled: boolean + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_ENABLED, BoolToAniBoolean(abilityInfo.enabled))); + + // supportWindowModes: Array + ani_object aSupportWindowModes = + ConvertAniArrayEnum(env, abilityInfo.windowModes, EnumUtils::EnumNativeToETS_BundleManager_SupportWindowMode); + RETURN_NULL_IF_NULL(aSupportWindowModes); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_SUPPORTWINDOWMODES, aSupportWindowModes)); + + // windowSize: WindowSize + ani_object aniWindowSizeObj = ConvertWindowSize(env, abilityInfo); + RETURN_NULL_IF_NULL(aniWindowSizeObj); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_WINDOWSIZE, aniWindowSizeObj)); + + // excludeFromDock: boolean + RETURN_NULL_IF_FALSE( + CallSetter(env, cls, object, PROPERTYNAME_EXCLUDEFROMDOCK, BoolToAniBoolean(abilityInfo.excludeFromDock))); + + // skills: Array + ani_object aSkillsObject = ConvertAniArray(env, abilityInfo.skills, ConvertAbilitySkill); + RETURN_NULL_IF_NULL(aSkillsObject); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_SKILLS, aSkillsObject)); + + // appIndex: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_APPINDEX, abilityInfo.appIndex)); + + // orientationId: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_ORIENTATIONID, abilityInfo.orientationId)); + + return object; +} + +ani_object CommonFunAni::ConvertWindowSize(ani_env* env, const AbilityInfo& abilityInfo) +{ + RETURN_NULL_IF_NULL(env); + + ani_class cls = CreateClassByName(env, CLASSNAME_WINDOWSIZE); + RETURN_NULL_IF_NULL(cls); + + ani_object object = CreateNewObjectByClass(env, cls); + RETURN_NULL_IF_NULL(object); + + // maxWindowRatio: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_MAXWINDOWRATIO, abilityInfo.maxWindowRatio)); + + // minWindowRatio: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_MINWINDOWRATIO, abilityInfo.minWindowRatio)); + + // maxWindowWidth: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_MAXWINDOWWIDTH, abilityInfo.maxWindowWidth)); + + // minWindowWidth: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_MINWINDOWWIDTH, abilityInfo.minWindowWidth)); + + // maxWindowHeight: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_MAXWINDOWHEIGHT, abilityInfo.maxWindowHeight)); + + // minWindowHeight: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_MINWINDOWHEIGHT, abilityInfo.minWindowHeight)); + + return object; +} + +ani_object CommonFunAni::ConvertExtensionInfo(ani_env* env, const ExtensionAbilityInfo& extensionInfo) +{ + RETURN_NULL_IF_NULL(env); + + ani_class cls = CreateClassByName(env, CLASSNAME_EXTENSIONABILITYINFO); + RETURN_NULL_IF_NULL(cls); + + ani_object object = CreateNewObjectByClass(env, cls); + RETURN_NULL_IF_NULL(object); + + ani_string string = nullptr; + + // bundleName: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, extensionInfo.bundleName, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_BUNDLENAME, string)); + + // moduleName: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, extensionInfo.moduleName, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_MODULENAME, string)); + + // name: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, extensionInfo.name, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_NAME, string)); + + // labelId: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_LABELID, extensionInfo.labelId)); + + // descriptionId: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_DESCRIPTIONID, extensionInfo.descriptionId)); + + // iconId: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_ICONID, extensionInfo.iconId)); + + // exported: boolean + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_EXPORTED, extensionInfo.visible)); + + // extensionAbilityType: bundleManager.ExtensionAbilityType + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_EXTENSIONABILITYTYPE, + EnumUtils::EnumNativeToETS_BundleManager_ExtensionAbilityType(env, static_cast(extensionInfo.type)))); + + // extensionAbilityTypeName: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, extensionInfo.extensionTypeName, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_EXTENSIONABILITYTYPENAME, string)); + + // permissions: Array + ani_ref aPermissions = ConvertAniArrayString(env, extensionInfo.permissions); + RETURN_NULL_IF_NULL(aPermissions); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_PERMISSIONS, aPermissions)); + + // applicationInfo: ApplicationInfo + ani_object aObject = ConvertApplicationInfo(env, extensionInfo.applicationInfo); + RETURN_NULL_IF_NULL(aObject); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_APPLICATIONINFO, aObject)); + + // metadata: Array + ani_object aMetadataObject = ConvertAniArray(env, extensionInfo.metadata, ConvertMetadata); + RETURN_NULL_IF_NULL(aMetadataObject); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_METADATA, aMetadataObject)); + + // enabled: boolean + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_ENABLED, extensionInfo.enabled)); + + // readPermission: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, extensionInfo.readPermission, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_READPERMISSION, string)); + + // writePermission: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, extensionInfo.writePermission, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_WRITEPERMISSION, string)); + + // skills: Array + ani_object aSkillsObject = ConvertAniArray(env, extensionInfo.skills, ConvertExtensionAbilitySkill); + RETURN_NULL_IF_NULL(aSkillsObject); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_SKILLS, aSkillsObject)); + + // appIndex: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_APPINDEX, extensionInfo.appIndex)); + + return object; +} + +ani_object CommonFunAni::ConvertResource(ani_env* env, const Resource& resource) +{ + RETURN_NULL_IF_NULL(env); + + ani_class cls = CreateClassByName(env, CLASSNAME_RESOURCE); + RETURN_NULL_IF_NULL(cls); + + ani_object object = CreateNewObjectByClass(env, cls); + RETURN_NULL_IF_NULL(object); + + ani_string string = nullptr; + + // bundleName: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, resource.bundleName, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_BUNDLENAME, string)); + + // moduleName: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, resource.moduleName, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_MODULENAME, string)); + + // id: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_ID, resource.id)); + + return object; +} + +ani_object CommonFunAni::ConvertSignatureInfo(ani_env* env, const SignatureInfo& signatureInfo) +{ + RETURN_NULL_IF_NULL(env); + + ani_class cls = CreateClassByName(env, CLASSNAME_SIGNATUREINFO); + RETURN_NULL_IF_NULL(cls); + + ani_object object = CreateNewObjectByClass(env, cls); + RETURN_NULL_IF_NULL(object); + + ani_string string = nullptr; + + // appId: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, signatureInfo.appId, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_APPID, string)); + + // fingerprint: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, signatureInfo.fingerprint, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_FINGERPRINT, string)); + + // appIdentifier: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, signatureInfo.appIdentifier, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_APPIDENTIFIER, string)); + + // certificate?: string + if (StringToAniStr(env, signatureInfo.certificate, string)) { + RETURN_NULL_IF_FALSE(CallSetterOptional(env, cls, object, PROPERTYNAME_CERTIFICATE, string)); + } + + return object; +} + +ani_object CommonFunAni::ConvertKeyValuePair( + ani_env* env, const std::pair& item, const char* className) +{ + RETURN_NULL_IF_NULL(env); + + ani_class cls = CreateClassByName(env, CLASSNAME_DATAITEM); + RETURN_NULL_IF_NULL(cls); + + ani_object object = CreateNewObjectByClass(env, cls); + RETURN_NULL_IF_NULL(object); + + ani_string string = nullptr; + + // key: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, item.first, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_KEY, string)); + + // value: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, item.second, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_VALUE, string)); + + return object; +} + +inline ani_object CommonFunAni::ConvertDataItem(ani_env* env, const std::pair& item) +{ + return ConvertKeyValuePair(env, item, CLASSNAME_DATAITEM); +} + +ani_object CommonFunAni::ConvertRouterItem(ani_env* env, const RouterItem& routerItem) +{ + RETURN_NULL_IF_NULL(env); + + ani_class cls = CreateClassByName(env, CLASSNAME_ROUTERITEM); + RETURN_NULL_IF_NULL(cls); + + ani_object object = CreateNewObjectByClass(env, cls); + RETURN_NULL_IF_NULL(object); + + ani_string string = nullptr; + + // name: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, routerItem.name, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_NAME, string)); + + // pageSourceFile: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, routerItem.pageSourceFile, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_PAGESOURCEFILE, string)); + + // buildFunction: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, routerItem.buildFunction, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_BUILDFUNCTION, string)); + + // customData: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, routerItem.customData, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_CUSTOMDATA, string)); + + // data: Array + ani_object aDataArrayObject = ConvertAniArray(env, routerItem.data, ConvertDataItem); + RETURN_NULL_IF_NULL(aDataArrayObject); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_DATA, aDataArrayObject)); + + return object; +} + +ani_object CommonFunAni::ConvertRequestPermission(ani_env* env, const RequestPermission& requestPermission) +{ + RETURN_NULL_IF_NULL(env); + + ani_class cls = CreateClassByName(env, CLASSNAME_PERMISSION); + RETURN_NULL_IF_NULL(cls); + + ani_object object = CreateNewObjectByClass(env, cls); + RETURN_NULL_IF_NULL(object); + + ani_string string = nullptr; + + // name: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, requestPermission.name, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_NAME, string)); + + // moduleName: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, requestPermission.moduleName, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_MODULENAME, string)); + + // reason: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, requestPermission.reason, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_REASON, string)); + + // reasonId: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_REASONID, requestPermission.reasonId)); + + // usedScene: UsedScene + ani_object aObject = ConvertRequestPermissionUsedScene(env, requestPermission.usedScene); + RETURN_NULL_IF_NULL(aObject); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_USEDSCENE, aObject)); + + return object; +} + +ani_object CommonFunAni::ConvertRequestPermissionUsedScene( + ani_env* env, const RequestPermissionUsedScene& requestPermissionUsedScene) +{ + RETURN_NULL_IF_NULL(env); + + ani_class cls = CreateClassByName(env, CLASSNAME_USEDSCENE); + RETURN_NULL_IF_NULL(cls); + + ani_object object = CreateNewObjectByClass(env, cls); + RETURN_NULL_IF_NULL(object); + + ani_string string = nullptr; + // when: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, requestPermissionUsedScene.when, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_WHEN, string)); + + // abilities: Array + ani_ref aAbilities = ConvertAniArrayString(env, requestPermissionUsedScene.abilities); + RETURN_NULL_IF_NULL(aAbilities); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_ABILITIES, aAbilities)); + + return object; +} + +ani_object CommonFunAni::ConvertPreloadItem(ani_env* env, const PreloadItem& preloadItem) +{ + RETURN_NULL_IF_NULL(env); + + ani_class cls = CreateClassByName(env, CLASSNAME_PRELOADITEM); + RETURN_NULL_IF_NULL(cls); + + ani_object object = CreateNewObjectByClass(env, cls); + RETURN_NULL_IF_NULL(object); + + ani_string string = nullptr; + + // moduleName: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, preloadItem.moduleName, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_MODULENAME, string)); + + return object; +} + +ani_object CommonFunAni::ConvertDependency(ani_env* env, const Dependency& dependency) +{ + RETURN_NULL_IF_NULL(env); + + ani_class cls = CreateClassByName(env, CLASSNAME_DEPENDENCY); + RETURN_NULL_IF_NULL(cls); + + ani_object object = CreateNewObjectByClass(env, cls); + RETURN_NULL_IF_NULL(object); + + ani_string string = nullptr; + // moduleName: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, dependency.moduleName, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_MODULENAME, string)); + + // bundleName: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, dependency.bundleName, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_BUNDLENAME, string)); + + // versionCode: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_VERSIONCODE, dependency.versionCode)); + + return object; +} + +ani_object CommonFunAni::ConvertHapModuleInfo(ani_env* env, const HapModuleInfo& hapModuleInfo) +{ + RETURN_NULL_IF_NULL(env); + + ani_class cls = CreateClassByName(env, CLASSNAME_HAPMODULEINFO); + RETURN_NULL_IF_NULL(cls); + + ani_object object = CreateNewObjectByClass(env, cls); + RETURN_NULL_IF_NULL(object); + + ani_string string = nullptr; + + // name: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, hapModuleInfo.name, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_NAME, string)); + + // icon: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, hapModuleInfo.iconPath, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_ICON, string)); + + // iconId: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_ICONID, hapModuleInfo.iconId)); + + // label: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, hapModuleInfo.label, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_LABEL, string)); + + // labelId: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_LABELID, hapModuleInfo.labelId)); + + // description: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, hapModuleInfo.description, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_DESCRIPTION, string)); + + // descriptionId: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_DESCRIPTIONID, hapModuleInfo.descriptionId)); + + // mainElementName: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, hapModuleInfo.mainElementName, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_MAINELEMENTNAME, string)); + + // abilitiesInfo: Array + ani_object aAbilityInfoObject = ConvertAniArray(env, hapModuleInfo.abilityInfos, ConvertAbilityInfo); + RETURN_NULL_IF_NULL(aAbilityInfoObject); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_ABILITIESINFO, aAbilityInfoObject)); + + // extensionAbilitiesInfo: Array + ani_object aExtensionAbilityInfoObject = ConvertAniArray(env, hapModuleInfo.extensionInfos, ConvertExtensionInfo); + RETURN_NULL_IF_NULL(aExtensionAbilityInfoObject); + RETURN_NULL_IF_FALSE( + CallSetter(env, cls, object, PROPERTYNAME_EXTENSIONABILITIESINFO, aExtensionAbilityInfoObject)); + + // metadata: Array + ani_object aMetadataObject = ConvertAniArray(env, hapModuleInfo.metadata, ConvertMetadata); + RETURN_NULL_IF_NULL(aMetadataObject); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_METADATA, aMetadataObject)); + + // deviceTypes: Array + ani_ref aDeviceTypes = ConvertAniArrayString(env, hapModuleInfo.deviceTypes); + RETURN_NULL_IF_NULL(aDeviceTypes); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_DEVICETYPES, aDeviceTypes)); + + // installationFree: boolean + RETURN_NULL_IF_FALSE( + CallSetter(env, cls, object, PROPERTYNAME_INSTALLATIONFREE, BoolToAniBoolean(hapModuleInfo.installationFree))); + + // hashValue: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, hapModuleInfo.hashValue, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_HASHVALUE, string)); + + // type: bundleManager.ModuleType + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_TYPE, + EnumUtils::EnumNativeToETS_BundleManager_ModuleType(env, static_cast(hapModuleInfo.moduleType)))); + + // dependencies: Array + ani_object aDependenciesObject = ConvertAniArray(env, hapModuleInfo.dependencies, ConvertDependency); + RETURN_NULL_IF_NULL(aDependenciesObject); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_DEPENDENCIES, aDependenciesObject)); + + // preloads: Array + ani_object aPreloadsObject = ConvertAniArray(env, hapModuleInfo.preloads, ConvertPreloadItem); + RETURN_NULL_IF_NULL(aPreloadsObject); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_PRELOADS, aPreloadsObject)); + + // fileContextMenuConfig: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, hapModuleInfo.fileContextMenu, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_FILECONTEXTMENUCONFIG, string)); + + // routerMap: Array + ani_object aRouterMapObject = ConvertAniArray(env, hapModuleInfo.routerArray, ConvertRouterItem); + RETURN_NULL_IF_NULL(aRouterMapObject); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_ROUTERMAP, aRouterMapObject)); + + // nativeLibraryPath: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, hapModuleInfo.nativeLibraryPath, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_NATIVELIBRARYPATH, string)); + + // codePath: string + std::string codePath = hapModuleInfo.hapPath; + size_t result = hapModuleInfo.hapPath.find(PATH_PREFIX); + if (result != std::string::npos) { + size_t pos = hapModuleInfo.hapPath.find_last_of('/'); + codePath = CODE_PATH_PREFIX; + if (pos != std::string::npos && pos != hapModuleInfo.hapPath.size() - 1) { + codePath.append(hapModuleInfo.hapPath.substr(pos + 1)); + } + } + RETURN_NULL_IF_FALSE(StringToAniStr(env, codePath, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_CODEPATH, string)); + + return object; +} + +ani_object CommonFunAni::ConvertElementName(ani_env* env, const ElementName& elementName) +{ + RETURN_NULL_IF_NULL(env); + + ani_class cls = CreateClassByName(env, CLASSNAME_ELEMENTNAME); + RETURN_NULL_IF_NULL(cls); + + ani_object object = CreateNewObjectByClass(env, cls); + RETURN_NULL_IF_NULL(object); + + ani_string string = nullptr; + + // deviceId?: string + if (StringToAniStr(env, elementName.GetDeviceID(), string)) { + RETURN_NULL_IF_FALSE(CallSetterOptional(env, cls, object, PROPERTYNAME_DEVICEID, string)); + } + + // bundleName: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, elementName.GetBundleName(), string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_BUNDLENAME, string)); + + // moduleName?: string + if (StringToAniStr(env, elementName.GetModuleName(), string)) { + RETURN_NULL_IF_FALSE(CallSetterOptional(env, cls, object, PROPERTYNAME_MODULENAME, string)); + } + + // abilityName: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, elementName.GetAbilityName(), string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_ABILITYNAME, string)); + + // uri?: string + if (StringToAniStr(env, elementName.GetURI(), string)) { + RETURN_NULL_IF_FALSE(CallSetterOptional(env, cls, object, PROPERTYNAME_URI, string)); + } + + // shortName?: string + if (StringToAniStr(env, "", string)) { + RETURN_NULL_IF_FALSE(CallSetterOptional(env, cls, object, PROPERTYNAME_SHORTNAME, string)); + } + + return object; +} + +ani_object CommonFunAni::ConvertCustomizeData(ani_env* env, const CustomizeData& customizeData) +{ + RETURN_NULL_IF_NULL(env); + + ani_class cls = CreateClassByName(env, CLASSNAME_CUSTOMIZEDATA); + RETURN_NULL_IF_NULL(cls); + + ani_object object = CreateNewObjectByClass(env, cls); + RETURN_NULL_IF_NULL(object); + + ani_string string = nullptr; + + // name: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, customizeData.name, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_NAME, string)); + + // value: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, customizeData.value, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_VALUE, string)); + + // extra: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, customizeData.extra, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_EXTRA, string)); + + return object; +} + +ani_object CommonFunAni::ConvertAbilitySkillUriInner(ani_env* env, const SkillUri& skillUri, bool isExtension) +{ + RETURN_NULL_IF_NULL(env); + + ani_class cls = CreateClassByName(env, CLASSNAME_SKILLURI); + RETURN_NULL_IF_NULL(cls); + + ani_object object = CreateNewObjectByClass(env, cls); + RETURN_NULL_IF_NULL(object); + + ani_string string = nullptr; + + // scheme: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, skillUri.scheme, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_SCHEME, string)); + + // host: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, skillUri.host, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_HOST, string)); + + // port: number + int32_t nPort = 0; + if (!skillUri.port.empty()) { + auto [ptr, ec] = std::from_chars(skillUri.port.data(), skillUri.port.data() + skillUri.port.size(), nPort); + if (ec != std::errc() || ptr != skillUri.port.data() + skillUri.port.size()) { + APP_LOGE("skillUri port convert failed"); + return nullptr; + } + } + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_PORT, nPort)); + + // path: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, skillUri.path, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_PATH, string)); + + // pathStartWith: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, skillUri.pathStartWith, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_PATHSTARTWITH, string)); + + // pathRegex: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, skillUri.pathRegex, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_PATHREGEX, string)); + + // type: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, skillUri.type, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_TYPE, string)); + + // utd: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, skillUri.utd, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_UTD, string)); + + // maxFileSupported: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_MAXFILESUPPORTED, skillUri.maxFileSupported)); + + if (!isExtension) { + // linkFeature: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, skillUri.linkFeature, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_LINKFEATURE, string)); + } + + return object; +} + +ani_object CommonFunAni::ConvertAbilitySkillInner(ani_env* env, const Skill& skill, bool isExtension) +{ + RETURN_NULL_IF_NULL(env); + + ani_class cls = CreateClassByName(env, CLASSNAME_SKILL); + RETURN_NULL_IF_NULL(cls); + + ani_object object = CreateNewObjectByClass(env, cls); + RETURN_NULL_IF_NULL(object); + + // actions: Array + ani_ref aActions = ConvertAniArrayString(env, skill.actions); + RETURN_NULL_IF_NULL(aActions); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_ACTIONS, aActions)); + + // entities: Array + ani_ref aEntities = ConvertAniArrayString(env, skill.entities); + RETURN_NULL_IF_NULL(aEntities); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_ENTITIES, aEntities)); + + // uris: Array + ani_object aSkillUri = + ConvertAniArray(env, skill.uris, isExtension ? ConvertExtensionAbilitySkillUri : ConvertAbilitySkillUri); + RETURN_NULL_IF_NULL(aSkillUri); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_URIS, aSkillUri)); + + if (!isExtension) { + // domainVerify: boolean + RETURN_NULL_IF_FALSE( + CallSetter(env, cls, object, PROPERTYNAME_DOMAINVERIFY, BoolToAniBoolean(skill.domainVerify))); + } + + return object; +} + +ani_object CommonFunAni::ConvertBundleResourceInfo(ani_env* env, const BundleResourceInfo& bundleResInfo) +{ + RETURN_NULL_IF_NULL(env); + + ani_class cls = CreateClassByName(env, CLASSNAME_BUNDLERESINFO); + RETURN_NULL_IF_NULL(cls); + + ani_object object = CreateNewObjectByClass(env, cls); + RETURN_NULL_IF_NULL(object); + + ani_string string = nullptr; + + // bundleName: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, bundleResInfo.bundleName, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_BUNDLENAME, string)); + + // icon: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, bundleResInfo.icon, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_ICON, string)); + + // label: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, bundleResInfo.label, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_LABEL, string)); + + // drawableDecriptor: drawableDecriptor + + // appIndex: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_APPINDEX, bundleResInfo.appIndex)); + + return object; +} + +ani_object CommonFunAni::ConvertShortcutInfo(ani_env* env, const ShortcutInfo& shortcutInfo) +{ + RETURN_NULL_IF_NULL(env); + + ani_class cls = CreateClassByName(env, CLASSNAME_SHORTCUTINFO); + RETURN_NULL_IF_NULL(cls); + + ani_object object = CreateNewObjectByClass(env, cls); + RETURN_NULL_IF_NULL(object); + + ani_string string = nullptr; + + // id: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, shortcutInfo.id, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_ID, string)); + + // bundleName: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, shortcutInfo.bundleName, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_BUNDLENAME, string)); + + // moduleName?: string + if (StringToAniStr(env, shortcutInfo.moduleName, string)) { + RETURN_NULL_IF_FALSE(CallSetterOptional(env, cls, object, PROPERTYNAME_MODULENAME, string)); + } + + // hostAbility?: string + if (StringToAniStr(env, shortcutInfo.hostAbility, string)) { + RETURN_NULL_IF_FALSE(CallSetterOptional(env, cls, object, PROPERTYNAME_HOSTABILITY, string)); + } + + // icon?: string + if (StringToAniStr(env, shortcutInfo.icon, string)) { + RETURN_NULL_IF_FALSE(CallSetterOptional(env, cls, object, PROPERTYNAME_ICON, string)); + } + + // iconId?: number + RETURN_NULL_IF_FALSE(CallSetterOptional(env, cls, object, PROPERTYNAME_ICONID, shortcutInfo.iconId)); + + // label?: string + if (StringToAniStr(env, shortcutInfo.label, string)) { + RETURN_NULL_IF_FALSE(CallSetterOptional(env, cls, object, PROPERTYNAME_LABEL, string)); + } + + // labelId?: number + RETURN_NULL_IF_FALSE(CallSetterOptional(env, cls, object, PROPERTYNAME_LABELID, shortcutInfo.labelId)); + + // wants?: Array + ani_object aShortcutWantObject = ConvertAniArray(env, shortcutInfo.intents, ConvertShortcutIntent); + RETURN_NULL_IF_NULL(aShortcutWantObject); + RETURN_NULL_IF_FALSE(CallSetterOptional(env, cls, object, PROPERTYNAME_WANTS, aShortcutWantObject)); + + // appIndex: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_APPINDEX, shortcutInfo.appIndex)); + + // sourceType: number + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_SOURCETYPE, shortcutInfo.sourceType)); + + return object; +} + +ani_object CommonFunAni::ConvertShortcutIntent(ani_env* env, const ShortcutIntent& shortcutIntent) +{ + RETURN_NULL_IF_NULL(env); + + ani_class cls = CreateClassByName(env, CLASSNAME_SHORTCUTWANT); + RETURN_NULL_IF_NULL(cls); + + ani_object object = CreateNewObjectByClass(env, cls); + RETURN_NULL_IF_NULL(object); + + ani_string string = nullptr; + + // targetBundle: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, shortcutIntent.targetBundle, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_TARGETBUNDLE, string)); + + // targetModule?: string + if (StringToAniStr(env, shortcutIntent.targetModule, string)) { + RETURN_NULL_IF_FALSE(CallSetterOptional(env, cls, object, PROPERTYNAME_TARGETMODULE, string)); + } + + // targetAbility: string + RETURN_NULL_IF_FALSE(StringToAniStr(env, shortcutIntent.targetClass, string)); + RETURN_NULL_IF_FALSE(CallSetter(env, cls, object, PROPERTYNAME_TARGETABILITY, string)); + + // parameters?: Array + ani_object aParameters = ConvertAniArray(env, shortcutIntent.parameters, ConvertShortcutIntentParameter); + RETURN_NULL_IF_NULL(aParameters); + RETURN_NULL_IF_FALSE(CallSetterOptional(env, cls, object, PROPERTYNAME_PARAMETERS, aParameters)); + + return object; +} + +inline ani_object CommonFunAni::ConvertShortcutIntentParameter( + ani_env* env, const std::pair& item) +{ + return ConvertKeyValuePair(env, item, CLASSNAME_SHORTCUT_PARAMETERITEM); +} + +bool CommonFunAni::ParseShortcutInfo(ani_env* env, ani_object object, ShortcutInfo& shortcutInfo) +{ + RETURN_FALSE_IF_NULL(env); + RETURN_FALSE_IF_NULL(object); + + ani_string string = nullptr; + ani_int intValue = 0; + uint32_t uintValue = 0; + + // id: string + RETURN_FALSE_IF_FALSE(CallGetter(env, object, PROPERTYNAME_ID, &string)); + shortcutInfo.id = AniStrToString(env, string); + + // bundleName: string + RETURN_FALSE_IF_FALSE(CallGetter(env, object, PROPERTYNAME_BUNDLENAME, &string)); + shortcutInfo.bundleName = AniStrToString(env, string); + + // moduleName?: string + if (CallGetterOptional(env, object, PROPERTYNAME_MODULENAME, &string)) { + shortcutInfo.moduleName = AniStrToString(env, string); + } + + // hostAbility?: string + if (CallGetterOptional(env, object, PROPERTYNAME_HOSTABILITY, &string)) { + shortcutInfo.hostAbility = AniStrToString(env, string); + } + + // icon?: string + if (CallGetterOptional(env, object, PROPERTYNAME_ICON, &string)) { + shortcutInfo.icon = AniStrToString(env, string); + } + + // iconId?: number + if (CallGetterOptional(env, object, PROPERTYNAME_ICONID, &uintValue)) { + shortcutInfo.iconId = uintValue; + } + + // label?: string + if (CallGetterOptional(env, object, PROPERTYNAME_LABEL, &string)) { + shortcutInfo.label = AniStrToString(env, string); + } + + // labelId?: number + if (CallGetterOptional(env, object, PROPERTYNAME_LABELID, &intValue)) { + shortcutInfo.labelId = intValue; + } + + // wants?: Array + ani_array array = nullptr; + if (CallGetterOptional(env, object, PROPERTYNAME_WANTS, &array)) { + RETURN_FALSE_IF_FALSE(ParseAniArray(env, array, shortcutInfo.intents, ParseShortcutIntent)); + } + + // appIndex: number + RETURN_FALSE_IF_FALSE(CallGetter(env, object, PROPERTYNAME_APPINDEX, &intValue)); + shortcutInfo.appIndex = intValue; + + // sourceType: number + RETURN_FALSE_IF_FALSE(CallGetter(env, object, PROPERTYNAME_SOURCETYPE, &intValue)); + shortcutInfo.sourceType = intValue; + + return true; +} + +bool CommonFunAni::ParseShortcutIntent(ani_env* env, ani_object object, ShortcutIntent& shortcutIntent) +{ + RETURN_FALSE_IF_NULL(env); + RETURN_FALSE_IF_NULL(object); + + ani_string string = nullptr; + + // targetBundle: string + RETURN_FALSE_IF_FALSE(CallGetter(env, object, PROPERTYNAME_TARGETBUNDLE, &string)); + shortcutIntent.targetBundle = AniStrToString(env, string); + + // targetModule?: string + if (CallGetterOptional(env, object, PROPERTYNAME_TARGETMODULE, &string)) { + shortcutIntent.targetModule = AniStrToString(env, string); + } + + // targetAbility: string + RETURN_FALSE_IF_FALSE(CallGetter(env, object, PROPERTYNAME_TARGETABILITY, &string)); + shortcutIntent.targetClass = AniStrToString(env, string); + + // parameters?: Array + ani_array array = nullptr; + if (CallGetterOptional(env, object, PROPERTYNAME_PARAMETERS, &array)) { + std::vector> parameters; + RETURN_FALSE_IF_FALSE(ParseAniArray(env, array, parameters, ParseKeyValuePair)); + for (const auto& parameter : parameters) { + shortcutIntent.parameters[parameter.first] = parameter.second; + } + } + + return true; +} + +bool CommonFunAni::ParseKeyValuePairWithName(ani_env* env, ani_object object, + std::pair& pair, const char* keyName, const char* valueName) +{ + RETURN_FALSE_IF_NULL(env); + RETURN_FALSE_IF_NULL(object); + + ani_string string = nullptr; + + // key: string + RETURN_FALSE_IF_FALSE(CallGetter(env, object, keyName, &string)); + pair.first = AniStrToString(env, string); + + // value: string + RETURN_FALSE_IF_FALSE(CallGetter(env, object, valueName, &string)); + pair.second = AniStrToString(env, string); + + return true; +} + +bool CommonFunAni::ParseKeyValuePair(ani_env* env, ani_object object, std::pair& pair) +{ + return ParseKeyValuePairWithName(env, object, pair, PROPERTYNAME_KEY, PROPERTYNAME_VALUE); +} + +bool CommonFunAni::ParseHashParams(ani_env* env, ani_object object, std::pair& pair) +{ + return ParseKeyValuePairWithName(env, object, pair, PROPERTYNAME_MODULENAME, PROPERTYNAME_HASHVALUE); +} + +bool CommonFunAni::ParsePgoParams(ani_env* env, ani_object object, std::pair& pair) +{ + return ParseKeyValuePairWithName(env, object, pair, PROPERTYNAME_MODULENAME, PROPERTYNAME_PGOFILEPATH); +} + +bool CommonFunAni::ParseInstallParam(ani_env* env, ani_object object, InstallParam& installParam) +{ + RETURN_FALSE_IF_NULL(env); + RETURN_FALSE_IF_NULL(object); + + ani_array array = nullptr; + // hashParams? + if (CallGetterOptional(env, object, PROPERTYNAME_HASHPARAMS, &array)) { + std::vector> hashParams; + RETURN_FALSE_IF_FALSE(ParseAniArray(env, array, hashParams, ParseHashParams)); + for (const auto& parameter : hashParams) { + installParam.hashParams[parameter.first] = parameter.second; + } + } + // pgoParams? + if (CallGetterOptional(env, object, PROPERTYNAME_PGOPARAMS, &array)) { + std::vector> pgoParams; + RETURN_FALSE_IF_FALSE(ParseAniArray(env, array, pgoParams, ParsePgoParams)); + for (const auto& parameter : pgoParams) { + installParam.pgoParams[parameter.first] = parameter.second; + } + } + + ani_int intValue = 0; + // userId?: number + if (CallGetterOptional(env, object, PROPERTYNAME_USERID, &intValue)) { + installParam.userId = intValue; + } else { + APP_LOGW("Parse userId failed,using default value"); + } + // installFlag?: number + if (CallGetterOptional(env, object, PROPERTYNAME_INSTALLFLAG, &intValue)) { + if ((intValue != static_cast(OHOS::AppExecFwk::InstallFlag::NORMAL)) && + (intValue != static_cast(OHOS::AppExecFwk::InstallFlag::REPLACE_EXISTING)) && + (intValue != static_cast(OHOS::AppExecFwk::InstallFlag::FREE_INSTALL))) { + APP_LOGE("invalid installFlag param"); + return false; + } + installParam.installFlag = static_cast(intValue); + } else { + APP_LOGW("Parse installFlag failed,using default value"); + } + + ani_boolean boolValue = false; + // isKeepData?: boolean + if (CallGetterOptional(env, object, PROPERTYNAME_ISKEEPDATA, &boolValue)) { + installParam.isKeepData = boolValue; + } else { + APP_LOGW("Parse isKeepData failed,using default value"); + } + + // crowdtestDeadline?: number + if (CallGetterOptional(env, object, PROPERTYNAME_CROWDTESTDEADLINE, &intValue)) { + installParam.crowdtestDeadline = intValue; + } else { + APP_LOGW("Parse crowdtestDeadline failed,using default value"); + } + + // sharedBundleDirPaths?: Array + if (CallGetterOptional(env, object, PROPERTYNAME_SHAREDBUNDLEDIRPATHS, &array)) { + RETURN_FALSE_IF_FALSE(ParseStrArray(env, array, installParam.sharedBundleDirPaths)); + } + + ani_string string = nullptr; + + // specifiedDistributionType?: string + if (CallGetterOptional(env, object, PROPERTYNAME_SPECIFIEDDISTRIBUTIONTYPE, &string)) { + installParam.specifiedDistributionType = AniStrToString(env, string); + } else { + APP_LOGW("Parse specifiedDistributionType failed,using default value"); + } + + // additionalInfo?: string + if (CallGetterOptional(env, object, PROPERTYNAME_ADDITIONALINFO, &string)) { + installParam.specifiedDistributionType = AniStrToString(env, string); + } else { + APP_LOGW("Parse additionalInfo failed,using default value"); + } + return true; +} + +} // namespace AppExecFwk +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/ani/common/common_fun_ani.h b/interfaces/kits/ani/common/common_fun_ani.h new file mode 100644 index 0000000000000000000000000000000000000000..d11a74a168d587238bf607abad38c356dc0f4429 --- /dev/null +++ b/interfaces/kits/ani/common/common_fun_ani.h @@ -0,0 +1,590 @@ +/* + * Copyright (c) 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. + */ + +#ifndef BUNDLE_FRAMEWORK_INTERFACES_KITS_ANI_COMMON_FUN_ANI_H +#define BUNDLE_FRAMEWORK_INTERFACES_KITS_ANI_COMMON_FUN_ANI_H + +#include +#include +#include +#include +#include +#include + +#include "app_log_wrapper.h" +#include "bundle_mgr_interface.h" +#include "bundle_resource_info.h" +#include "enum_util.h" +#include "install_param.h" + +namespace OHOS { +namespace AppExecFwk { +namespace CommonFunAniNS { +constexpr const char* TYPE_INT = "int"; +constexpr const char* TYPE_STRING = "string"; +} // namespace CommonFunAniNS + +#define RETURN_IF_NULL(ptr) \ + do { \ + if ((ptr) == nullptr) { \ + APP_LOGE("ptr is null"); \ + return; \ + } \ + } while (0) +#define RETURN_NULL_IF_NULL(ptr) \ + do { \ + if ((ptr) == nullptr) { \ + APP_LOGE("ptr is null"); \ + return nullptr; \ + } \ + } while (0) +#define RETURN_FALSE_IF_NULL(ptr) \ + do { \ + if ((ptr) == nullptr) { \ + APP_LOGE("ptr is null"); \ + return false; \ + } \ + } while (0) +#define RETURN_NULL_IF_FALSE(condition) \ + do { \ + if (!(condition)) { \ + APP_LOGE("condition is false"); \ + return nullptr; \ + } \ + } while (0) +#define RETURN_FALSE_IF_FALSE(condition) \ + do { \ + if (!(condition)) { \ + APP_LOGE("condition is false"); \ + return false; \ + } \ + } while (0) +#define RETURN_ANI_STATUS_IF_NOT_OK(res, err) \ + do { \ + if ((res) != ANI_OK) { \ + APP_LOGE(err); \ + return res; \ + } \ + } while (0) +class CommonFunAni { +public: + // Data conversion. + static inline bool AniBooleanToBool(ani_boolean value) + { + return value == ANI_TRUE; + } + static inline ani_boolean BoolToAniBoolean(bool value) + { + return value ? ANI_TRUE : ANI_FALSE; + } + static std::string AniStrToString(ani_env* env, ani_string aniStr); + static inline bool StringToAniStr(ani_env* env, const std::string& str, ani_string& aniStr) + { + ani_status status = env->String_NewUTF8(str.c_str(), str.size(), &aniStr); + if (status != ANI_OK) { + APP_LOGE("String_NewUTF8 failed %{public}d", status); + return false; + } + return true; + } + + // Convert from native to ets + static ani_object ConvertMultiAppMode(ani_env* env, const MultiAppModeData& multiAppMode); + static ani_object ConvertMetadata(ani_env* env, const Metadata& metadata); + static ani_object ConvertModuleMetaInfosItem( + ani_env* env, const std::pair>& metadata); + static ani_object ConvertResource(ani_env* env, const Resource& resource); + static ani_object ConvertApplicationInfo(ani_env* env, const ApplicationInfo& appInfo); + + static ani_object ConvertAbilityInfo(ani_env* env, const AbilityInfo& abilityInfo); + static ani_object ConvertWindowSize(ani_env* env, const AbilityInfo& abilityInfo); + static ani_object ConvertExtensionInfo(ani_env* env, const ExtensionAbilityInfo& extensionInfo); + static ani_object ConvertDependency(ani_env* env, const Dependency& dependency); + static ani_object ConvertPreloadItem(ani_env* env, const PreloadItem& preloadItem); + static ani_object ConvertHapModuleInfo(ani_env* env, const HapModuleInfo& hapModuleInfo); + + static ani_object ConvertRequestPermissionUsedScene( + ani_env* env, const RequestPermissionUsedScene& requestPermissionUsedScene); + static ani_object ConvertRequestPermission(ani_env* env, const RequestPermission& requestPermission); + + static ani_object ConvertSignatureInfo(ani_env* env, const SignatureInfo& signatureInfo); + + static ani_object ConvertKeyValuePair( + ani_env* env, const std::pair& item, const char* className); + static ani_object ConvertDataItem(ani_env* env, const std::pair& item); + static ani_object ConvertRouterItem(ani_env* env, const RouterItem& routerItem); + + static ani_object ConvertElementName(ani_env* env, const ElementName& elementName); + + static ani_object ConvertCustomizeData(ani_env* env, const CustomizeData& customizeData); + + static ani_object ConvertAbilitySkillUriInner(ani_env* env, const SkillUri& skillUri, bool isExtension); + static inline ani_object ConvertAbilitySkillUri(ani_env* env, const SkillUri& skillUri) + { + return ConvertAbilitySkillUriInner(env, skillUri, false); + } + static inline ani_object ConvertExtensionAbilitySkillUri(ani_env* env, const SkillUri& skillUri) + { + return ConvertAbilitySkillUriInner(env, skillUri, true); + } + static ani_object ConvertAbilitySkillInner(ani_env* env, const Skill& skill, bool isExtension); + static inline ani_object ConvertAbilitySkill(ani_env* env, const Skill& skill) + { + return ConvertAbilitySkillInner(env, skill, false); + } + static inline ani_object ConvertExtensionAbilitySkill(ani_env* env, const Skill& skill) + { + return ConvertAbilitySkillInner(env, skill, true); + } + static ani_object ConvertBundleInfo(ani_env* env, const BundleInfo& bundleInfo, int32_t flags); + + static ani_object ConvertBundleResourceInfo(ani_env* env, const BundleResourceInfo& bundleResInfo); + + static ani_object ConvertShortcutInfo(ani_env* env, const ShortcutInfo& shortcutInfo); + static ani_object ConvertShortcutIntent(ani_env* env, const ShortcutIntent& shortcutIntent); + static ani_object ConvertShortcutIntentParameter(ani_env* env, const std::pair& item); + + // Parse from ets to native + static bool ParseShortcutInfo(ani_env* env, ani_object object, ShortcutInfo& shortcutInfo); + static bool ParseShortcutIntent(ani_env* env, ani_object object, ShortcutIntent& shortcutIntent); + static bool ParseKeyValuePair(ani_env* env, ani_object object, std::pair& pair); + static bool ParseKeyValuePairWithName(ani_env* env, ani_object object, std::pair& pair, + const char* keyName, const char* valueName); + + static ani_class CreateClassByName(ani_env* env, const std::string& className); + static ani_object CreateNewObjectByClass(ani_env* env, ani_class cls); + static inline ani_object ConvertAniArrayString(ani_env* env, const std::vector& strings) + { + return ConvertAniArray(env, strings, [](ani_env* env, const std::string& nativeStr) { + ani_string aniStr = nullptr; + return StringToAniStr(env, nativeStr, aniStr) ? aniStr : nullptr; + }); + } + static inline bool ParseStrArray(ani_env* env, ani_object arrayObj, std::vector& strings) + { + return ParseAniArray(env, arrayObj, strings, [](ani_env* env, ani_object aniStr, std::string& nativeStr) { + nativeStr = AniStrToString(env, static_cast(aniStr)); + return true; + }); + } + static bool ParseInstallParam(ani_env* env, ani_object object, InstallParam& installParam); + static bool ParseHashParams(ani_env* env, ani_object object, std::pair& pair); + static bool ParsePgoParams(ani_env* env, ani_object object, std::pair& pair); + + template + static bool TryCastDoubleTo(const double fromValue, toType* toValue) + { + RETURN_FALSE_IF_NULL(toValue); + + if (std::isnan(fromValue)) { + APP_LOGE("value is NaN"); + return false; + } + if (std::isinf(fromValue)) { + APP_LOGE("value is Inf"); + return false; + } + if (fromValue > static_cast(std::numeric_limits::max())) { + APP_LOGE("value too large"); + return false; + } + if (fromValue < static_cast(std::numeric_limits::lowest())) { + APP_LOGE("value too small"); + return false; + } + + *toValue = static_cast(fromValue); + return true; + } + + template + static ani_object ConvertAniArrayEnum( + ani_env* env, const std::vector& cArray, ani_enum_item (*converter)(ani_env*, const int32_t)) + { + RETURN_NULL_IF_NULL(env); + RETURN_NULL_IF_NULL(converter); + + ani_class arrayCls = nullptr; + ani_status status = env->FindClass("Lescompat/Array;", &arrayCls); + if (status != ANI_OK) { + APP_LOGE("FindClass failed %{public}d", status); + return nullptr; + } + + ani_method arrayCtor; + status = env->Class_FindMethod(arrayCls, "", "I:V", &arrayCtor); + if (status != ANI_OK) { + APP_LOGE("Class_FindMethod failed %{public}d", status); + return nullptr; + } + + ani_object arrayObj; + ani_size length = cArray.size(); + status = env->Object_New(arrayCls, arrayCtor, &arrayObj, length); + if (status != ANI_OK) { + APP_LOGE("Object_New failed %{public}d", status); + return nullptr; + } + if (length > 0) { + for (ani_size i = 0; i < length; ++i) { + ani_enum_item item = converter(env, static_cast(cArray[i])); + if (item == nullptr) { + APP_LOGE("convert failed"); + return nullptr; + } + status = env->Object_CallMethodByName_Void(arrayObj, "$_set", "ILstd/core/Object;:V", i, item); + env->Reference_Delete(item); + if (status != ANI_OK) { + APP_LOGE("Object_CallMethodByName_Void failed %{public}d", status); + return nullptr; + } + } + } + + return arrayObj; + } + + template + static ani_object ConvertAniArray(ani_env* env, + const containerType& nativeArray, Converter converter, Args&&... args) + { + RETURN_NULL_IF_NULL(env); + RETURN_NULL_IF_NULL(converter); + + ani_class arrayCls = nullptr; + ani_status status = env->FindClass("Lescompat/Array;", &arrayCls); + if (status != ANI_OK) { + APP_LOGE("FindClass failed %{public}d", status); + return nullptr; + } + + ani_method arrayCtor; + status = env->Class_FindMethod(arrayCls, "", "I:V", &arrayCtor); + if (status != ANI_OK) { + APP_LOGE("Class_FindMethod failed %{public}d", status); + return nullptr; + } + + ani_size length = nativeArray.size(); + ani_object arrayObj; + status = env->Object_New(arrayCls, arrayCtor, &arrayObj, length); + if (status != ANI_OK) { + APP_LOGE("Object_New failed %{public}d", status); + return nullptr; + } + + ani_size i = 0; + for (const auto& iter : nativeArray) { + ani_object item = converter(env, iter, std::forward(args)...); + RETURN_NULL_IF_NULL(item); + status = env->Object_CallMethodByName_Void(arrayObj, "$_set", "ILstd/core/Object;:V", i, item); + env->Reference_Delete(item); + if (status != ANI_OK) { + APP_LOGE("Object_CallMethodByName_Void failed %{public}d", status); + return nullptr; + } + ++i; + } + + return arrayObj; + } + + template + static bool AniArrayForeach(ani_env* env, ani_object aniArray, callbackType callback, Args&&... args) + { + RETURN_FALSE_IF_NULL(env); + RETURN_FALSE_IF_NULL(aniArray); + + ani_double length; + ani_status status = env->Object_GetPropertyByName_Double(aniArray, "length", &length); + if (status != ANI_OK) { + APP_LOGE("Object_GetPropertyByName_Double failed %{public}d", status); + return false; + } + for (ani_int i = 0; i < static_cast(length); ++i) { + ani_ref ref; + status = env->Object_CallMethodByName_Ref(aniArray, "$_get", "I:Lstd/core/Object;", &ref, i); + if (status != ANI_OK) { + APP_LOGE("Object_CallMethodByName_Ref failed %{public}d", status); + return false; + } + bool result = callback(reinterpret_cast(ref), std::forward(args)...); + env->Reference_Delete(ref); + if (!result) { + return false; + } + } + return true; + } + + template + static bool ParseAniArray(ani_env* env, + ani_object aniArray, std::vector& nativeArray, Parser parser, Args&&... args) + { + return AniArrayForeach( + env, aniArray, + [env, &nativeArray, parser](ani_object aniObj, Args&&... args) { + nativeType nativeObj; + bool result = parser(env, aniObj, nativeObj, std::forward(args)...); + if (result) { + nativeArray.emplace_back(nativeObj); + return true; + } else { + nativeArray.clear(); + return false; + } + }, + std::forward(args)...); + } + + template + static bool CallGetter(ani_env* env, ani_object object, const char* propertyName, valueType* value) + { + RETURN_FALSE_IF_NULL(env); + RETURN_FALSE_IF_NULL(object); + + ani_status status = ANI_ERROR; + if constexpr (std::is_pointer_v && std::is_base_of_v<__ani_ref, std::remove_pointer_t>) { + status = env->Object_GetPropertyByName_Ref(object, propertyName, reinterpret_cast(value)); + } else if constexpr (std::is_same_v) { + status = env->Object_GetPropertyByName_Boolean(object, propertyName, value); + } else if constexpr (std::is_same_v) { + status = env->Object_GetPropertyByName_Char(object, propertyName, value); + } else if constexpr (std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v) { + // uint64_t -> BigInt later + double d = 0; + status = env->Object_GetPropertyByName_Double(object, propertyName, &d); + if (status != ANI_OK) { + APP_LOGE("Object_GetPropertyByName %{public}s failed %{public}d", propertyName, status); + return false; + } + if (!TryCastDoubleTo(d, value)) { + APP_LOGE("TryCastDoubleTo %{public}s failed", propertyName); + return false; + } + return true; + } else { + APP_LOGE("Object_GetPropertyByName %{public}s Unsupported", propertyName); + return false; + } + + if (status != ANI_OK) { + APP_LOGE("Object_GetPropertyByName %{public}s failed %{public}d", propertyName, status); + return false; + } + + return true; + } + + template + static bool CallGetterOptional(ani_env* env, ani_object object, const char* propertyName, valueType* value) + { + RETURN_FALSE_IF_NULL(env); + RETURN_FALSE_IF_NULL(object); + + ani_ref ref = nullptr; + ani_status status = env->Object_GetPropertyByName_Ref(object, propertyName, &ref); + if (status != ANI_OK) { + APP_LOGE("Object_GetPropertyByName_Ref %{public}s failed %{public}d", propertyName, status); + return false; + } + + ani_boolean isUndefined; + status = env->Reference_IsUndefined(ref, &isUndefined); + if (status != ANI_OK) { + APP_LOGE("Reference_IsUndefined %{public}s failed %{public}d", propertyName, status); + return false; + } + if (isUndefined) { + return false; + } + + if constexpr (std::is_pointer_v && std::is_base_of_v<__ani_ref, std::remove_pointer_t>) { + *value = reinterpret_cast(ref); + } else { + status = ANI_ERROR; + if constexpr (std::is_same_v) { + status = env->Object_CallMethodByName_Boolean( + reinterpret_cast(ref), "unboxed", ":Z", value); + } else if constexpr (std::is_same_v) { + status = + env->Object_CallMethodByName_Char(reinterpret_cast(ref), "unboxed", ":C", value); + } else if constexpr (std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v || + std::is_same_v || + std::is_same_v || std::is_same_v) { + double d = 0; + status = + env->Object_CallMethodByName_Double(reinterpret_cast(ref), "doubleValue", nullptr, &d); + if (status != ANI_OK) { + APP_LOGE("Object_GetPropertyByName %{public}s failed %{public}d", propertyName, status); + return false; + } + *value = static_cast(d); + if (!TryCastDoubleTo(d, value)) { + APP_LOGE("TryCastDoubleTo %{public}s failed", propertyName); + return false; + } + return true; + } else { + APP_LOGE("Object_CallMethodByName %{public}s Unsupported", propertyName); + return false; + } + if (status != ANI_OK) { + APP_LOGE("Object_CallMethodByName %{public}s failed %{public}d", propertyName, status); + return false; + } + } + + return true; + } + + template + static bool CallSetter(ani_env* env, ani_class cls, ani_object object, const char* propertyName, valueType value) + { + RETURN_FALSE_IF_NULL(env); + RETURN_FALSE_IF_NULL(cls); + RETURN_FALSE_IF_NULL(object); + + std::string setterName(""); + setterName.append(propertyName); + ani_method setter; + ani_status status = env->Class_FindMethod(cls, setterName.c_str(), nullptr, &setter); + if (status != ANI_OK) { + APP_LOGE("Class_FindMethod %{public}s failed %{public}d", propertyName, status); + return false; + } + + if constexpr (std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v || + std::is_same_v || + std::is_same_v || std::is_same_v) { + status = env->Object_CallMethod_Void(object, setter, static_cast(value)); + } else { + status = env->Object_CallMethod_Void(object, setter, value); + } + + if (status != ANI_OK) { + APP_LOGE("Object_CallMethod_Void %{public}s failed %{public}d", propertyName, status); + return false; + } + + return true; + } + + // sets property to null + static bool CallSetterNull(ani_env* env, ani_class cls, ani_object object, const char* propertyName) + { + RETURN_FALSE_IF_NULL(env); + RETURN_FALSE_IF_NULL(cls); + RETURN_FALSE_IF_NULL(object); + + ani_ref nullRef = nullptr; + ani_status status = env->GetNull(&nullRef); + if (status != ANI_OK) { + APP_LOGE("GetNull %{public}s failed %{public}d", propertyName, status); + return false; + } + + return CallSetter(env, cls, object, propertyName, nullRef); + } + + // sets optional property to undefined + static bool CallSetterOptionalUndefined(ani_env* env, ani_class cls, ani_object object, const char* propertyName) + { + RETURN_FALSE_IF_NULL(env); + RETURN_FALSE_IF_NULL(cls); + RETURN_FALSE_IF_NULL(object); + + ani_ref undefined = nullptr; + ani_status status = env->GetUndefined(&undefined); + if (status != ANI_OK) { + APP_LOGE("GetUndefined %{public}s failed %{public}d", propertyName, status); + return false; + } + + return CallSetter(env, cls, object, propertyName, undefined); + } + + template + static bool CallSetterOptional( + ani_env* env, ani_class cls, ani_object object, const char* propertyName, valueType value) + { + RETURN_FALSE_IF_NULL(env); + RETURN_FALSE_IF_NULL(cls); + RETURN_FALSE_IF_NULL(object); + + if constexpr (std::is_pointer_v && std::is_base_of_v<__ani_ref, std::remove_pointer_t>) { + return CallSetter(env, cls, object, propertyName, value); + } + + const char* valueClassName = nullptr; + const char* ctorSig = nullptr; + if constexpr (std::is_same_v) { + valueClassName = "Lstd/core/Boolean;"; + ctorSig = "Z:V"; + } else if constexpr (std::is_same_v) { + valueClassName = "Lstd/core/Char;"; + ctorSig = "C:V"; + } else if constexpr (std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v || + std::is_same_v || + std::is_same_v || std::is_same_v) { + valueClassName = "Lstd/core/Double;"; + ctorSig = "D:V"; + } else { + APP_LOGE("Classname %{public}s Unsupported", propertyName); + return false; + } + + ani_class valueClass = nullptr; + ani_status status = env->FindClass(valueClassName, &valueClass); + if (status != ANI_OK) { + APP_LOGE("FindClass %{public}s %{public}s failed %{public}d", propertyName, valueClassName, status); + return false; + } + + ani_method ctor = nullptr; + status = env->Class_FindMethod(valueClass, "", ctorSig, &ctor); + if (status != ANI_OK) { + APP_LOGE("Class_FindMethod %{public}s failed %{public}d", propertyName, status); + return false; + } + + ani_object valueObj = nullptr; + if constexpr (std::is_same_v || std::is_same_v || + std::is_same_v || std::is_same_v || + std::is_same_v || + std::is_same_v || std::is_same_v) { + status = env->Object_New(valueClass, ctor, &valueObj, static_cast(value)); + } else { + APP_LOGE("Classname %{public}s Unsupported", propertyName); + return false; + } + + if (status != ANI_OK) { + APP_LOGE("Object_New %{public}s failed %{public}d", propertyName, status); + return false; + } + + return CallSetter(env, cls, object, propertyName, valueObj); + } +}; +} // namespace AppExecFwk +} // namespace OHOS +#endif \ No newline at end of file diff --git a/interfaces/kits/ani/common/enum_util.h b/interfaces/kits/ani/common/enum_util.h new file mode 100644 index 0000000000000000000000000000000000000000..b40acc219631e98c804762d751564ca7f8e64734 --- /dev/null +++ b/interfaces/kits/ani/common/enum_util.h @@ -0,0 +1,439 @@ +/* + * Copyright (c) 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. + */ + +#ifndef BUNDLE_FRAMEWORK_INTERFACES_KITS_ANI_ENUM_UTIL_H +#define BUNDLE_FRAMEWORK_INTERFACES_KITS_ANI_ENUM_UTIL_H + +#include +#include + +#include "app_log_wrapper.h" +#include "bundle_mgr_interface.h" + +namespace OHOS { +namespace AppExecFwk { +namespace CommonFunAniNS { +constexpr const char* CLASSNAME_BUNDLEMANAGER_BUNDLE_FLAG = "L@ohos/bundle/bundleManager/bundleManager/BundleFlag;"; +constexpr const char* CLASSNAME_BUNDLEMANAGER_BUNDLE_TYPE = "L@ohos/bundle/bundleManager/bundleManager/BundleType;"; +constexpr const char* CLASSNAME_BUNDLEMANAGER_MULTIAPPMODE_TYPE = + "L@ohos/bundle/bundleManager/bundleManager/MultiAppModeType;"; +constexpr const char* CLASSNAME_BUNDLEMANAGER_DISPLAYORIENTATION = + "L@ohos/bundle/bundleManager/bundleManager/DisplayOrientation;"; +constexpr const char* CLASSNAME_BUNDLEMANAGER_LAUNCH_TYPE = "L@ohos/bundle/bundleManager/bundleManager/LaunchType;"; +constexpr const char* CLASSNAME_BUNDLEMANAGER_SUPPORTWINDOWMODE = + "L@ohos/bundle/bundleManager/bundleManager/SupportWindowMode;"; +constexpr const char* CLASSNAME_BUNDLEMANAGER_EXTENSIONABILITY_TYPE = + "L@ohos/bundle/bundleManager/bundleManager/ExtensionAbilityType;"; +constexpr const char* CLASSNAME_BUNDLEMANAGER_MODULE_TYPE = "L@ohos/bundle/bundleManager/bundleManager/ModuleType;"; +constexpr const char* CLASSNAME_BUNDLEMANAGER_PERMISSIONGRANTSTATE = + "L@ohos/bundle/bundleManager/bundleManager/PermissionGrantState;"; +constexpr const char* CLASSNAME_BUNDLEMANAGER_APPLICATION_FLAG = + "L@ohos/bundle/bundleManager/bundleManager/ApplicationFlag;"; +constexpr const char* CLASSNAME_BUNDLE_DISPLAYORIENTATION = "L@ohos/bundle/bundle/DisplayOrientation;"; +constexpr const char* CLASSNAME_BUNDLE_ABILITY_TYPE = "L@ohos/bundle/bundle/AbilityType;"; +constexpr const char* CLASSNAME_BUNDLE_ABILITYSUB_TYPE = "L@ohos/bundle/bundle/AbilitySubType;"; +constexpr const char* CLASSNAME_BUNDLE_LAUNCHMODE = "L@ohos/bundle/bundle/LaunchMode;"; +constexpr const char* CLASSNAME_ZLIB_COMPRESSLEVEL = "L@ohos/zlib/zlib/CompressLevel;"; +constexpr const char* CLASSNAME_ZLIB_MEMLEVEL = "L@ohos/zlib/zlib/MemLevel;"; +constexpr const char* CLASSNAME_ZLIB_COMPRESSSTRATEGY = "L@ohos/zlib/zlib/CompressStrategy;"; +} // namespace CommonFunAniNS +class EnumUtils { +private: + static ani_enum_item EnumNativeToETSByIndex(ani_env* env, const char* enumClassName, const size_t index) + { + if (env == nullptr) { + APP_LOGE("null env"); + return nullptr; + } + + ani_enum aniEnum = nullptr; + ani_status status = env->FindEnum(enumClassName, &aniEnum); + if (status != ANI_OK) { + APP_LOGE("FindEnum failed %{public}d", status); + return nullptr; + } + + ani_enum_item enumItem = nullptr; + status = env->Enum_GetEnumItemByIndex(aniEnum, index, &enumItem); + if (status != ANI_OK) { + APP_LOGE("Enum_GetEnumItemByIndex failed %{public}d", status); + return nullptr; + } + return enumItem; + } + + // enum offset = enum value - enum index + static inline ani_enum_item EnumNativeToETSByOffset( + ani_env* env, const char* enumClassName, const int32_t enumValue, const int32_t offset) + { + if (enumValue < offset) { + APP_LOGE("invalid index"); + return nullptr; + } + return EnumNativeToETSByIndex(env, enumClassName, enumValue - offset); + } + + template + static inline ani_enum_item EnumNativeToETSByTable( + ani_env* env, const char* enumClassName, const int32_t enumValue, const std::array& table) + { + for (std::size_t index = 0; index < table.size(); ++index) { + if (enumValue == table[index]) { + return EnumNativeToETSByIndex(env, enumClassName, index); + } + } + + APP_LOGE("Not found %{public}d", enumValue); + return nullptr; + } + + // bundleManager.BundleFlag + // enum BundleFlag { + // GET_BUNDLE_INFO_DEFAULT = 0x00000000, + // GET_BUNDLE_INFO_WITH_APPLICATION = 0x00000001, + // GET_BUNDLE_INFO_WITH_HAP_MODULE = 0x00000002, + // GET_BUNDLE_INFO_WITH_ABILITY = 0x00000004, + // GET_BUNDLE_INFO_WITH_EXTENSION_ABILITY = 0x00000008, + // GET_BUNDLE_INFO_WITH_REQUESTED_PERMISSION = 0x00000010, + // GET_BUNDLE_INFO_WITH_METADATA = 0x00000020, + // GET_BUNDLE_INFO_WITH_DISABLE = 0x00000040, + // GET_BUNDLE_INFO_WITH_SIGNATURE_INFO = 0x00000080, + // GET_BUNDLE_INFO_WITH_MENU = 0x00000100, + // GET_BUNDLE_INFO_WITH_ROUTER_MAP = 0x00000200, + // GET_BUNDLE_INFO_WITH_SKILL = 0x00000800, + // GET_BUNDLE_INFO_ONLY_WITH_LAUNCHER_ABILITY = 0x00001000, + // GET_BUNDLE_INFO_OF_ANY_USER = 0x00002000, + // GET_BUNDLE_INFO_EXCLUDE_CLONE = 0x00004000, + // } + static constexpr std::array Array_BundleManager_BundleFlag = { + 0x00000000, + 0x00000001, + 0x00000002, + 0x00000004, + 0x00000008, + 0x00000010, + 0x00000020, + 0x00000040, + 0x00000080, + 0x00000100, + 0x00000200, + 0x00000800, + 0x00001000, + 0x00002000, + 0x00004000, + }; + // bundleManager.ExtensionAbilityType + // enum ExtensionAbilityType { + // FORM = 0, + // WORK_SCHEDULER = 1, + // INPUT_METHOD = 2, + // SERVICE = 3, + // ACCESSIBILITY = 4, + // DATA_SHARE = 5, + // FILE_SHARE = 6, + // STATIC_SUBSCRIBER = 7, + // WALLPAPER = 8, + // BACKUP = 9, + // WINDOW = 10, + // ENTERPRISE_ADMIN = 11, + // THUMBNAIL = 13, + // PREVIEW = 14, + // PRINT = 15, + // SHARE = 16, + // PUSH = 17, + // DRIVER = 18, + // ACTION = 19, + // ADS_SERVICE = 20, + // EMBEDDED_UI = 21, + // INSIGHT_INTENT_UI = 22, + // FENCE = 24, + // ASSET_ACCELERATION = 26, + // FORM_EDIT = 27, + // DISTRIBUTED = 28, + // UNSPECIFIED = 255 + // } + static constexpr std::array Array_BundleManager_ExtensionAbilityType = { + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 24, + 26, + 27, + 28, + 255, + }; + // bundleManager.ApplicationFlag + // enum ApplicationFlag { + // GET_APPLICATION_INFO_DEFAULT = 0x00000000, + // GET_APPLICATION_INFO_WITH_PERMISSION = 0x00000001, + // GET_APPLICATION_INFO_WITH_METADATA = 0x00000002, + // GET_APPLICATION_INFO_WITH_DISABLE = 0x00000004 + // } + static constexpr std::array Array_BundleManager_ApplicationFlag = { + 0x00000000, + 0x00000001, + 0x00000002, + 0x00000004, + }; + // zlib.CompressLevel + // enum CompressLevel { + // COMPRESS_LEVEL_NO_COMPRESSION = 0, + // COMPRESS_LEVEL_BEST_SPEED = 1, + // COMPRESS_LEVEL_BEST_COMPRESSION = 9, + // COMPRESS_LEVEL_DEFAULT_COMPRESSION = -1 + // } + static constexpr std::array Array_Zlib_CompressLevel = { + 0, + 1, + 9, + -1, + }; + // zlib.MemLevel + // enum MemLevel { + // MEM_LEVEL_MIN = 1, + // MEM_LEVEL_MAX = 9, + // MEM_LEVEL_DEFAULT = 8 + // } + static constexpr std::array Array_Zlib_MemLevel = { + 1, + 9, + 8, + }; + +public: + template + static bool EnumETSToNative(ani_env* env, ani_enum_item enumItem, enumType& enumValue) + { + if (env == nullptr) { + APP_LOGE("null env"); + return false; + } + + if (enumItem == nullptr) { + APP_LOGE("null enumItem"); + return false; + } + + ani_int value {}; + ani_status status = env->EnumItem_GetValue_Int(enumItem, &value); + if (status != ANI_OK) { + APP_LOGE("EnumItem_GetValue_Int failed %{public}d", status); + return false; + } + + enumValue = static_cast(value); + return true; + } + + // bundleManager.BundleFlag + static inline ani_enum_item EnumNativeToETS_BundleManager_BundleFlag(ani_env* env, const int32_t value) + { + return EnumNativeToETSByTable( + env, CommonFunAniNS::CLASSNAME_BUNDLEMANAGER_BUNDLE_FLAG, value, Array_BundleManager_BundleFlag); + } + + // bundleManager.BundleType + // enum BundleType { + // APP = 0, + // ATOMIC_SERVICE = 1 + // } + static inline ani_enum_item EnumNativeToETS_BundleManager_BundleType(ani_env* env, const int32_t value) + { + return EnumNativeToETSByOffset(env, CommonFunAniNS::CLASSNAME_BUNDLEMANAGER_BUNDLE_TYPE, value, 0); + } + + // bundleManager.MultiAppModeType + // enum MultiAppModeType { + // UNSPECIFIED = 0, + // MULTI_INSTANCE = 1, + // APP_CLONE = 2, + // } + static inline ani_enum_item EnumNativeToETS_BundleManager_MultiAppModeType(ani_env* env, const int32_t value) + { + return EnumNativeToETSByOffset(env, CommonFunAniNS::CLASSNAME_BUNDLEMANAGER_MULTIAPPMODE_TYPE, value, 0); + } + + // bundleManager.DisplayOrientation + // enum DisplayOrientation { + // UNSPECIFIED, + // LANDSCAPE, + // PORTRAIT, + // FOLLOW_RECENT, + // LANDSCAPE_INVERTED, + // PORTRAIT_INVERTED, + // AUTO_ROTATION, + // AUTO_ROTATION_LANDSCAPE, + // AUTO_ROTATION_PORTRAIT, + // AUTO_ROTATION_RESTRICTED, + // AUTO_ROTATION_LANDSCAPE_RESTRICTED, + // AUTO_ROTATION_PORTRAIT_RESTRICTED, + // LOCKED, + // AUTO_ROTATION_UNSPECIFIED, + // FOLLOW_DESKTOP + // } + static inline ani_enum_item EnumNativeToETS_BundleManager_DisplayOrientation(ani_env* env, const int32_t value) + { + return EnumNativeToETSByOffset(env, CommonFunAniNS::CLASSNAME_BUNDLEMANAGER_DISPLAYORIENTATION, value, 0); + } + + // bundleManager.LaunchType + // enum LaunchType { + // SINGLETON = 0, + // MULTITON = 1, + // SPECIFIED = 2 + // } + static inline ani_enum_item EnumNativeToETS_BundleManager_LaunchType(ani_env* env, const int32_t value) + { + return EnumNativeToETSByOffset(env, CommonFunAniNS::CLASSNAME_BUNDLEMANAGER_LAUNCH_TYPE, value, 0); + } + + // bundleManager.SupportWindowMode + // SupportWindowMode { + // FULL_SCREEN = 0, + // SPLIT = 1, + // FLOATING = 2 + // } + static inline ani_enum_item EnumNativeToETS_BundleManager_SupportWindowMode(ani_env* env, const int32_t value) + { + return EnumNativeToETSByOffset(env, CommonFunAniNS::CLASSNAME_BUNDLEMANAGER_SUPPORTWINDOWMODE, value, 0); + } + + // bundleManager.ExtensionAbilityType + static inline ani_enum_item EnumNativeToETS_BundleManager_ExtensionAbilityType(ani_env* env, const int32_t value) + { + return EnumNativeToETSByTable(env, CommonFunAniNS::CLASSNAME_BUNDLEMANAGER_EXTENSIONABILITY_TYPE, value, + Array_BundleManager_ExtensionAbilityType); + } + + // bundleManager.ModuleType + // enum ModuleType { + // ENTRY = 1, + // FEATURE = 2, + // SHARED = 3 + // } + static inline ani_enum_item EnumNativeToETS_BundleManager_ModuleType(ani_env* env, const int32_t value) + { + return EnumNativeToETSByOffset(env, CommonFunAniNS::CLASSNAME_BUNDLEMANAGER_MODULE_TYPE, value, 1); + } + + // bundleManager.PermissionGrantState + // enum PermissionGrantState { + // PERMISSION_DENIED = -1, + // PERMISSION_GRANTED = 0 + // } + static inline ani_enum_item EnumNativeToETS_BundleManager_PermissionGrantState(ani_env* env, const int32_t value) + { + return EnumNativeToETSByOffset(env, CommonFunAniNS::CLASSNAME_BUNDLEMANAGER_PERMISSIONGRANTSTATE, value, -1); + } + + // bundleManager.ApplicationFlag + static inline ani_enum_item EnumNativeToETS_BundleManager_ApplicationFlag(ani_env* env, const int32_t value) + { + return EnumNativeToETSByTable( + env, CommonFunAniNS::CLASSNAME_BUNDLEMANAGER_APPLICATION_FLAG, value, Array_BundleManager_ApplicationFlag); + } + + // bundle.DisplayOrientation + // enum DisplayOrientation { + // UNSPECIFIED, + // LANDSCAPE, + // PORTRAIT, + // FOLLOW_RECENT + // } + static inline ani_enum_item EnumNativeToETS_Bundle_DisplayOrientation(ani_env* env, const int32_t value) + { + return EnumNativeToETSByOffset(env, CommonFunAniNS::CLASSNAME_BUNDLE_DISPLAYORIENTATION, value, 0); + } + + // bundle.AbilityType + // enum AbilityType { + // UNKNOWN, + // PAGE, + // SERVICE, + // DATA + // } + static inline ani_enum_item EnumNativeToETS_Bundle_AbilityType(ani_env* env, const int32_t value) + { + return EnumNativeToETSByOffset(env, CommonFunAniNS::CLASSNAME_BUNDLE_ABILITY_TYPE, value, 0); + } + + // bundle.AbilitySubType + // enum AbilitySubType { + // UNSPECIFIED = 0, + // CA = 1 + // } + static inline ani_enum_item EnumNativeToETS_Bundle_AbilitySubType(ani_env* env, const int32_t value) + { + return EnumNativeToETSByOffset(env, CommonFunAniNS::CLASSNAME_BUNDLE_ABILITYSUB_TYPE, value, 0); + } + + // bundle.LaunchMode + // enum LaunchMode { + // SINGLETON = 0, + // STANDARD = 1 + // } + static inline ani_enum_item EnumNativeToETS_Bundle_LaunchMode(ani_env* env, const int32_t value) + { + return EnumNativeToETSByOffset(env, CommonFunAniNS::CLASSNAME_BUNDLE_LAUNCHMODE, value, 0); + } + + // zlib.CompressLevel + static inline ani_enum_item EnumNativeToETS_Zlib_CompressLevel(ani_env* env, const int32_t value) + { + return EnumNativeToETSByTable( + env, CommonFunAniNS::CLASSNAME_ZLIB_COMPRESSLEVEL, value, Array_Zlib_CompressLevel); + } + + // zlib.MemLevel + static inline ani_enum_item EnumNativeToETS_Zlib_MemLevel(ani_env* env, const int32_t value) + { + return EnumNativeToETSByTable(env, CommonFunAniNS::CLASSNAME_ZLIB_MEMLEVEL, value, Array_Zlib_MemLevel); + } + + // zlib.CompressStrategy + // enum CompressStrategy { + // COMPRESS_STRATEGY_DEFAULT_STRATEGY = 0, + // COMPRESS_STRATEGY_FILTERED = 1, + // COMPRESS_STRATEGY_HUFFMAN_ONLY = 2, + // COMPRESS_STRATEGY_RLE = 3, + // COMPRESS_STRATEGY_FIXED = 4 + // } + static inline ani_enum_item EnumNativeToETS_Zlib_CompressStrategy(ani_env* env, const int32_t value) + { + return EnumNativeToETSByOffset(env, CommonFunAniNS::CLASSNAME_ZLIB_COMPRESSSTRATEGY, value, 0); + } +}; +} // namespace AppExecFwk +} // namespace OHOS +#endif diff --git a/interfaces/kits/ani/launcher_bundle_manager/BUILD.gn b/interfaces/kits/ani/launcher_bundle_manager/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..2fc611c84a74c932e726bd09a04ae3e6ee0045a2 --- /dev/null +++ b/interfaces/kits/ani/launcher_bundle_manager/BUILD.gn @@ -0,0 +1,93 @@ +# Copyright (c) 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. + +import("//build/config/components/ets_frontend/ets2abc_config.gni") +import("//build/ohos.gni") +import("//foundation/bundlemanager/bundle_framework/appexecfwk.gni") + +ohos_shared_library("ani_launcher_bundle_manager") { + branch_protector_ret = "pac_ret" + + sanitize = { + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + integer_overflow = true + ubsan = true + } + include_dirs = [ + "${kits_path}/ani/common", + "${kits_path}/ani/launcher_bundle_manager", + "${kits_path}/js/launcher_bundle_manager", + ] + if (bundle_framework_launcher) { + sources = [ "ani_launcher_bundle_manager.cpp" ] + } else { + sources = [ "ani_launcher_bundle_manager_unsupported.cpp" ] + } + + defines = [ + "APP_LOG_TAG = \"BMS\"", + "LOG_DOMAIN = 0xD001120", + ] + + deps = [ + "${base_path}:appexecfwk_base", + "${common_path}:libappexecfwk_common", + "${core_path}:appexecfwk_core", + "${kits_path}/ani/common:bms_ani_common", + "${kits_path}/js/common:bundle_napi_common", + "${kits_path}/js/launcher_bundle_manager:launcherbundlemanager_common", + ] + + cflags = [ + "-Os", + "-fstack-protector-strong", + ] + + cflags_cc = [ + "-Os", + "-fstack-protector-strong", + ] + + external_deps = [ + "ability_base:want", + "ability_runtime:ability_manager", + "ability_runtime:ability_start_options", + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_single", + "napi:ace_napi", + "runtime_core:ani", + "runtime_core:ani_helpers", + ] + + subsystem_name = "bundlemanager" + part_name = "bundle_framework" +} + +generate_static_abc("launcher_bundle_manager") { + base_url = "./ets" + files = [ "./ets/@ohos.bundle.launcherBundleManager.ets" ] + is_boot_abc = "True" + device_dst_file = "/system/framework/launcher_bundle_manager.abc" +} + +ohos_prebuilt_etc("launcher_bundle_manager_etc") { + source = "$target_out_dir/launcher_bundle_manager.abc" + module_install_dir = "framework" + subsystem_name = "bundlemanager" + part_name = "bundle_framework" + deps = [ ":launcher_bundle_manager" ] +} diff --git a/interfaces/kits/ani/launcher_bundle_manager/ani_launcher_bundle_manager.cpp b/interfaces/kits/ani/launcher_bundle_manager/ani_launcher_bundle_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..38937ce0e0ef74624fb376eadeb8ec68f75e8f7f --- /dev/null +++ b/interfaces/kits/ani/launcher_bundle_manager/ani_launcher_bundle_manager.cpp @@ -0,0 +1,178 @@ +/* + * Copyright (c) 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 + +#include "ability_manager_client.h" +#include "ani.h" +#include +#include "app_log_wrapper.h" +#include "business_error_ani.h" +#include "common_fun_ani.h" +#include "common_func.h" +#include "js_launcher_service.h" +#include "launcher_ability_info.h" +#include "shortcut_info.h" +#include "start_options.h" +#include "ipc_skeleton.h" + +namespace OHOS { +namespace AppExecFwk { +namespace { +constexpr int32_t EMPTY_USER_ID = -500; +constexpr int32_t ANI_CONSTRUCTOR_FIND_NAMESPACE_ERR = 2; +constexpr int32_t ANI_CONSTRUCTOR_BIND_NATIVE_FUNC_ERR = 3; +constexpr int32_t ANI_CONSTRUCTOR_ENV_ERR = 9; + +const std::map START_SHORTCUT_RES_MAP = { { ERR_OK, ERR_OK }, + { ERR_PERMISSION_DENIED, ERR_BUNDLE_MANAGER_PERMISSION_DENIED }, + { ERR_NOT_SYSTEM_APP, ERR_BUNDLE_MANAGER_SYSTEM_API_DENIED } }; + +constexpr const char* GET_SHORTCUT_INFO_SYNC = "GetShortcutInfoSync"; +constexpr const char* START_SHORTCUT = "StartShortcut"; +constexpr const char* PERMISSION_GET_BUNDLE_INFO_PRIVILEGED = "ohos.permission.GET_BUNDLE_INFO_PRIVILEGED"; +constexpr const char* ERROR_EMPTY_WANT = "want in ShortcutInfo cannot be empty"; +constexpr const char* ERROR_EMPTY_BUNDLE_NAME = "bundle name is empty"; +constexpr const char* PARSE_SHORTCUT_INFO = "parse ShortcutInfo failed"; +} // namespace + +static void StartShortcutSync(ani_env *env, ani_object aniShortcutInfo) +{ + ShortcutInfo shortcutInfo; + if (!CommonFunAni::ParseShortcutInfo(env, aniShortcutInfo, shortcutInfo)) { + APP_LOGE("ParseShortcutInfo error"); + BusinessErrorAni::ThrowError(env, ERROR_PARAM_CHECK_ERROR, PARSE_SHORTCUT_INFO); + return; + } + if (shortcutInfo.intents.empty()) { + APP_LOGW("intents is empty"); + BusinessErrorAni::ThrowError(env, ERROR_PARAM_CHECK_ERROR, ERROR_EMPTY_WANT); + return; + } + AAFwk::Want want; + ElementName element; + element.SetBundleName(shortcutInfo.intents[0].targetBundle); + element.SetModuleName(shortcutInfo.intents[0].targetModule); + element.SetAbilityName(shortcutInfo.intents[0].targetClass); + want.SetElement(element); + std::for_each(shortcutInfo.intents[0].parameters.begin(), shortcutInfo.intents[0].parameters.end(), + [&want](const auto& item) { want.SetParam(item.first, item.second); }); + + want.SetParam(AAFwk::Want::PARAM_APP_CLONE_INDEX_KEY, shortcutInfo.appIndex); + auto abilityManagerClient = AAFwk::AbilityManagerClient::GetInstance(); + if (abilityManagerClient == nullptr) { + APP_LOGI("abilityManagerClient is nullptr"); + return; + } + StartOptions startOptions; + ErrCode result = abilityManagerClient->StartShortcut(want, startOptions); + auto iter = START_SHORTCUT_RES_MAP.find(result); + result = iter == START_SHORTCUT_RES_MAP.end() ? ERR_BUNDLE_MANAGER_START_SHORTCUT_FAILED : iter->second; + if (result != ERR_OK) { + APP_LOGE("StartShortcut failed, result: %{public}d", result); + BusinessErrorAni::ThrowParameterTypeError( + env, CommonFunc::ConvertErrCode(result), START_SHORTCUT, Constants::PERMISSION_START_SHORTCUT); + } +} + +static ani_object GetShortcutInfoSync(ani_env *env, ani_string aniBundleName, ani_double aniUserId) +{ + std::string bundleName = CommonFunAni::AniStrToString(env, aniBundleName); + if (bundleName.empty()) { + APP_LOGE("BundleName is empty"); + BusinessErrorAni::ThrowError(env, ERROR_PARAM_CHECK_ERROR, ERROR_EMPTY_BUNDLE_NAME); + return nullptr; + } + int32_t userId = 0; + if (!CommonFunAni::TryCastDoubleTo(aniUserId, &userId)) { + APP_LOGE("try cast userId failed"); + BusinessErrorAni::ThrowParameterTypeError( + env, ERROR_PARAM_CHECK_ERROR, Constants::USER_ID, CommonFunAniNS::TYPE_INT); + return nullptr; + } + if (userId == EMPTY_USER_ID) { + userId = IPCSkeleton::GetCallingUid() / Constants::BASE_USER_RANGE; + } + auto launcherService = JSLauncherService::GetLauncherService(); + if (launcherService == nullptr) { + APP_LOGE("launcherService is nullptr"); + BusinessErrorAni::ThrowParameterTypeError( + env, ERROR_BUNDLE_SERVICE_EXCEPTION, GET_SHORTCUT_INFO_SYNC, PERMISSION_GET_BUNDLE_INFO_PRIVILEGED); + return nullptr; + } + std::vector shortcutInfos; + ErrCode result = launcherService->GetShortcutInfoV9(bundleName, shortcutInfos, userId); + ErrCode ret = CommonFunc::ConvertErrCode(result); + if (ret != ERR_OK) { + APP_LOGE("GetShortcutInfoV9 failed, ret %{public}d", ret); + BusinessErrorAni::ThrowParameterTypeError( + env, ret, GET_SHORTCUT_INFO_SYNC, Constants::PERMISSION_GET_BUNDLE_INFO_PRIVILEGED); + return nullptr; + } + ani_object arrayShortcutInfos = + CommonFunAni::ConvertAniArray(env, shortcutInfos, CommonFunAni::ConvertShortcutInfo); + if (arrayShortcutInfos == nullptr) { + APP_LOGE("ConvertAniArray failed"); + return nullptr; + } + return arrayShortcutInfos; +} + +extern "C" { +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) +{ + APP_LOGI("ANI_Constructor called"); + ani_env* env; + if (vm == nullptr) { + APP_LOGE("ANI_Constructor vm is nullptr"); + return static_cast(ANI_CONSTRUCTOR_ENV_ERR); + } + if (vm->GetEnv(ANI_VERSION_1, &env) != ANI_OK) { + APP_LOGE("Unsupported ANI_VERSION_1"); + return static_cast(ANI_CONSTRUCTOR_ENV_ERR); + } + if (env == nullptr) { + APP_LOGE("ANI_Constructor env is nullptr"); + return static_cast(ANI_CONSTRUCTOR_ENV_ERR); + } + auto nsName = arkts::ani_signature::Builder::BuildNamespace( + {"@ohos", "bundle", "launcherBundleManager", "launcherBundleManager"}); + ani_namespace kitNs; + if (env->FindNamespace(nsName.Descriptor().c_str(), &kitNs) != ANI_OK) { + APP_LOGE("Not found nameSpace name: %{public}s", nsName.Descriptor().c_str()); + return static_cast(ANI_CONSTRUCTOR_FIND_NAMESPACE_ERR); + } + + std::array methods = { + ani_native_function { + "StartShortcutSync", nullptr, reinterpret_cast(StartShortcutSync) + }, + ani_native_function { + "GetShortcutInfoSync", nullptr, reinterpret_cast(GetShortcutInfoSync) + }, + }; + + if (env->Namespace_BindNativeFunctions(kitNs, methods.data(), methods.size()) != ANI_OK) { + APP_LOGE("Cannot bind native methods to %{public}s", nsName.Descriptor().c_str()); + return static_cast(ANI_CONSTRUCTOR_BIND_NATIVE_FUNC_ERR); + }; + + *result = ANI_VERSION_1; + APP_LOGI("ANI_Constructor finished"); + return ANI_OK; +} +} // extern "C" +} // namespace AppExecFwk +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/ani/launcher_bundle_manager/ani_launcher_bundle_manager_unsupported.cpp b/interfaces/kits/ani/launcher_bundle_manager/ani_launcher_bundle_manager_unsupported.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0608b85ca6ea39426d7317301db1a80d009f0c03 --- /dev/null +++ b/interfaces/kits/ani/launcher_bundle_manager/ani_launcher_bundle_manager_unsupported.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (c) 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 "app_log_wrapper.h" +#include +#include "bundle_errors.h" +#include "business_error_ani.h" +#include "common_func.h" + +namespace OHOS { +namespace AppExecFwk { +namespace { +constexpr const char* START_SHORTCUT = "StartShortcut"; +constexpr const char* GET_SHORTCUT_INFO_SYNC = "GetShortcutInfoSync"; +} + +static void StartShortcutSync(ani_env *env, ani_object aniShortcutInfo) +{ + APP_LOGE("SystemCapability.BundleManager.BundleFramework.Launcher not supported"); + BusinessErrorAni::ThrowParameterTypeError(env, ERROR_SYSTEM_ABILITY_NOT_FOUND, START_SHORTCUT, ""); + return nullptr; +} + +static ani_object GetShortcutInfoSync(ani_env *env, ani_string aniBundleName, ani_double aniUserId) +{ + APP_LOGE("SystemCapability.BundleManager.BundleFramework.Launcher not supported"); + BusinessErrorAni::ThrowParameterTypeError(env, ERROR_SYSTEM_ABILITY_NOT_FOUND, GET_SHORTCUT_INFO_SYNC, ""); + return nullptr; +} + +extern "C" { +ANI_EXPORT ani_status ANI_Constructor(ani_vm *vm, uint32_t *result) +{ + APP_LOGI("ANI_Constructor called"); + ani_env* env; + if (vm == nullptr) { + APP_LOGE("ANI_Constructor vm is nullptr"); + return static_cast(ANI_CONSTRUCTOR_ENV_ERR); + } + if (vm->GetEnv(ANI_VERSION_1, &env) != ANI_OK) { + APP_LOGE("Unsupported ANI_VERSION_1"); + return static_cast(ANI_CONSTRUCTOR_ENV_ERR); + } + if (env == nullptr) { + APP_LOGE("ANI_Constructor env is nullptr"); + return static_cast(ANI_CONSTRUCTOR_ENV_ERR); + } + auto nsName = arkts::ani_signature::Builder::BuildNamespace( + {"@ohos", "bundle", "launcherBundleManager", "launcherBundleManager"}); + ani_namespace kitNs; + if (env->FindNamespace(nsName.Descriptor().c_str(), &kitNs) != ANI_OK) { + APP_LOGE("Not found nameSpace name: %{public}s", nsName.Descriptor().c_str()); + return static_cast(ANI_CONSTRUCTOR_FIND_NAMESPACE_ERR); + } + + std::array methods = { + ani_native_function { + "StartShortcutSync", nullptr, reinterpret_cast(StartShortcutSync) + }, + ani_native_function { + "GetShortcutInfoSync", nullptr, reinterpret_cast(GetShortcutInfoSync) + }, + }; + + if (env->Namespace_BindNativeFunctions(kitNs, methods.data(), methods.size()) != ANI_OK) { + APP_LOGE("Cannot bind native methods to %{public}s", nsName); + return static_cast(ANI_CONSTRUCTOR_BIND_NATIVE_FUNC_ERR); + }; + + *result = ANI_VERSION_1; + APP_LOGI("ANI_Constructor finished"); + return ANI_OK; +} +} // extern "C" +} // AppExecFwk +} // OHOS \ No newline at end of file diff --git a/interfaces/kits/ani/launcher_bundle_manager/ets/@ohos.bundle.launcherBundleManager.ets b/interfaces/kits/ani/launcher_bundle_manager/ets/@ohos.bundle.launcherBundleManager.ets new file mode 100644 index 0000000000000000000000000000000000000000..da8cbcd05f8bfe9bd8cfcefd4a96ac2c16d9aca4 --- /dev/null +++ b/interfaces/kits/ani/launcher_bundle_manager/ets/@ohos.bundle.launcherBundleManager.ets @@ -0,0 +1,50 @@ +/* + * Copyright (c) 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. + */ + +import { BusinessError } from '@ohos.base'; +import { ShortcutInfo as _ShortcutInfo, ShortcutWant as _ShortcutWant, ParameterItem as _ParameterItem } from 'bundleManager.ShortcutInfo'; + +export default namespace launcherBundleManager { + loadLibrary("ani_launcher_bundle_manager.z"); + + export native function StartShortcutSync(shortcutInfo: ShortcutInfo): void; + export native function GetShortcutInfoSync(bundleName: string, userId: number): Array; + + function startShortcut(shortcutInfo: ShortcutInfo): Promise { + let p:Promise = new Promise((resolve:(v:undefined) =>void, reject: (error: Object) => void):void=> { + let cb = ():NullishType=>{ launcherBundleManager.StartShortcutSync(shortcutInfo); } + let p1 = taskpool.execute(cb); + p1.then((): void => { + resolve(undefined); + }, (err: Object): void => { + let br = err as BusinessError; + reject(br); + }); + }); + return p; + } + + function getShortcutInfoSync(bundleName: string): Array { + return launcherBundleManager.GetShortcutInfoSync(bundleName, -500); + } + + function getShortcutInfoSync(bundleName: string, userId: number): Array { + return launcherBundleManager.GetShortcutInfoSync(bundleName, userId); + } + + export type ShortcutInfo = _ShortcutInfo; + export type ShortcutWant = _ShortcutWant; + export type ParameterItem = _ParameterItem; +} diff --git a/interfaces/kits/ani/resource_manager/BUILD.gn b/interfaces/kits/ani/resource_manager/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..2478af35fa3536ed65ed3da3052073a0265998c4 --- /dev/null +++ b/interfaces/kits/ani/resource_manager/BUILD.gn @@ -0,0 +1,115 @@ +# Copyright (c) 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. + +import("//build/config/components/ets_frontend/ets2abc_config.gni") +import("//build/ohos.gni") +import("//foundation/bundlemanager/bundle_framework/appexecfwk.gni") + +ohos_shared_library("ani_bundle_res_manager") { + branch_protector_ret = "pac_ret" + + sanitize = { + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + integer_overflow = true + ubsan = true + } + include_dirs = [ + "${inner_api_path}/appexecfwk_core/include", + "${kits_path}/ani/resource_manager", + "${kits_path}/ani/common", + "${kits_path}/js/common", + "${kits_path}/js/bundle_resource", + ] + + if (bundle_framework_bundle_resource) { + sources = [ "ani_resource_manager.cpp" ] + } else { + sources = [ "ani_resource_manager_unsupport.cpp" ] + } + + defines = [ + "APP_LOG_TAG = \"BMS\"", + "LOG_DOMAIN = 0xD001120", + ] + + deps = [ + "${base_path}:appexecfwk_base", + "${common_path}:libappexecfwk_common", + "${core_path}:appexecfwk_core", + "${kits_path}/ani/common:bms_ani_common", + "${kits_path}/js/bundle_resource:bundle_res_common", + "${kits_path}/js/common:bundle_napi_common", + ] + + cflags = [ + "-Os", + "-fstack-protector-strong", + ] + + cflags_cc = [ + "-Os", + "-fstack-protector-strong", + ] + + external_deps = [ + "ability_base:want", + "c_utils:utils", + "common_event_service:cesfwk_core", + "common_event_service:cesfwk_innerkits", + "hilog:libhilog", + "ipc:ipc_core", + "napi:ace_napi", + "runtime_core:ani", + "runtime_core:ani_helpers", + "samgr:samgr_proxy", + ] + + subsystem_name = "bundlemanager" + part_name = "bundle_framework" +} + +generate_static_abc("bundle_resource_info") { + base_url = "./ets" + files = [ + "./ets/bundleManager/BundleResourceInfo.ets", + "./ets/bundleManager/BundleResourceInfoInner.ets", + ] + is_boot_abc = "True" + device_dst_file = "/system/framework/bundle_resource_info.abc" +} + +ohos_prebuilt_etc("bundle_resource_info_etc") { + source = "$target_out_dir/bundle_resource_info.abc" + module_install_dir = "framework" + subsystem_name = "bundlemanager" + part_name = "bundle_framework" + deps = [ ":bundle_resource_info" ] +} + +generate_static_abc("bundle_resource_manager") { + base_url = "./ets" + files = [ "./ets/@ohos.bundle.bundleResourceManager.ets" ] + is_boot_abc = "True" + device_dst_file = "/system/framework/bundle_resource_manager.abc" +} + +ohos_prebuilt_etc("bundle_resource_manager_etc") { + source = "$target_out_dir/bundle_resource_manager.abc" + module_install_dir = "framework" + subsystem_name = "bundlemanager" + part_name = "bundle_framework" + deps = [ ":bundle_resource_manager" ] +} diff --git a/interfaces/kits/ani/resource_manager/ani_resource_manager.cpp b/interfaces/kits/ani/resource_manager/ani_resource_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4c791b16aceda876edcf2d8269b4f65c0a8092c8 --- /dev/null +++ b/interfaces/kits/ani/resource_manager/ani_resource_manager.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (c) 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 "app_log_wrapper.h" +#include +#include "bundle_errors.h" +#include "bundle_resource_info.h" +#include "bundle_resource_interface.h" +#include "business_error_ani.h" +#include "common_fun_ani.h" +#include "common_func.h" +#include "resource_helper.h" + +namespace OHOS { +namespace AppExecFwk { + +namespace { + constexpr int32_t INVALID_INT = -500; + constexpr int32_t DEFAULT_RES_FLAG = 1; + constexpr int32_t DEFAULT_IDX = 0; + constexpr const char* APP_INDEX = "appIndex"; + constexpr const char* BUNDLE_RESOURCE_FLAG = "ResourceFlag"; + constexpr const char* GET_BUNDLE_RESOURCE_INFO = "GetBundleResourceInfo"; + constexpr const char* PERMISSION_GET_BUNDLE_RESOURCES = "ohos.permission.GET_BUNDLE_RESOURCES"; +} + +static ani_object GetBundleResourceInfo([[maybe_unused]] ani_env* env, ani_string aniBundleName, + ani_double resFlag, ani_double appIdx) +{ + std::string bundleName = CommonFunAni::AniStrToString(env, aniBundleName); + if (bundleName.empty()) { + APP_LOGE("BundleName is empty"); + BusinessErrorAni::ThrowParameterTypeError( + env, ERROR_PARAM_CHECK_ERROR, Constants::BUNDLE_NAME, CommonFunAniNS::TYPE_STRING); + return nullptr; + } + int32_t resFlagInt = 0; + if (!CommonFunAni::TryCastDoubleTo(resFlag, &resFlagInt)) { + APP_LOGE("Cast resFlag failed"); + BusinessErrorAni::ThrowParameterTypeError( + env, ERROR_PARAM_CHECK_ERROR, BUNDLE_RESOURCE_FLAG, CommonFunAniNS::TYPE_INT); + return nullptr; + } + int32_t appIdxInt = 0; + if (!CommonFunAni::TryCastDoubleTo(appIdx, &appIdxInt)) { + APP_LOGE("Cast appIdx failed"); + BusinessErrorAni::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, APP_INDEX, CommonFunAniNS::TYPE_INT); + return nullptr; + } + auto resourceMgr = ResourceHelper::GetBundleResourceMgr(); + if (resourceMgr == nullptr) { + APP_LOGE("GetBundleResourceMgr failed"); + return nullptr; + } + + if (resFlagInt == INVALID_INT) { + resFlagInt = DEFAULT_RES_FLAG; + } + + if (appIdxInt == INVALID_INT) { + appIdxInt = DEFAULT_IDX; + } + + BundleResourceInfo bundleResInfo; + int32_t ret = resourceMgr->GetBundleResourceInfo(bundleName, resFlagInt, bundleResInfo, appIdxInt); + if (ret != ERR_OK) { + APP_LOGE("GetBundleResourceInfo failed ret: %{public}d", ret); + BusinessErrorAni::ThrowParameterTypeError( + env, CommonFunc::ConvertErrCode(ret), GET_BUNDLE_RESOURCE_INFO, PERMISSION_GET_BUNDLE_RESOURCES); + return nullptr; + } + + return CommonFunAni::ConvertBundleResourceInfo(env, bundleResInfo); +} + +extern "C" { +ANI_EXPORT ani_status ANI_Constructor(ani_vm* vm, uint32_t* result) +{ + APP_LOGI("ANI_Constructor resourceMgr called"); + ani_env* env; + ani_status res = vm->GetEnv(ANI_VERSION_1, &env); + RETURN_ANI_STATUS_IF_NOT_OK(res, "Unsupported ANI_VERSION_1"); + + auto nsName = arkts::ani_signature::Builder::BuildNamespace( + {"@ohos", "bundle", "bundleResourceManager", "bundleResourceManager"}); + ani_namespace kitNs; + res = env->FindNamespace(nsName.Descriptor().c_str(), &kitNs); + RETURN_ANI_STATUS_IF_NOT_OK( + res, "Not found nameSpace L@ohos/bundle/bundleResourceManager/bundleResourceManager;"); + + std::array methods = { + ani_native_function { + "getBundleResourceInfoNative", + nullptr, + reinterpret_cast(GetBundleResourceInfo) + } + }; + + res = env->Namespace_BindNativeFunctions(kitNs, methods.data(), methods.size()); + RETURN_ANI_STATUS_IF_NOT_OK(res, "Cannot bind native methods"); + + *result = ANI_VERSION_1; + + APP_LOGI("ANI_Constructor finished"); + + return ANI_OK; +} +} +} // AppExecFwk +} // OHOS \ No newline at end of file diff --git a/interfaces/kits/ani/resource_manager/ani_resource_manager_unsupport.cpp b/interfaces/kits/ani/resource_manager/ani_resource_manager_unsupport.cpp new file mode 100644 index 0000000000000000000000000000000000000000..11890d8455e7b33a6d68f2a9a2c49fdbbaf29f0a --- /dev/null +++ b/interfaces/kits/ani/resource_manager/ani_resource_manager_unsupport.cpp @@ -0,0 +1,68 @@ +/* + * Copyright (c) 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 "app_log_wrapper.h" +#include +#include "bundle_errors.h" +#include "business_error_ani.h" + +namespace OHOS { +namespace AppExecFwk { +namespace { + constexpr const char* GET_BUNDLE_RESOURCE_INFO = "GetBundleResourceInfo"; +} + +static ani_object GetBundleResourceInfo([[maybe_unused]] ani_env* env, ani_string aniBundleName, + ani_double resFlag, ani_double appIdx) +{ + APP_LOGE("SystemCapability.BundleManager.BundleFramework.Resource not supported"); + BusinessErrorAni::ThrowParameterTypeError(env, ERROR_SYSTEM_ABILITY_NOT_FOUND, GET_BUNDLE_RESOURCE_INFO, ""); + return nullptr; +} + +extern "C" { +ANI_EXPORT ani_status ANI_Constructor(ani_vm* vm, uint32_t* result) +{ + APP_LOGI("ANI_Constructor resourceMgr called"); + ani_env* env; + ani_status res = vm->GetEnv(ANI_VERSION_1, &env); + RETURN_ANI_STATUS_IF_NOT_OK(res, "Unsupported ANI_VERSION_1"); + + auto nsName = arkts::ani_signature::Builder::BuildNamespace( + {"@ohos", "bundle", "bundleResourceManager", "bundleResourceManager"}); + ani_namespace kitNs; + res = env->FindNamespace(nsName.Descriptor().c_str(), &kitNs); + RETURN_ANI_STATUS_IF_NOT_OK( + res, "Not found nameSpace L@ohos/bundle/bundleResourceManager/bundleResourceManager;"); + + std::array methods = { + ani_native_function { + "getBundleResourceInfoNative", + nullptr, + reinterpret_cast(GetBundleResourceInfo) + } + }; + + res = env->Namespace_BindNativeFunctions(kitNs, methods.data(), methods.size()); + RETURN_ANI_STATUS_IF_NOT_OK(res, "Cannot bind native methods"); + + *result = ANI_VERSION_1; + + APP_LOGI("ANI_Constructor finished"); + + return ANI_OK; +} +} +} // AppExecFwk +} // OHOS \ No newline at end of file diff --git a/interfaces/kits/ani/resource_manager/ets/@ohos.bundle.bundleResourceManager.ets b/interfaces/kits/ani/resource_manager/ets/@ohos.bundle.bundleResourceManager.ets new file mode 100644 index 0000000000000000000000000000000000000000..671d8317e01ea44ee7620824b900c228e00f44f1 --- /dev/null +++ b/interfaces/kits/ani/resource_manager/ets/@ohos.bundle.bundleResourceManager.ets @@ -0,0 +1,43 @@ +/* + * Copyright (c) 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. + */ + +/** + * @file + * @kit AbilityKit + */ + +import { BundleResourceInfo } from 'bundleManager.BundleResourceInfo'; + +export default namespace bundleResourceManager { + + loadLibrary("ani_bundle_res_manager.z"); + + enum ResourceFlag { + GET_RESOURCE_INFO_ALL = 0x00000001, + GET_RESOURCE_INFO_WITH_LABEL = 0x00000002, + GET_RESOURCE_INFO_WITH_ICON = 0x00000004, + GET_RESOURCE_INFO_WITH_SORTED_BY_LABEL = 0x00000008, + GET_RESOURCE_INFO_WITH_DRAWABLE_DESCRIPTOR = 0x00000010 + } + + function getBundleResourceInfo(bundleName: string, resourceFlags?: number, appIndex?: number): BundleResourceInfo + { + let resFlag = resourceFlags ?? -500; + let appIdx = appIndex ?? -500; + return bundleResourceManager.getBundleResourceInfoNative(bundleName, resFlag, appIdx); + } + + export native function getBundleResourceInfoNative(bundleName: string, resourceFlags: number, appIndex: number): BundleResourceInfo; +} \ No newline at end of file diff --git a/interfaces/kits/ani/resource_manager/ets/bundleManager/BundleResourceInfo.ets b/interfaces/kits/ani/resource_manager/ets/bundleManager/BundleResourceInfo.ets new file mode 100644 index 0000000000000000000000000000000000000000..ff8a17b797ad37c237a35576542a4597d7445fa2 --- /dev/null +++ b/interfaces/kits/ani/resource_manager/ets/bundleManager/BundleResourceInfo.ets @@ -0,0 +1,73 @@ +/* + * Copyright (c) 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. + */ + +/** + * @file + * @kit AbilityKit + */ + +/** + * Obtains resource information about a bundle + * + * @typedef BundleResourceInfo + * @syscap SystemCapability.BundleManager.BundleFramework.Resource + * @systemapi + * @since 11 + */ +export interface BundleResourceInfo { + /** + * Indicates the bundleName of this bundle + * + * @type { string } + * @readonly + * @syscap SystemCapability.BundleManager.BundleFramework.Resource + * @systemapi + * @since 11 + */ + readonly bundleName: string; + + /** + * Indicates the icon of this bundle, which is base64 format + * + * @type { string } + * @readonly + * @syscap SystemCapability.BundleManager.BundleFramework.Resource + * @systemapi + * @since 11 + */ + readonly icon: string; + + /** + * Indicates the label of this bundle + * + * @type { string } + * @readonly + * @syscap SystemCapability.BundleManager.BundleFramework.Resource + * @systemapi + * @since 11 + */ + readonly label: string; + + /** + * Indicates the index of the bundle + * + * @type { number } + * @readonly + * @syscap SystemCapability.BundleManager.BundleFramework.Resource + * @systemapi + * @since 12 + */ + readonly appIndex: number; +} \ No newline at end of file diff --git a/interfaces/kits/ani/resource_manager/ets/bundleManager/BundleResourceInfoInner.ets b/interfaces/kits/ani/resource_manager/ets/bundleManager/BundleResourceInfoInner.ets new file mode 100644 index 0000000000000000000000000000000000000000..2e24c8ef24f3ff0cc33285af03f8f846508c48ec --- /dev/null +++ b/interfaces/kits/ani/resource_manager/ets/bundleManager/BundleResourceInfoInner.ets @@ -0,0 +1,28 @@ +/* + * Copyright (c) 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. + */ + +/** + * @file + * @kit AbilityKit + */ + +import { BundleResourceInfo } from 'bundleManager.BundleResourceInfo'; + +export class BundleResourceInfoInner implements BundleResourceInfo { + readonly bundleName: string = ''; + readonly icon: string = ''; + readonly label: string = ''; + readonly appIndex: number; +} diff --git a/interfaces/kits/ani/shortcut_manager/BUILD.gn b/interfaces/kits/ani/shortcut_manager/BUILD.gn new file mode 100755 index 0000000000000000000000000000000000000000..85f410f705330a86fea17ad31edb62d85c677a7d --- /dev/null +++ b/interfaces/kits/ani/shortcut_manager/BUILD.gn @@ -0,0 +1,105 @@ +# Copyright (c) 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. + +import("//build/config/components/ets_frontend/ets2abc_config.gni") +import("//build/ohos.gni") +import("//foundation/bundlemanager/bundle_framework/appexecfwk.gni") + +ohos_shared_library("anishortcutmanager") { + branch_protector_ret = "pac_ret" + + sanitize = { + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + integer_overflow = true + ubsan = true + } + include_dirs = [ + "${inner_api_path}/appexecfwk_core/include", + "${kits_path}/ani/shortcut_manager", + "${kits_path}/ani/common", + "${kits_path}/js/common", + ] + sources = [ "ani_shortcut_manager.cpp" ] + + defines = [ + "APP_LOG_TAG = \"BundleMgrService\"", + "LOG_DOMAIN = 0xD001120", + ] + + deps = [ + "${base_path}:appexecfwk_base", + "${common_path}:libappexecfwk_common", + "${core_path}:appexecfwk_core", + "${kits_path}/ani/common:bms_ani_common", + "${kits_path}/js/common:bundle_napi_common", + ] + + cflags = [ + "-Os", + "-fstack-protector-strong", + ] + + cflags_cc = [ + "-Os", + "-fstack-protector-strong", + ] + + external_deps = [ + "ability_base:want", + "c_utils:utils", + "common_event_service:cesfwk_core", + "common_event_service:cesfwk_innerkits", + "hilog:libhilog", + "ipc:ipc_core", + "napi:ace_napi", + "runtime_core:ani", + "runtime_core:ani_helpers", + "samgr:samgr_proxy", + ] + + subsystem_name = "bundlemanager" + part_name = "bundle_framework" +} + +generate_static_abc("shortcut_info") { + base_url = "./ets" + files = [ "./ets/bundleManager/ShortcutInfo.ets" ] + is_boot_abc = "True" + device_dst_file = "/system/framework/shortcut_info.abc" +} + +ohos_prebuilt_etc("shortcut_info_etc") { + source = "$target_out_dir/shortcut_info.abc" + module_install_dir = "framework" + subsystem_name = "bundlemanager" + part_name = "bundle_framework" + deps = [ ":shortcut_info" ] +} + +generate_static_abc("shortcut_manager") { + base_url = "./ets" + files = [ "./ets/@ohos.bundle.shortcutManager.ets" ] + is_boot_abc = "True" + device_dst_file = "/system/framework/shortcut_manager.abc" +} + +ohos_prebuilt_etc("shortcut_manager_etc") { + source = "$target_out_dir/shortcut_manager.abc" + module_install_dir = "framework" + subsystem_name = "bundlemanager" + part_name = "bundle_framework" + deps = [ ":shortcut_manager" ] +} diff --git a/interfaces/kits/ani/shortcut_manager/ani_shortcut_manager.cpp b/interfaces/kits/ani/shortcut_manager/ani_shortcut_manager.cpp new file mode 100755 index 0000000000000000000000000000000000000000..9a41e6d1fd2ad358f513a03fec2b5bc2aa5704d5 --- /dev/null +++ b/interfaces/kits/ani/shortcut_manager/ani_shortcut_manager.cpp @@ -0,0 +1,171 @@ +/* + * Copyright (c) 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 "app_log_wrapper.h" +#include +#include "bundle_errors.h" +#include "bundle_mgr_interface.h" +#include "bundle_mgr_proxy.h" +#include "business_error_ani.h" +#include "common_fun_ani.h" +#include "common_func.h" +#include "ipc_skeleton.h" + +namespace OHOS { +namespace AppExecFwk { +namespace { +constexpr const char* ADD_DESKTOP_SHORTCUT_INFO = "AddDesktopShortcutInfo"; +constexpr const char* DELETE_DESKTOP_SHORTCUT_INFO = "DeleteDesktopShortcutInfo"; +constexpr const char* GET_ALL_DESKTOP_SHORTCUT_INFO = "GetAllDesktopShortcutInfo"; +constexpr const char* PARSE_SHORTCUT_INFO = "ParseShortcutInfo"; +} + +static void AddDesktopShortcutInfo(ani_env* env, ani_object info, ani_double userId) +{ + int32_t userIdInt = 0; + if (!CommonFunAni::TryCastDoubleTo(userId, &userIdInt)) { + APP_LOGE("Cast userId failed"); + BusinessErrorAni::ThrowParameterTypeError( + env, ERROR_PARAM_CHECK_ERROR, Constants::USER_ID, CommonFunAniNS::TYPE_INT); + return; + } + + ShortcutInfo shortcutInfo; + if (!CommonFunAni::ParseShortcutInfo(env, info, shortcutInfo) || + !CommonFunc::CheckShortcutInfo(shortcutInfo)) { + BusinessErrorAni::ThrowError(env, ERROR_PARAM_CHECK_ERROR, PARSE_SHORTCUT_INFO); + APP_LOGE("Parse shortcutInfo err. userId:%{public}d", userIdInt); + return; + } + + auto iBundleMgr = CommonFunc::GetBundleMgr(); + if (iBundleMgr == nullptr) { + APP_LOGE("Can not get iBundleMgr"); + BusinessErrorAni::ThrowError(env, ERR_APPEXECFWK_SERVICE_NOT_READY, ADD_DESKTOP_SHORTCUT_INFO); + return; + } + ErrCode ret = iBundleMgr->AddDesktopShortcutInfo(shortcutInfo, userIdInt); + if (ret != ERR_OK) { + APP_LOGE("AddDesktopShortcutInfo failed ret:%{public}d,userId:%{public}d", ret, userIdInt); + BusinessErrorAni::ThrowParameterTypeError( + env, CommonFunc::ConvertErrCode(ret), ADD_DESKTOP_SHORTCUT_INFO, Constants::PERMISSION_MANAGER_SHORTCUT); + } +} + +static void DeleteDesktopShortcutInfo(ani_env* env, ani_object info, ani_double userId) +{ + int32_t userIdInt = 0; + if (!CommonFunAni::TryCastDoubleTo(userId, &userIdInt)) { + APP_LOGE("Cast userId failed"); + BusinessErrorAni::ThrowParameterTypeError( + env, ERROR_PARAM_CHECK_ERROR, Constants::USER_ID, CommonFunAniNS::TYPE_INT); + return; + } + + ShortcutInfo shortcutInfo; + if (!CommonFunAni::ParseShortcutInfo(env, info, shortcutInfo) || + !CommonFunc::CheckShortcutInfo(shortcutInfo)) { + APP_LOGE("Parse shortcutInfo err. userId:%{public}d", userIdInt); + BusinessErrorAni::ThrowError(env, ERROR_PARAM_CHECK_ERROR, PARSE_SHORTCUT_INFO); + return; + } + + auto iBundleMgr = CommonFunc::GetBundleMgr(); + if (iBundleMgr == nullptr) { + APP_LOGE("Can not get iBundleMgr"); + BusinessErrorAni::ThrowError(env, ERR_APPEXECFWK_SERVICE_NOT_READY, DELETE_DESKTOP_SHORTCUT_INFO); + return; + } + ErrCode ret = iBundleMgr->DeleteDesktopShortcutInfo(shortcutInfo, userIdInt); + if (ret != ERR_OK) { + APP_LOGE("DeleteDesktopShortcutInfo failed ret:%{public}d,userId:%{public}d", ret, userIdInt); + BusinessErrorAni::ThrowParameterTypeError( + env, CommonFunc::ConvertErrCode(ret), + DELETE_DESKTOP_SHORTCUT_INFO, Constants::PERMISSION_MANAGER_SHORTCUT); + } +} + +static ani_ref GetAllDesktopShortcutInfo(ani_env* env, ani_double userId) +{ + int32_t userIdInt = 0; + if (!CommonFunAni::TryCastDoubleTo(userId, &userIdInt)) { + APP_LOGE("Cast userId failed"); + BusinessErrorAni::ThrowParameterTypeError( + env, ERROR_PARAM_CHECK_ERROR, Constants::USER_ID, CommonFunAniNS::TYPE_INT); + return nullptr; + } + + std::vector shortcutInfos; + auto iBundleMgr = CommonFunc::GetBundleMgr(); + if (iBundleMgr == nullptr) { + APP_LOGE("Can not get iBundleMgr"); + BusinessErrorAni::ThrowError(env, ERR_APPEXECFWK_SERVICE_NOT_READY, GET_ALL_DESKTOP_SHORTCUT_INFO); + return nullptr; + } + ErrCode ret = iBundleMgr->GetAllDesktopShortcutInfo(userIdInt, shortcutInfos); + if (ret != ERR_OK) { + APP_LOGE("GetAllDesktopShortcutInfo failed ret:%{public}d,userId:%{public}d", ret, userIdInt); + BusinessErrorAni::ThrowParameterTypeError( + env, CommonFunc::ConvertErrCode(ret), + GET_ALL_DESKTOP_SHORTCUT_INFO, Constants::PERMISSION_MANAGER_SHORTCUT); + return nullptr; + } + ani_ref shortcutInfosRef = CommonFunAni::ConvertAniArray(env, shortcutInfos, CommonFunAni::ConvertShortcutInfo); + if (shortcutInfosRef == nullptr) { + APP_LOGE("nullptr shortcutInfosRef"); + } + + return shortcutInfosRef; +} + +extern "C" { +ANI_EXPORT ani_status ANI_Constructor(ani_vm* vm, uint32_t* result) +{ + APP_LOGI("ANI_Constructor called"); + ani_env* env; + ani_status res = vm->GetEnv(ANI_VERSION_1, &env); + RETURN_ANI_STATUS_IF_NOT_OK(res, "Unsupported ANI_VERSION_1"); + + auto nsName = arkts::ani_signature::Builder::BuildNamespace( + {"@ohos", "bundle", "shortcutManager", "shortcutManager"}); + ani_namespace kitNs; + res = env->FindNamespace(nsName.Descriptor().c_str(), &kitNs); + RETURN_ANI_STATUS_IF_NOT_OK( + res, "Not found nameSpace L@ohos/bundle/shortcutManager/shortcutManager;"); + + std::array methods = { + ani_native_function { + "AddDesktopShortcutInfo", nullptr, reinterpret_cast(AddDesktopShortcutInfo) + }, + ani_native_function { + "DeleteDesktopShortcutInfo", nullptr, reinterpret_cast(DeleteDesktopShortcutInfo) + }, + ani_native_function { + "GetAllDesktopShortcutInfo", nullptr, reinterpret_cast(GetAllDesktopShortcutInfo) + }, + }; + + res = env->Namespace_BindNativeFunctions(kitNs, methods.data(), methods.size()); + RETURN_ANI_STATUS_IF_NOT_OK(res, "Cannot bind native methods"); + + *result = ANI_VERSION_1; + + APP_LOGI("ANI_Constructor finished"); + + return ANI_OK; +} +} +} // AppExecFwk +} // OHOS \ No newline at end of file diff --git a/interfaces/kits/ani/shortcut_manager/ets/@ohos.bundle.shortcutManager.ets b/interfaces/kits/ani/shortcut_manager/ets/@ohos.bundle.shortcutManager.ets new file mode 100755 index 0000000000000000000000000000000000000000..0421943f3a2fa89550251dc69d826d360697ab3a --- /dev/null +++ b/interfaces/kits/ani/shortcut_manager/ets/@ohos.bundle.shortcutManager.ets @@ -0,0 +1,77 @@ +/* + * Copyright (c) 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. + */ + +import { ShortcutInfo as _ShortcutInfo, ShortcutWant as _ShortcutWant, ParameterItem as _ParameterItem } from 'bundleManager.ShortcutInfo'; +import { BusinessError } from '@ohos.base'; + +namespace shortcutManager { + + loadLibrary("anishortcutmanager.z"); + + export native function AddDesktopShortcutInfo(shortcutInfo: ShortcutInfo, userId: number): void; + + function addDesktopShortcutInfo(shortcutInfo: ShortcutInfo, userId: number): Promise { + let p:Promise = new Promise((resolve:(v:undefined) =>void, reject: (error: Object) => void):void=> { + let cb = ():NullishType=>{shortcutManager.AddDesktopShortcutInfo(shortcutInfo, userId);return undefined;} + let p1 = taskpool.execute(cb); + p1.then(():void => { + resolve(undefined); + }, (err: Object): void => { + let br = err as BusinessError; + reject(br); + }); + }); + return p; + } + + export native function DeleteDesktopShortcutInfo(shortcutInfo: ShortcutInfo, userId: number): void; + + function deleteDesktopShortcutInfo(shortcutInfo: ShortcutInfo, userId: number): Promise { + let p:Promise = new Promise((resolve:(v:undefined) =>void, reject: (error: Object) => void):void=> { + let cb = ():NullishType=>{shortcutManager.DeleteDesktopShortcutInfo(shortcutInfo, userId);return undefined;} + let p1 = taskpool.execute(cb); + p1.then(():void => { + resolve(undefined); + }, (err: Object): void => { + let br = err as BusinessError; + reject(br); + }); + }); + return p; + } + + export native function GetAllDesktopShortcutInfo(userId: number): Array; + + function getAllDesktopShortcutInfo(userId: number): Promise> { + let p = new Promise>((resolve: (arrShortcutInfo: Array) => void, reject: (error: Object)=>void) => { + let cb = ():(Array)=>{return shortcutManager.GetAllDesktopShortcutInfo(userId);}; + let p1 = taskpool.execute(cb); + p1.then((e: NullishType) => { + let resultShortcutInfo: Array = e as Array; + resolve(resultShortcutInfo); + }, (err: Object): void => { + let br = err as BusinessError; + reject(br); + }); + }); + return p; + } + + export type ShortcutInfo = _ShortcutInfo; + export type ShortcutWant = _ShortcutWant; + export type ParameterItem = _ParameterItem; +} + +export default shortcutManager; \ No newline at end of file diff --git a/interfaces/kits/ani/shortcut_manager/ets/bundleManager/ShortcutInfo.ets b/interfaces/kits/ani/shortcut_manager/ets/bundleManager/ShortcutInfo.ets new file mode 100755 index 0000000000000000000000000000000000000000..18f5a2f7a9ae5cc5151674d48c025fbc63c29621 --- /dev/null +++ b/interfaces/kits/ani/shortcut_manager/ets/bundleManager/ShortcutInfo.ets @@ -0,0 +1,66 @@ +/* + * Copyright (c) 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. + */ + +export interface ShortcutInfo { + id: string; + bundleName: string; + moduleName?: string; + hostAbility?: string; + icon?: string; + iconId?: number; + label?: string; + labelId?: number; + wants?: Array; + appIndex: number; + sourceType: number; +} + +export interface ShortcutWant { + targetBundle: string; + targetModule?: string; + targetAbility: string; + parameters?: Array; +} + +export interface ParameterItem { + key: string; + value: string; +} + +export class ShortcutInfoInner implements ShortcutInfo { + id: string = ""; + bundleName: string = ""; + moduleName?: string | undefined = ""; + hostAbility?: string | undefined = ""; + icon?: string | undefined = ""; + iconId?: number | undefined; + label?: string | undefined = ""; + labelId?: number | undefined; + wants?: Array | undefined = new Array; + appIndex: number; + sourceType: number; +} + +class ShortcutWantInner implements ShortcutWant { + targetBundle: string = ""; + targetModule?: string | undefined = ""; + targetAbility: string = ""; + parameters?: Array | undefined = new Array; +} + +class ParameterItemInner implements ParameterItem { + key: string = ""; + value: string = ""; +} diff --git a/interfaces/kits/ani/zlib/BUILD.gn b/interfaces/kits/ani/zlib/BUILD.gn new file mode 100644 index 0000000000000000000000000000000000000000..739e5cf1a27d4e4acace75a46b7c144df5e662c2 --- /dev/null +++ b/interfaces/kits/ani/zlib/BUILD.gn @@ -0,0 +1,104 @@ +# Copyright (c) 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. + +import("//build/config/components/ets_frontend/ets2abc_config.gni") +import("//build/ohos.gni") +import("//foundation/bundlemanager/bundle_framework/appexecfwk.gni") + +ohos_shared_library("ani_zlib") { + branch_protector_ret = "pac_ret" + + sanitize = { + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + integer_overflow = true + ubsan = true + } + + defines = [ + "APP_LOG_TAG = \"BMS\"", + "LOG_DOMAIN = 0xD001120", + ] + + include_dirs = [ + "${inner_api_path}/appexecfwk_core/include", + "${kits_path}/ani/zlib", + "${kits_path}/ani/common", + "${kits_path}/js/common", + "${kits_path}/js/zip/include", + "${kits_path}/js/zip/napi", + ] + + sources = [ + "${kits_path}/js/zip/src/file_path.cpp", + "${kits_path}/js/zip/src/zip_internal.cpp", + "${kits_path}/js/zip/src/zip_reader.cpp", + "${kits_path}/js/zip/src/zip_utils.cpp", + "${kits_path}/js/zip/src/zip_writer.cpp", + "ani_zip.cpp", + "ani_zlib.cpp", + ] + + deps = [ + "${base_path}:appexecfwk_base", + "${common_path}:libappexecfwk_common", + "${core_path}:appexecfwk_core", + "${kits_path}/ani/common:bms_ani_common", + "${kits_path}/js/common:bundle_napi_common", + ] + + cflags = [ + "-Os", + "-fstack-protector-strong", + ] + + cflags_cc = [ + "-Os", + "-fstack-protector-strong", + ] + + external_deps = [ + "ability_base:want", + "c_utils:utils", + "common_event_service:cesfwk_core", + "common_event_service:cesfwk_innerkits", + "eventhandler:libeventhandler", + "ffrt:libffrt", + "hilog:libhilog", + "ipc:ipc_core", + "napi:ace_napi", + "runtime_core:ani", + "samgr:samgr_proxy", + "zlib:shared_libz", + ] + + subsystem_name = "bundlemanager" + part_name = "bundle_framework" +} + +generate_static_abc("zlib") { + base_url = "./ets" + files = [ "./ets/@ohos.zlib.ets" ] + is_boot_abc = "True" + device_dst_file = "/system/framework/zlib.abc" +} + +ohos_prebuilt_etc("zlib_etc") { + source = "$target_out_dir/zlib.abc" + module_install_dir = "framework" + subsystem_name = "bundlemanager" + part_name = "bundle_framework" + deps = [ ":zlib" ] +} diff --git a/interfaces/kits/ani/zlib/ani_zip.cpp b/interfaces/kits/ani/zlib/ani_zip.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6fbc44fe3a5d07c6663ec3380870016f7ef2dbd9 --- /dev/null +++ b/interfaces/kits/ani/zlib/ani_zip.cpp @@ -0,0 +1,453 @@ +/* + * Copyright (c) 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 "ani_zip.h" +#include "zip.h" +#include "zip_reader.h" +#include "zip_writer.h" + +namespace OHOS { +namespace AppExecFwk { +namespace LIBZIP { +constexpr const char* PROPERTY_NAME_LEVEL = "level"; +constexpr const char* PROPERTY_NAME_MEMLEVEL = "memLevel"; +constexpr const char* PROPERTY_NAME_STRATEGY = "strategy"; +constexpr const char* SEPARATOR = "/"; +constexpr const char HIDDEN_SEPARATOR = '.'; + +using FilterCallback = std::function; +using DirectoryCreator = std::function; +using WriterFactory = std::function(FilePath&, FilePath&)>; + +struct ANIUnzipParam { + FilterCallback filterCB = nullptr; + bool logSkippedFiles = false; +}; + +bool ANIParseOptions(ani_env* env, ani_object object, LIBZIP::OPTIONS& options) +{ + RETURN_FALSE_IF_NULL(env); + + if (object == nullptr) { + return true; // allow null + } + + options.level = LIBZIP::COMPRESS_LEVEL::COMPRESS_LEVEL_DEFAULT_COMPRESSION; + options.memLevel = LIBZIP::MEMORY_LEVEL::MEM_LEVEL_DEFAULT_MEMLEVEL; + options.strategy = LIBZIP::COMPRESS_STRATEGY::COMPRESS_STRATEGY_DEFAULT_STRATEGY; + + ani_boolean isUndefined; + ani_status status = env->Reference_IsUndefined(object, &isUndefined); + if (status != ANI_OK) { + APP_LOGI("Reference_IsUndefined failed %{public}d", status); + return false; + } + + if (isUndefined) { + return true; // allow undefined + } + + ani_enum_item enumItem = nullptr; + // level?: CompressLevel + if (CommonFunAni::CallGetterOptional(env, object, PROPERTY_NAME_LEVEL, &enumItem)) { + RETURN_FALSE_IF_FALSE(EnumUtils::EnumETSToNative(env, enumItem, options.level)); + } + + // memLevel?: MemLevel + if (CommonFunAni::CallGetterOptional(env, object, PROPERTY_NAME_MEMLEVEL, &enumItem)) { + RETURN_FALSE_IF_FALSE(EnumUtils::EnumETSToNative(env, enumItem, options.memLevel)); + } + + // strategy?: CompressStrategy + if (CommonFunAni::CallGetterOptional(env, object, PROPERTY_NAME_STRATEGY, &enumItem)) { + RETURN_FALSE_IF_FALSE(EnumUtils::EnumETSToNative(env, enumItem, options.strategy)); + } + + return true; +} + +bool ANIIsHiddenFile(const FilePath& filePath) +{ + FilePath localFilePath = filePath; + if (!localFilePath.Value().empty()) { + return localFilePath.Value()[0] == HIDDEN_SEPARATOR; + } + + return false; +} + +bool ANIExcludeNoFilesFilter(const FilePath& filePath) +{ + return true; +} + +bool ANIExcludeHiddenFilesFilter(const FilePath& filePath) +{ + return !ANIIsHiddenFile(filePath); +} + +std::vector ANIListDirectoryContent(const FilePath& filePath, bool& isSuccess) +{ + FilePath curPath = filePath; + std::vector fileDirectoryVector; + std::vector filelist; + isSuccess = FilePath::GetZipAllDirFiles(curPath.Value(), filelist); + if (isSuccess) { + APP_LOGD("f.size=%{public}zu", filelist.size()); + for (size_t i = 0; i < filelist.size(); i++) { + std::string str(filelist[i]); + if (!str.empty()) { + fileDirectoryVector.push_back( + FileAccessor::DirectoryContentEntry(FilePath(str), FilePath::DirectoryExists(FilePath(str)))); + } + } + } + return fileDirectoryVector; +} + +bool ANICreateDirectory(FilePath& extractDir, FilePath& entryPath) +{ + std::string path = extractDir.Value(); + if (EndsWith(path, SEPARATOR)) { + APP_LOGE("ANICreateDirectory: %{public}s", FilePath(extractDir.Value() + entryPath.Value()).Value().c_str()); + return FilePath::CreateDirectory(FilePath(extractDir.Value() + entryPath.Value())); + } else { + APP_LOGE( + "ANICreateDirectory: %{public}s", FilePath(extractDir.Value() + "/" + entryPath.Value()).Value().c_str()); + return FilePath::CreateDirectory(FilePath(extractDir.Value() + "/" + entryPath.Value())); + } +} + +std::unique_ptr ANICreateFilePathWriterDelegate(FilePath& extractDir, FilePath entryPath) +{ + if (EndsWith(extractDir.Value(), SEPARATOR)) { + APP_LOGE("ANICreateFilePathWriterDelegate: %{public}s", + FilePath(extractDir.Value() + entryPath.Value()).Value().c_str()); + return std::make_unique(FilePath(extractDir.Value() + entryPath.Value())); + } else { + APP_LOGE("ANICreateFilePathWriterDelegate: %{public}s", + FilePath(extractDir.Value() + "/" + entryPath.Value()).Value().c_str()); + return std::make_unique(FilePath(extractDir.Value() + "/" + entryPath.Value())); + } +} + +ZipParams::ZipParams(const std::vector& srcDir, const FilePath& destFile) + : srcDir_(srcDir), destFile_(destFile) +{} + +// Does not take ownership of |fd|. +ZipParams::ZipParams(const std::vector& srcDir, int destFd) : srcDir_(srcDir), destFd_(destFd) {} + +FilePath ANIFilePathEndIsSeparator(FilePath paramPath) +{ + bool endIsSeparator = EndsWith(paramPath.Value(), SEPARATOR); + if (FilePath::IsDir(paramPath)) { + if (!endIsSeparator) { + paramPath.AppendSeparator(); + } + } + return paramPath; +} + +ErrCode ANIUnzipWithFilterAndWriters(const PlatformFile& srcFile, FilePath& destDir, WriterFactory writerFactory, + DirectoryCreator directoryCreator, ANIUnzipParam& unzipParam) +{ + APP_LOGI("destDir=%{private}s", destDir.Value().c_str()); + ZipReader reader; + if (!reader.OpenFromPlatformFile(srcFile)) { + APP_LOGI("Failed to open srcFile"); + return ERR_ZLIB_SRC_FILE_FORMAT_ERROR; + } + while (reader.HasMore()) { + if (!reader.OpenCurrentEntryInZip()) { + APP_LOGI("Failed to open the current file in zip"); + return ERR_ZLIB_SRC_FILE_FORMAT_ERROR; + } + const FilePath& constEntryPath = reader.CurrentEntryInfo()->GetFilePath(); + FilePath entryPath = constEntryPath; + if (reader.CurrentEntryInfo()->IsUnsafe()) { + APP_LOGI("Found an unsafe file in zip"); + return ERR_ZLIB_SRC_FILE_FORMAT_ERROR; + } + if (!unzipParam.filterCB(entryPath)) { + if (unzipParam.logSkippedFiles) { + APP_LOGI("Skipped file"); + } + if (!reader.AdvanceToNextEntry()) { + APP_LOGI("Failed to advance to the next file"); + return ERR_ZLIB_SRC_FILE_FORMAT_ERROR; + } + continue; + } + + if (reader.CurrentEntryInfo()->IsDirectory()) { + if (!directoryCreator(destDir, entryPath)) { + APP_LOGI("directory_creator(%{private}s) Failed", entryPath.Value().c_str()); + return ERR_ZLIB_DEST_FILE_DISABLED; + } + } else { + std::unique_ptr writer = writerFactory(destDir, entryPath); + if (!writer->PrepareOutput()) { + APP_LOGE("PrepareOutput err"); + return ERR_ZLIB_DEST_FILE_DISABLED; + } + if (!reader.ExtractCurrentEntry(writer.get(), std::numeric_limits::max())) { + APP_LOGI("Failed to extract"); + return ERR_ZLIB_SRC_FILE_FORMAT_ERROR; + } + } + + if (!reader.AdvanceToNextEntry()) { + APP_LOGI("Failed to advance to the next file"); + return ERR_ZLIB_SRC_FILE_FORMAT_ERROR; + } + } + return ERR_OK; +} + +ErrCode ANIUnzipWithFilterAndWritersParallel(const FilePath& srcFile, FilePath& destDir, WriterFactory writerFactory, + DirectoryCreator directoryCreator, ANIUnzipParam& unzipParam) +{ + ZipParallelReader reader; + FilePath src = srcFile; + + if (!reader.Open(src)) { + APP_LOGI("Failed to open srcFile"); + return ERR_ZLIB_SRC_FILE_FORMAT_ERROR; + } + ErrCode ret = ERR_OK; + for (int32_t i = 0; i < reader.num_entries(); i++) { + if (!reader.OpenCurrentEntryInZip()) { + APP_LOGI("Failed to open the current file in zip"); + return ERR_ZLIB_SRC_FILE_FORMAT_ERROR; + } + const FilePath& constEntryPath = reader.CurrentEntryInfo()->GetFilePath(); + if (reader.CurrentEntryInfo()->IsUnsafe()) { + APP_LOGI("Found an unsafe file in zip"); + return ERR_ZLIB_SRC_FILE_FORMAT_ERROR; + } + unz_file_pos position = {}; + if (!reader.GetCurrentEntryPos(position)) { + return ERR_ZLIB_SRC_FILE_FORMAT_ERROR; + } + bool isDirectory = reader.CurrentEntryInfo()->IsDirectory(); + ffrt::submit( + [&, position, isDirectory, constEntryPath]() { + if (ret != ERR_OK) { + return; + } + int resourceId = sched_getcpu(); + unzFile zipFile = reader.GetZipHandler(resourceId); + if (!reader.GotoEntry(zipFile, position)) { + APP_LOGI("Failed to go to entry"); + ret = ERR_ZLIB_SRC_FILE_FORMAT_ERROR; + return; + } + FilePath entryPath = constEntryPath; + if (unzipParam.filterCB(entryPath)) { + if (isDirectory) { + if (!directoryCreator(destDir, entryPath)) { + APP_LOGI("directory_creator(%{private}s) Failed", entryPath.Value().c_str()); + reader.ReleaseZipHandler(resourceId); + ret = ERR_ZLIB_DEST_FILE_DISABLED; + return; + } + } else { + std::unique_ptr writer = writerFactory(destDir, entryPath); + if (!writer->PrepareOutput()) { + APP_LOGE("PrepareOutput err"); + reader.ReleaseZipHandler(resourceId); + ret = ERR_ZLIB_DEST_FILE_DISABLED; + return; + } + if (!reader.ExtractEntry(writer.get(), zipFile, std::numeric_limits::max())) { + APP_LOGI("Failed to extract"); + reader.ReleaseZipHandler(resourceId); + ret = ERR_ZLIB_SRC_FILE_FORMAT_ERROR; + return; + } + } + } else if (unzipParam.logSkippedFiles) { + APP_LOGI("Skipped file"); + } + reader.ReleaseZipHandler(resourceId); + }, + {}, {}); + if (!reader.AdvanceToNextEntry()) { + APP_LOGI("Failed to advance to the next file"); + return ERR_ZLIB_SRC_FILE_FORMAT_ERROR; + } + } + ffrt::wait(); + return ERR_OK; +} + +ErrCode ANIUnzipWithFilterCallback( + const FilePath& srcFile, const FilePath& destDir, const OPTIONS& options, ANIUnzipParam& unzipParam) +{ + FilePath src = srcFile; + if (!FilePathCheckValid(src.Value())) { + APP_LOGI("FilePathCheckValid returnValue is false"); + return ERR_ZLIB_SRC_FILE_DISABLED; + } + + FilePath dest = destDir; + + APP_LOGI("srcFile=%{private}s, destFile=%{private}s", src.Value().c_str(), dest.Value().c_str()); + + if (!FilePath::PathIsValid(srcFile)) { + APP_LOGI("PathIsValid return value is false"); + return ERR_ZLIB_SRC_FILE_DISABLED; + } + + ErrCode ret = ERR_OK; + if (options.parallel == PARALLEL_STRATEGY_PARALLEL_DECOMPRESSION) { + ret = ANIUnzipWithFilterAndWritersParallel(src, dest, + std::bind(&ANICreateFilePathWriterDelegate, std::placeholders::_1, std::placeholders::_2), + std::bind(&ANICreateDirectory, std::placeholders::_1, std::placeholders::_2), unzipParam); + } else { + PlatformFile zipFd = open(src.Value().c_str(), S_IREAD, O_CREAT); + if (zipFd == kInvalidPlatformFile) { + APP_LOGE("Failed to open"); + return ERR_ZLIB_SRC_FILE_DISABLED; + } + ret = ANIUnzipWithFilterAndWriters(zipFd, dest, + std::bind(&ANICreateFilePathWriterDelegate, std::placeholders::_1, std::placeholders::_2), + std::bind(&ANICreateDirectory, std::placeholders::_1, std::placeholders::_2), unzipParam); + close(zipFd); + } + return ret; +} + +ErrCode ANIDecompressFileImpl(const std::string& inFile, const std::string& outFile, const LIBZIP::OPTIONS& options) +{ + LIBZIP::FilePath srcFileDir(inFile); + LIBZIP::FilePath destDir(outFile); + if ((destDir.Value().size() == 0) || LIBZIP::FilePath::HasRelativePathBaseOnAPIVersion(outFile)) { + return ERR_ZLIB_DEST_FILE_DISABLED; + } + if ((srcFileDir.Value().size() == 0) || LIBZIP::FilePath::HasRelativePathBaseOnAPIVersion(inFile)) { + APP_LOGI("srcFile doesn't Exist"); + return ERR_ZLIB_SRC_FILE_DISABLED; + } + if (!LIBZIP::FilePath::PathIsValid(srcFileDir)) { + APP_LOGI("srcFile invalid"); + return ERR_ZLIB_SRC_FILE_DISABLED; + } + if (LIBZIP::FilePath::DirectoryExists(destDir)) { + if (!LIBZIP::FilePath::PathIsWriteable(destDir)) { + APP_LOGI("FilePath::PathIsWriteable(destDir) fail"); + return ERR_ZLIB_DEST_FILE_DISABLED; + } + } else { + APP_LOGI("destDir isn't path"); + return ERR_ZLIB_DEST_FILE_DISABLED; + } + + ANIUnzipParam unzipParam { .filterCB = ANIExcludeNoFilesFilter, .logSkippedFiles = true }; + return ANIUnzipWithFilterCallback(srcFileDir, destDir, options, unzipParam); +} + +bool ANIZip(const ZipParams& params, const OPTIONS& options) +{ + const std::vector>* filesToAdd = ¶ms.GetFilesTozip(); + std::vector> allRelativeFiles; + FilePath srcDir = params.SrcDir().front(); + FilePath paramPath = ANIFilePathEndIsSeparator(srcDir); + if (filesToAdd->empty()) { + filesToAdd = &allRelativeFiles; + std::list entries; + if (EndsWith(paramPath.Value(), SEPARATOR)) { + entries.push_back(FileAccessor::DirectoryContentEntry(srcDir, true)); + FilterCallback filterCallback = params.GetFilterCallback(); + for (auto iter = entries.begin(); iter != entries.end(); ++iter) { + if (iter != entries.begin() && ((!params.GetIncludeHiddenFiles() && ANIIsHiddenFile(iter->path)) || + (filterCallback && !filterCallback(iter->path)))) { + continue; + } + if (iter != entries.begin()) { + FilePath relativePath; + FilePath paramsSrcPath = srcDir; + if (paramsSrcPath.AppendRelativePath(iter->path, &relativePath)) { + allRelativeFiles.push_back(std::make_pair(relativePath, iter->path)); + } + } + if (iter->isDirectory) { + bool isSuccess = false; + std::vector subEntries = + ANIListDirectoryContent(iter->path, isSuccess); + entries.insert(entries.end(), subEntries.begin(), subEntries.end()); + } + } + } else { + allRelativeFiles.push_back(std::make_pair(paramPath.BaseName(), paramPath)); + } + } + std::unique_ptr zipWriter = nullptr; + if (params.DestFd() != kInvalidPlatformFile) { + zipWriter = std::make_unique(ZipWriter::InitZipFileWithFd(params.DestFd())); + } else { + zipWriter = std::make_unique(ZipWriter::InitZipFileWithFile(params.DestFile())); + } + if (zipWriter == nullptr) { + APP_LOGE("Init zipWriter failed"); + return false; + } + return zipWriter->WriteEntries(*filesToAdd, options); +} + +ErrCode ANIZipWithFilterCallback( + const FilePath& srcDir, const FilePath& destFile, const OPTIONS& options, FilterCallback filterCB) +{ + FilePath destPath = destFile; + if (!FilePath::DirectoryExists(destPath.DirName())) { + APP_LOGE("The destPath not exist"); + return ERR_ZLIB_DEST_FILE_DISABLED; + } + if (!FilePath::PathIsWriteable(destPath.DirName())) { + APP_LOGE("The destPath not writeable"); + return ERR_ZLIB_DEST_FILE_DISABLED; + } + + if (!FilePath::PathIsValid(srcDir)) { + APP_LOGI("srcDir isn't Exist"); + return ERR_ZLIB_SRC_FILE_DISABLED; + } else if (!FilePath::PathIsReadable(srcDir)) { + APP_LOGI("srcDir not readable"); + return ERR_ZLIB_SRC_FILE_DISABLED; + } + + std::vector srcFile = { srcDir }; + ZipParams params(srcFile, FilePath(destPath.CheckDestDirTail())); + params.SetFilterCallback(filterCB); + return ANIZip(params, options) ? ERR_OK : ERR_ZLIB_DEST_FILE_DISABLED; +} + +ErrCode ANICompressFileImpl(const std::string& inFile, const std::string& outFile, const LIBZIP::OPTIONS& options) +{ + LIBZIP::FilePath srcFileDir(inFile); + LIBZIP::FilePath destDir(outFile); + if ((destDir.Value().size() == 0) || LIBZIP::FilePath::HasRelativePathBaseOnAPIVersion(outFile)) { + return ERR_ZLIB_DEST_FILE_DISABLED; + } + if ((srcFileDir.Value().size() == 0) || LIBZIP::FilePath::HasRelativePathBaseOnAPIVersion(inFile)) { + return ERR_ZLIB_SRC_FILE_DISABLED; + } + + return ANIZipWithFilterCallback(srcFileDir, destDir, options, ANIExcludeHiddenFilesFilter); +} +} // namespace LIBZIP +} // namespace AppExecFwk +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/ani/zlib/ani_zip.h b/interfaces/kits/ani/zlib/ani_zip.h new file mode 100644 index 0000000000000000000000000000000000000000..3e2286fb3af6d308628181e504120a10021b0326 --- /dev/null +++ b/interfaces/kits/ani/zlib/ani_zip.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 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. + */ + +#ifndef BUNDLE_FRAMEWORK_INTERFACES_KITS_ANI_ZLIB_H +#define BUNDLE_FRAMEWORK_INTERFACES_KITS_ANI_ZLIB_H + +#include "app_log_wrapper.h" +#include "bundle_errors.h" +#include "business_error_ani.h" +#include "common_fun_ani.h" +#include "common_func.h" +#include "enum_util.h" +#include "file_path.h" +#include "zip_utils.h" + +namespace OHOS { +namespace AppExecFwk { +namespace LIBZIP { +bool ANIParseOptions(ani_env* env, ani_object object, LIBZIP::OPTIONS& options); +ErrCode ANICompressFileImpl(const std::string& inFile, const std::string& outFile, const LIBZIP::OPTIONS& options); +ErrCode ANIDecompressFileImpl(const std::string& inFile, const std::string& outFile, const LIBZIP::OPTIONS& options); +} // namespace LIBZIP +} // namespace AppExecFwk +} // namespace OHOS + +#endif \ No newline at end of file diff --git a/interfaces/kits/ani/zlib/ani_zlib.cpp b/interfaces/kits/ani/zlib/ani_zlib.cpp new file mode 100644 index 0000000000000000000000000000000000000000..91863bb7afa2151f169636fc3d078bfaf3e53044 --- /dev/null +++ b/interfaces/kits/ani/zlib/ani_zlib.cpp @@ -0,0 +1,127 @@ +/* + * Copyright (c) 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 "ani_zip.h" +#include "common_func.h" + +namespace OHOS { +namespace AppExecFwk { + +namespace { +constexpr const char* PARAM_NAME_IN_FILE = "inFile"; +constexpr const char* PARAM_NAME_OUT_FILE = "outFile"; +constexpr const char* PARAM_NAME_OPTIONS = "options"; +constexpr const char* TYPE_STRING = "string"; +} // namespace + +static void CompressFile(ani_env* env, ani_string aniInFile, ani_string aniOutFile, ani_object aniOptions) +{ + std::string inFile = CommonFunAni::AniStrToString(env, aniInFile); + if (inFile.empty()) { + APP_LOGE("inFile is empty."); + BusinessErrorAni::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAM_NAME_IN_FILE, TYPE_STRING); + return; + } + + std::string outFile = CommonFunAni::AniStrToString(env, aniOutFile); + if (inFile.empty()) { + APP_LOGE("inFile is empty."); + BusinessErrorAni::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAM_NAME_OUT_FILE, TYPE_STRING); + return; + } + + LIBZIP::OPTIONS options; + if (!LIBZIP::ANIParseOptions(env, aniOptions, options)) { + APP_LOGE("options parse failed."); + BusinessErrorAni::ThrowError(env, ERROR_PARAM_CHECK_ERROR, PARAM_NAME_OPTIONS); + return; + } + + int32_t errCode = CommonFunc::ConvertErrCode(LIBZIP::ANICompressFileImpl(inFile, outFile, options)); + if (errCode != ERR_OK) { + APP_LOGE("DecompressFile failed, ret %{public}d", errCode); + BusinessErrorAni::ThrowParameterTypeError(env, errCode, "", ""); + } +} + +static void DecompressFile(ani_env* env, ani_string aniInFile, ani_string aniOutFile, ani_object aniOptions) +{ + APP_LOGE("DecompressFile entry"); + std::string inFile = CommonFunAni::AniStrToString(env, aniInFile); + if (inFile.empty()) { + APP_LOGE("inFile is empty."); + BusinessErrorAni::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAM_NAME_IN_FILE, TYPE_STRING); + return; + } + + std::string outFile = CommonFunAni::AniStrToString(env, aniOutFile); + if (inFile.empty()) { + APP_LOGE("inFile is empty."); + BusinessErrorAni::ThrowParameterTypeError(env, ERROR_PARAM_CHECK_ERROR, PARAM_NAME_OUT_FILE, TYPE_STRING); + return; + } + + LIBZIP::OPTIONS options; + if (!LIBZIP::ANIParseOptions(env, aniOptions, options)) { + APP_LOGE("options parse failed."); + BusinessErrorAni::ThrowError(env, ERROR_PARAM_CHECK_ERROR, PARAM_NAME_OPTIONS); + return; + } + + int32_t errCode = CommonFunc::ConvertErrCode(LIBZIP::ANIDecompressFileImpl(inFile, outFile, options)); + if (errCode != ERR_OK) { + APP_LOGE("DecompressFile failed, ret %{public}d", errCode); + BusinessErrorAni::ThrowParameterTypeError(env, errCode, "", ""); + } +} + +extern "C" { +ANI_EXPORT ani_status ANI_Constructor(ani_vm* vm, uint32_t* result) +{ + APP_LOGI("ANI_Constructor zlib called"); + ani_env* env; + ani_status status = vm->GetEnv(ANI_VERSION_1, &env); + if (status != ANI_OK) { + APP_LOGE("Unsupported ANI_VERSION_1: %{public}d", status); + return status; + } + + static const char* nsName = "L@ohos/zlib/zlib;"; + ani_namespace kitNs = nullptr; + status = env->FindNamespace(nsName, &kitNs); + if (status != ANI_OK) { + APP_LOGE("FindNamespace: %{public}s fail with %{public}d", nsName, status); + return status; + } + + std::array methods = { + ani_native_function { "CompressFile", nullptr, reinterpret_cast(CompressFile) }, + ani_native_function { "DecompressFile", nullptr, reinterpret_cast(DecompressFile) }, + }; + + status = env->Namespace_BindNativeFunctions(kitNs, methods.data(), methods.size()); + if (status != ANI_OK) { + APP_LOGE("Namespace_BindNativeFunctions: %{public}s fail with %{public}d", nsName, status); + return status; + } + + *result = ANI_VERSION_1; + + APP_LOGI("ANI_Constructor finished"); + + return ANI_OK; +} +} +} // namespace AppExecFwk +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/ani/zlib/ets/@ohos.zlib.ets b/interfaces/kits/ani/zlib/ets/@ohos.zlib.ets new file mode 100644 index 0000000000000000000000000000000000000000..c017a381acd8cb3b55354634a71ae9bbba8dd76b --- /dev/null +++ b/interfaces/kits/ani/zlib/ets/@ohos.zlib.ets @@ -0,0 +1,132 @@ +/* + * Copyright (c) 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. + */ + +/** + * @file + * @kit BasicServicesKit + */ + +import { AsyncCallback, BusinessError } from '@ohos.base'; + +export default namespace zlib { + + loadLibrary("ani_zlib.z"); + + export enum CompressLevel { + COMPRESS_LEVEL_NO_COMPRESSION = 0, + COMPRESS_LEVEL_BEST_SPEED = 1, + COMPRESS_LEVEL_BEST_COMPRESSION = 9, + COMPRESS_LEVEL_DEFAULT_COMPRESSION = -1 + } + + export enum CompressStrategy { + COMPRESS_STRATEGY_DEFAULT_STRATEGY = 0, + COMPRESS_STRATEGY_FILTERED = 1, + COMPRESS_STRATEGY_HUFFMAN_ONLY = 2, + COMPRESS_STRATEGY_RLE = 3, + COMPRESS_STRATEGY_FIXED = 4 + } + + export enum MemLevel { + MEM_LEVEL_MIN = 1, + MEM_LEVEL_MAX = 9, + MEM_LEVEL_DEFAULT = 8 + } + + export interface Options { + level?: CompressLevel; + memLevel?: MemLevel; + strategy?: CompressStrategy; + } + + class OptionsInner implements Options { + level?: CompressLevel | undefined = CompressLevel.COMPRESS_LEVEL_DEFAULT_COMPRESSION; + memLevel?: MemLevel | undefined = MemLevel.MEM_LEVEL_DEFAULT; + strategy?: CompressStrategy | undefined = CompressStrategy.COMPRESS_STRATEGY_DEFAULT_STRATEGY; + } + + export function compressFile(inFile: string, outFile: string, options: Options, callback: AsyncCallback): void { + let execFun = (): void => { + zlib.CompressFile(inFile, outFile, options); + }; + let p1 = taskpool.execute(execFun); + p1.then(() => { + let r = new BusinessError(); + callback(r, undefined); + }).catch((err: BusinessError): void => { + callback(err, undefined); + }); + } + + export function compressFile(inFile: string, outFile: string, options: Options): Promise { + let p: Promise = new Promise((resolve: (v:undefined) => void, reject: (error: Object) => void) : void => { + let execFun = (): void => { + zlib.CompressFile(inFile, outFile, options); + }; + let p1 = taskpool.execute(execFun); + p1.then((): void => { + resolve(undefined); + }, (err: BusinessError): void => { + reject(err); + }); + }); + return p; + } + + export native function CompressFile(inFile: string, outFile: string, options?: Options): void; + + export function decompressFile(inFile: string, outFile: string, options: Options, callback: AsyncCallback): void { + let execFun = (): void => { + zlib.DecompressFile(inFile, outFile, options); + }; + let p1 = taskpool.execute(execFun); + p1.then(() => { + let r = new BusinessError(); + callback(r, undefined); + }).catch((err: BusinessError): void => { + callback(err, undefined); + }); + } + + export function decompressFile(inFile: string, outFile: string, callback: AsyncCallback): void { + let execFun = (): void => { + zlib.DecompressFile(inFile, outFile, undefined); + }; + let p1 = taskpool.execute(execFun); + p1.then(() => { + let r = new BusinessError(); + callback(r, undefined); + }).catch((err: BusinessError): void => { + callback(err, undefined); + }); + } + + export function decompressFile(inFile: string, outFile: string, options?: Options): Promise { + let p: Promise = new Promise((resolve: (v:undefined) => void, reject: (error: Object) => void) : void => { + let execFun = (): void => { + zlib.DecompressFile(inFile, outFile, options); + }; + let p1 = taskpool.execute(execFun); + p1.then((): void => { + resolve(undefined); + }, (err: BusinessError): void => { + reject(err); + }); + }); + return p; + } + + export native function DecompressFile(inFile: string, outFile: string, options?: Options): void; +} \ No newline at end of file diff --git a/interfaces/kits/js/BUILD.gn b/interfaces/kits/js/BUILD.gn index afd39f8f18cce65ac0f1c0bd292c511a1bbc68f8..e62a011e4850bf1bf86b0025c9efd720a85054c8 100644 --- a/interfaces/kits/js/BUILD.gn +++ b/interfaces/kits/js/BUILD.gn @@ -25,12 +25,14 @@ group("napi_packages") { "app_control:appcontrol", "bundle_manager:bundlemanager", "bundle_monitor:bundlemonitor", + "bundle_resource:bundle_res_common", "bundle_resource:bundleresourcemanager", "bundlemgr:bundle", "default_app:defaultappmanager", "free_install:freeinstall", "installer:installer", "launcher_bundle_manager:launcherbundlemanager", + "launcher_bundle_manager:launcherbundlemanager_common", "launchermgr:innerbundlemanager", "overlay:overlay", "package:package", diff --git a/interfaces/kits/js/bundle_resource/BUILD.gn b/interfaces/kits/js/bundle_resource/BUILD.gn index 9f9bfc213ec3121eb0803a34909610dfdc49ad5c..815462d5f590b59a4054e9196a958c08cc61a933 100644 --- a/interfaces/kits/js/bundle_resource/BUILD.gn +++ b/interfaces/kits/js/bundle_resource/BUILD.gn @@ -14,6 +14,54 @@ import("//build/ohos.gni") import("../../../../appexecfwk.gni") +ohos_shared_library("bundle_res_common") { + branch_protector_ret = "pac_ret" + + sanitize = { + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + integer_overflow = true + ubsan = true + } + + sources = [ "resource_helper.cpp" ] + + cflags = [ + "-Os", + "-fstack-protector-strong", + ] + + cflags_cc = [ + "-Os", + "-fstack-protector-strong", + ] + + deps = [ + "${base_path}:appexecfwk_base", + "${common_path}:libappexecfwk_common", + "${core_path}:appexecfwk_core", + ] + + defines = [ + "APP_LOG_TAG = \"BMS\"", + "LOG_DOMAIN = 0xD001120", + ] + + external_deps = [ + "c_utils:utils", + "hilog:libhilog", + "ipc:ipc_core", + "runtime_core:ani", + "safwk:system_ability_fwk", + "samgr:samgr_proxy", + ] + + subsystem_name = "bundlemanager" + part_name = "bundle_framework" +} + ohos_shared_library("bundleresourcemanager") { branch_protector_ret = "pac_ret" @@ -29,6 +77,7 @@ ohos_shared_library("bundleresourcemanager") { include_dirs = [ "${inner_api_path}/bundlemgr_resource/include", "${kits_path}/js/common", + "${kits_path}/js/resource_comm", ] defines = [ "APP_LOG_TAG = \"BMS\"", @@ -37,6 +86,7 @@ ohos_shared_library("bundleresourcemanager") { sources = [ "native_module.cpp" ] deps = [ + ":bundle_res_common", "${base_path}:appexecfwk_base", "${common_path}:libappexecfwk_common", "${core_path}:appexecfwk_core", diff --git a/interfaces/kits/js/bundle_resource/bundle_resource.cpp b/interfaces/kits/js/bundle_resource/bundle_resource.cpp index 4e40e237da2a40d268fd98a4fa58ab2b95824ba5..bad6f70af38b5d1c5bcddc1b8c405f1cf447d355 100644 --- a/interfaces/kits/js/bundle_resource/bundle_resource.cpp +++ b/interfaces/kits/js/bundle_resource/bundle_resource.cpp @@ -28,6 +28,7 @@ #include "napi/native_api.h" #include "napi/native_common.h" #include "napi/native_node_api.h" +#include "resource_helper.h" #include "system_ability_definition.h" namespace OHOS { @@ -57,55 +58,6 @@ constexpr const char* GET_RESOURCE_INFO_WITH_DRAWABLE_DESCRIPTOR = "GET_RESOURCE constexpr const char* EXTENSION_ABILITY_TYPE = "extensionAbilityType"; constexpr const char* GET_RESOURCE_INFO_ONLY_WITH_MAIN_ABILITY = "GET_RESOURCE_INFO_ONLY_WITH_MAIN_ABILITY"; -class ResourceHelper { -public: - static sptr GetBundleResourceMgr(); - -private: - class BundleResourceMgrDeathRecipient : public IRemoteObject::DeathRecipient { - void OnRemoteDied([[maybe_unused]] const wptr& remote) override; - }; - static sptr bundleResourceMgr_; - static std::mutex bundleResourceMutex_; - static sptr deathRecipient_; -}; - -sptr ResourceHelper::bundleResourceMgr_ = nullptr; -std::mutex ResourceHelper::bundleResourceMutex_; -sptr ResourceHelper::deathRecipient_(sptr::MakeSptr()); - -void ResourceHelper::BundleResourceMgrDeathRecipient::OnRemoteDied([[maybe_unused]] const wptr& remote) -{ - APP_LOGI("BundleManagerService dead"); - std::lock_guard lock(bundleResourceMutex_); - bundleResourceMgr_ = nullptr; -}; - -sptr ResourceHelper::GetBundleResourceMgr() -{ - std::lock_guard lock(bundleResourceMutex_); - if (bundleResourceMgr_ == nullptr) { - auto systemAbilityManager = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); - if (systemAbilityManager == nullptr) { - APP_LOGE("systemAbilityManager is null"); - return nullptr; - } - auto bundleMgrSa = systemAbilityManager->GetSystemAbility(OHOS::BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); - if (bundleMgrSa == nullptr) { - APP_LOGE("bundleMgrSa is null"); - return nullptr; - } - auto bundleMgr = OHOS::iface_cast(bundleMgrSa); - if (bundleMgr == nullptr) { - APP_LOGE("iface_cast failed"); - return nullptr; - } - bundleMgr->AsObject()->AddDeathRecipient(deathRecipient_); - bundleResourceMgr_ = bundleMgr->GetBundleResourceProxy(); - } - return bundleResourceMgr_; -} - static void ConvertBundleResourceInfo( napi_env env, const BundleResourceInfo &bundleResourceInfo, diff --git a/interfaces/kits/js/bundle_resource/resource_helper.cpp b/interfaces/kits/js/bundle_resource/resource_helper.cpp new file mode 100644 index 0000000000000000000000000000000000000000..eaeb62ce99d44ad8520075be652ae3a96f5f36c6 --- /dev/null +++ b/interfaces/kits/js/bundle_resource/resource_helper.cpp @@ -0,0 +1,62 @@ +/* +* Copyright (c) 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 "resource_helper.h" +#include "app_log_wrapper.h" +#include "iservice_registry.h" +#include "system_ability_definition.h" +#include "bundle_mgr_interface.h" +#include "bundle_mgr_proxy.h" + +namespace OHOS { +namespace AppExecFwk { + +sptr ResourceHelper::bundleResourceMgr_ = nullptr; +std::mutex ResourceHelper::bundleResourceMutex_; +sptr ResourceHelper::deathRecipient_(sptr::MakeSptr()); + +void ResourceHelper::BundleResourceMgrDeathRecipient::OnRemoteDied([[maybe_unused]] const wptr& remote) +{ + APP_LOGI("BundleManagerService dead"); + std::lock_guard lock(bundleResourceMutex_); + bundleResourceMgr_ = nullptr; +}; + +sptr ResourceHelper::GetBundleResourceMgr() +{ + std::lock_guard lock(bundleResourceMutex_); + if (bundleResourceMgr_ == nullptr) { + auto systemAbilityManager = OHOS::SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); + if (systemAbilityManager == nullptr) { + APP_LOGE("systemAbilityManager is null"); + return nullptr; + } + auto bundleMgrSa = systemAbilityManager->GetSystemAbility(OHOS::BUNDLE_MGR_SERVICE_SYS_ABILITY_ID); + if (bundleMgrSa == nullptr) { + APP_LOGE("bundleMgrSa is null"); + return nullptr; + } + auto bundleMgr = OHOS::iface_cast(bundleMgrSa); + if (bundleMgr == nullptr) { + APP_LOGE("iface_cast failed"); + return nullptr; + } + bundleMgr->AsObject()->AddDeathRecipient(deathRecipient_); + bundleResourceMgr_ = bundleMgr->GetBundleResourceProxy(); + } + return bundleResourceMgr_; +} + +} // AppExecFwk +} // OHOS \ No newline at end of file diff --git a/interfaces/kits/js/bundle_resource/resource_helper.h b/interfaces/kits/js/bundle_resource/resource_helper.h new file mode 100644 index 0000000000000000000000000000000000000000..8f30c4d8e6c50309fe0746d06b52cad28e7798e5 --- /dev/null +++ b/interfaces/kits/js/bundle_resource/resource_helper.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 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. + */ + +#ifndef BUNDLE_FRAMEWORK_INTERFACES_KITS_JS_RESOURCE_HELPER_H +#define BUNDLE_FRAMEWORK_INTERFACES_KITS_JS_RESOURCE_HELPER_H + +#include "bundle_resource_interface.h" +#include "bundle_resource_info.h" +#include "iservice_registry.h" + +namespace OHOS { +namespace AppExecFwk { +class ResourceHelper { +public: + static sptr GetBundleResourceMgr(); + +private: + class BundleResourceMgrDeathRecipient : public IRemoteObject::DeathRecipient { + void OnRemoteDied([[maybe_unused]] const wptr& remote) override; + }; + static sptr bundleResourceMgr_; + static std::mutex bundleResourceMutex_; + static sptr deathRecipient_; +}; +} // AppExecFwk +} // OHOS +#endif \ No newline at end of file diff --git a/interfaces/kits/js/installer/BUILD.gn b/interfaces/kits/js/installer/BUILD.gn index 8d5b8df0af2ef6c0276f2e8f892517745c57ace6..624313f1d4511df18e4ae672f079a7bac9bceb42 100755 --- a/interfaces/kits/js/installer/BUILD.gn +++ b/interfaces/kits/js/installer/BUILD.gn @@ -65,6 +65,7 @@ ohos_shared_library("installer") { "${kits_path}/js/bundlemgr/bundle_death_recipient.cpp", "${kits_path}/js/bundlemgr/installer_callback.cpp", "installer.cpp", + "installer_helper.cpp", "native_module.cpp", ] external_deps += [ diff --git a/interfaces/kits/js/installer/installer.cpp b/interfaces/kits/js/installer/installer.cpp index 8598bf7cd9b5b30c70ac92fc0db62137031a0088..544a0ed8198183cca7c1604244a0a7e27975bce8 100644 --- a/interfaces/kits/js/installer/installer.cpp +++ b/interfaces/kits/js/installer/installer.cpp @@ -27,6 +27,7 @@ #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" @@ -242,216 +243,6 @@ napi_value GetBundleInstallerSync(napi_env env, napi_callback_info info) APP_LOGI("call GetBundleInstallerSync done"); } -static void CreateErrCodeMap(std::unordered_map &errCodeMap) -{ - errCodeMap = { - { IStatusReceiver::SUCCESS, SUCCESS}, - { IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION }, - { IStatusReceiver::ERR_INSTALL_HOST_INSTALLER_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION }, - { IStatusReceiver::ERR_INSTALLD_PARAM_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION }, - { IStatusReceiver::ERR_INSTALLD_GET_PROXY_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION }, - { IStatusReceiver::ERR_INSTALL_INSTALLD_SERVICE_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION }, - { IStatusReceiver::ERR_UNINSTALL_BUNDLE_MGR_SERVICE_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION }, - { IStatusReceiver::ERR_FAILED_SERVICE_DIED, ERROR_BUNDLE_SERVICE_EXCEPTION }, - { IStatusReceiver::ERR_FAILED_GET_INSTALLER_PROXY, ERROR_BUNDLE_SERVICE_EXCEPTION }, - { IStatusReceiver::ERR_USER_CREATE_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION }, - { IStatusReceiver::ERR_USER_REMOVE_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION }, - { IStatusReceiver::ERR_UNINSTALL_KILLING_APP_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION }, - { IStatusReceiver::ERR_INSTALL_GENERATE_UID_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION }, - { IStatusReceiver::ERR_INSTALL_STATE_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION }, - { IStatusReceiver::ERR_RECOVER_NOT_ALLOWED, ERROR_BUNDLE_SERVICE_EXCEPTION }, - { IStatusReceiver::ERR_RECOVER_GET_BUNDLEPATH_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION }, - { IStatusReceiver::ERR_UNINSTALL_AND_RECOVER_NOT_PREINSTALLED_BUNDLE, ERROR_BUNDLE_NOT_PREINSTALLED }, - { IStatusReceiver::ERR_UNINSTALL_SYSTEM_APP_ERROR, ERROR_UNINSTALL_PREINSTALL_APP_FAILED }, - { IStatusReceiver::ERR_INSTALL_PARSE_FAILED, ERROR_INSTALL_PARSE_FAILED }, - { IStatusReceiver::ERR_INSTALL_PARSE_UNEXPECTED, ERROR_INSTALL_PARSE_FAILED }, - { IStatusReceiver::ERR_INSTALL_PARSE_MISSING_BUNDLE, ERROR_INSTALL_PARSE_FAILED }, - { IStatusReceiver::ERR_INSTALL_PARSE_NO_PROFILE, ERROR_INSTALL_PARSE_FAILED }, - { IStatusReceiver::ERR_INSTALL_PARSE_BAD_PROFILE, ERROR_INSTALL_PARSE_FAILED }, - { IStatusReceiver::ERR_INSTALL_PARSE_PROFILE_PROP_TYPE_ERROR, ERROR_INSTALL_PARSE_FAILED }, - { IStatusReceiver::ERR_INSTALL_PARSE_PROFILE_MISSING_PROP, ERROR_INSTALL_PARSE_FAILED }, - { IStatusReceiver::ERR_INSTALL_PARSE_PERMISSION_ERROR, ERROR_INSTALL_PARSE_FAILED }, - { IStatusReceiver::ERR_INSTALL_PARSE_PROFILE_PROP_CHECK_ERROR, ERROR_INSTALL_PARSE_FAILED }, - { IStatusReceiver::ERR_INSTALL_PARSE_RPCID_FAILED, ERROR_INSTALL_PARSE_FAILED }, - { IStatusReceiver::ERR_INSTALL_PARSE_NATIVE_SO_FAILED, ERROR_INSTALL_PARSE_FAILED }, - { IStatusReceiver::ERR_INSTALL_PARSE_AN_FAILED, ERROR_INSTALL_PARSE_FAILED }, - { IStatusReceiver::ERR_INSTALL_PARSE_MISSING_ABILITY, ERROR_INSTALL_PARSE_FAILED }, - { IStatusReceiver::ERR_INSTALL_FAILED_PROFILE_PARSE_FAIL, ERROR_INSTALL_PARSE_FAILED }, - { IStatusReceiver::ERR_INSTALL_VERIFICATION_FAILED, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, - { IStatusReceiver::ERR_INSTALL_FAILED_INCOMPATIBLE_SIGNATURE, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, - { IStatusReceiver::ERR_INSTALL_FAILED_INVALID_SIGNATURE_FILE_PATH, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, - { IStatusReceiver::ERR_INSTALL_FAILED_BAD_BUNDLE_SIGNATURE_FILE, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, - { IStatusReceiver::ERR_INSTALL_FAILED_NO_BUNDLE_SIGNATURE, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, - { IStatusReceiver::ERR_INSTALL_FAILED_VERIFY_APP_PKCS7_FAIL, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, - { IStatusReceiver::ERR_INSTALL_FAILED_APP_SOURCE_NOT_TRUESTED, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, - { IStatusReceiver::ERR_INSTALL_FAILED_BAD_DIGEST, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, - { IStatusReceiver::ERR_INSTALL_FAILED_BUNDLE_INTEGRITY_VERIFICATION_FAILURE, - ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, - { IStatusReceiver::ERR_INSTALL_FAILED_BAD_PUBLICKEY, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, - { IStatusReceiver::ERR_INSTALL_FAILED_BAD_BUNDLE_SIGNATURE, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, - { IStatusReceiver::ERR_INSTALL_FAILED_NO_PROFILE_BLOCK_FAIL, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, - { IStatusReceiver::ERR_INSTALL_FAILED_BUNDLE_SIGNATURE_VERIFICATION_FAILURE, - ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, - { IStatusReceiver::ERR_INSTALL_FAILED_VERIFY_SOURCE_INIT_FAIL, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, - { IStatusReceiver::ERR_INSTALL_FAILED_DEVICE_UNAUTHORIZED, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, - { IStatusReceiver::ERR_INSTALL_SINGLETON_INCOMPATIBLE, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, - { IStatusReceiver::ERR_INSTALL_U1_ENABLE_NOT_SAME_IN_ALL_BUNDLE_INFOS, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, - { IStatusReceiver::ERR_INSTALL_FAILED_INCONSISTENT_SIGNATURE, ERROR_INSTALL_FAILED_INCONSISTENT_SIGNATURE }, - { IStatusReceiver::ERR_INSTALL_PARAM_ERROR, ERROR_BUNDLE_NOT_EXIST }, - { IStatusReceiver::ERR_UNINSTALL_PARAM_ERROR, ERROR_BUNDLE_NOT_EXIST }, - { IStatusReceiver::ERR_RECOVER_INVALID_BUNDLE_NAME, ERROR_BUNDLE_NOT_EXIST }, - { IStatusReceiver::ERR_UNINSTALL_INVALID_NAME, ERROR_BUNDLE_NOT_EXIST }, - { IStatusReceiver::ERR_INSTALL_INVALID_BUNDLE_FILE, ERROR_INSTALL_HAP_FILEPATH_INVALID }, - { IStatusReceiver::ERR_INSTALL_FAILED_MODULE_NAME_EMPTY, ERROR_MODULE_NOT_EXIST }, - { IStatusReceiver::ERR_INSTALL_FAILED_MODULE_NAME_DUPLICATE, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_FAILED_CHECK_HAP_HASH_PARAM, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_UNINSTALL_MISSING_INSTALLED_BUNDLE, ERROR_BUNDLE_NOT_EXIST }, - { IStatusReceiver::ERR_UNINSTALL_MISSING_INSTALLED_MODULE, ERROR_MODULE_NOT_EXIST }, - { IStatusReceiver::ERR_USER_NOT_INSTALL_HAP, ERROR_BUNDLE_NOT_EXIST }, - { IStatusReceiver::ERR_INSTALL_FILE_PATH_INVALID, ERROR_INSTALL_HAP_FILEPATH_INVALID }, - { IStatusReceiver::ERR_INSTALL_PERMISSION_DENIED, ERROR_PERMISSION_DENIED_ERROR }, - { IStatusReceiver::ERR_UNINSTALL_PERMISSION_DENIED, ERROR_PERMISSION_DENIED_ERROR }, - { IStatusReceiver::ERR_INSTALL_GRANT_REQUEST_PERMISSIONS_FAILED, ERROR_INSTALL_PERMISSION_CHECK_ERROR }, - { IStatusReceiver::ERR_INSTALL_UPDATE_HAP_TOKEN_FAILED, ERROR_INSTALL_PERMISSION_CHECK_ERROR }, - { IStatusReceiver::ERR_INSTALLD_CREATE_DIR_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION }, - { IStatusReceiver::ERR_INSTALLD_CHOWN_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION }, - { IStatusReceiver::ERR_INSTALLD_CREATE_DIR_EXIST, ERROR_BUNDLE_SERVICE_EXCEPTION }, - { IStatusReceiver::ERR_INSTALLD_REMOVE_DIR_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION }, - { IStatusReceiver::ERR_INSTALLD_EXTRACT_FILES_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION }, - { IStatusReceiver::ERR_INSTALLD_RNAME_DIR_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION }, - { IStatusReceiver::ERR_INSTALLD_CLEAN_DIR_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION }, - { IStatusReceiver::ERR_INSTALL_ENTRY_ALREADY_EXIST, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_ALREADY_EXIST, ERROR_INSTALL_ALREADY_EXIST }, - { IStatusReceiver::ERR_INSTALL_BUNDLENAME_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_VERSIONCODE_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_VERSIONNAME_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_MINCOMPATIBLE_VERSIONCODE_NOT_SAME, - ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_VENDOR_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_RELEASETYPE_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_RELEASETYPE_TARGET_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_RELEASETYPE_COMPATIBLE_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_SINGLETON_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_ZERO_USER_WITH_NO_SINGLETON, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_CHECK_SYSCAP_FAILED, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_APPTYPE_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_URI_DUPLICATE, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_VERSION_NOT_COMPATIBLE, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_APP_DISTRIBUTION_TYPE_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_APP_PROVISION_TYPE_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_SO_INCOMPATIBLE, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_AN_INCOMPATIBLE, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_TYPE_ERROR, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_TYPE_ERROR, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_NOT_UNIQUE_DISTRO_MODULE_NAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_INCONSISTENT_MODULE_NAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_INVALID_NUMBER_OF_ENTRY_HAP, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_ASAN_ENABLED_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_ASAN_ENABLED_NOT_SUPPORT, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT}, - { IStatusReceiver::ERR_INSTALL_BUNDLE_TYPE_NOT_SAME, ERROR_INSTALL_PARSE_FAILED}, - { IStatusReceiver::ERR_INSTALL_DISK_MEM_INSUFFICIENT, ERROR_INSTALL_NO_DISK_SPACE_LEFT }, - { IStatusReceiver::ERR_USER_NOT_EXIST, ERROR_INVALID_USER_ID }, - { IStatusReceiver::ERR_INSTALL_VERSION_DOWNGRADE, ERROR_INSTALL_VERSION_DOWNGRADE }, - { IStatusReceiver::ERR_INSTALL_DEVICE_TYPE_NOT_SUPPORTED, ERROR_INSTALL_PARSE_FAILED }, - { IStatusReceiver::ERR_INSTALL_CHECK_SYSCAP_FAILED_AND_DEVICE_TYPE_NOT_SUPPORTED, ERROR_INSTALL_PARSE_FAILED }, - { IStatusReceiver::ERR_INSTALL_PARSE_PROFILE_PROP_SIZE_CHECK_ERROR, ERROR_INSTALL_PARSE_FAILED }, - { IStatusReceiver::ERR_INSTALL_DEPENDENT_MODULE_NOT_EXIST, ERROR_INSTALL_DEPENDENT_MODULE_NOT_EXIST }, - { IStatusReceiver::ERR_INSTALL_SHARE_APP_LIBRARY_NOT_ALLOWED, ERROR_INSTALL_SHARE_APP_LIBRARY_NOT_ALLOWED }, - { IStatusReceiver::ERR_INSTALL_COMPATIBLE_POLICY_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_FILE_IS_SHARED_LIBRARY, ERROR_INSTALL_FILE_IS_SHARED_LIBRARY }, - { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_INTERNAL_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION }, - { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_INVALID_BUNDLE_NAME, ERROR_BUNDLE_NOT_EXIST }, - { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_INVALID_MODULE_NAME, ERROR_MODULE_NOT_EXIST}, - { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_ERROR_HAP_TYPE, ERROR_INVALID_TYPE }, - { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_ERROR_BUNDLE_TYPE, ERROR_INVALID_TYPE }, - { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_TARGET_BUNDLE_NAME_MISSED, ERROR_INSTALL_PARSE_FAILED }, - { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_TARGET_MODULE_NAME_MISSED, ERROR_INSTALL_PARSE_FAILED }, - { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_TARGET_BUNDLE_NAME_NOT_SAME, - ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_INTERNAL_EXTERNAL_OVERLAY_EXISTED_SIMULTANEOUSLY, - ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_TARGET_PRIORITY_NOT_SAME, - ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_INVALID_PRIORITY, ERROR_INSTALL_PARSE_FAILED }, - { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_INCONSISTENT_VERSION_CODE, - ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_SERVICE_EXCEPTION, ERROR_BUNDLE_SERVICE_EXCEPTION }, - { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_BUNDLE_NAME_SAME_WITH_TARGET_BUNDLE_NAME, - ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT}, - { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_NO_SYSTEM_APPLICATION_FOR_EXTERNAL_OVERLAY, - ERROR_INSTALL_HAP_OVERLAY_CHECK_FAILED }, - { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_DIFFERENT_SIGNATURE_CERTIFICATE, - ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, - { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_TARGET_BUNDLE_IS_OVERLAY_BUNDLE, - ERROR_INSTALL_HAP_OVERLAY_CHECK_FAILED }, - {IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_TARGET_MODULE_IS_OVERLAY_MODULE, - ERROR_INSTALL_HAP_OVERLAY_CHECK_FAILED }, - { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_OVERLAY_TYPE_NOT_SAME, - ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_INVALID_BUNDLE_DIR, ERROR_BUNDLE_SERVICE_EXCEPTION }, - { IStatusReceiver::ERR_APPEXECFWK_UNINSTALL_SHARE_APP_LIBRARY_IS_NOT_EXIST, - ERROR_UNINSTALL_SHARE_APP_LIBRARY_IS_NOT_EXIST}, - { IStatusReceiver::ERR_APPEXECFWK_UNINSTALL_SHARE_APP_LIBRARY_IS_RELIED, - ERROR_UNINSTALL_SHARE_APP_LIBRARY_IS_RELIED}, - { IStatusReceiver::ERR_APPEXECFWK_UNINSTALL_BUNDLE_IS_SHARED_LIBRARY, - ERROR_UNINSTALL_BUNDLE_IS_SHARED_BUNDLE}, - { IStatusReceiver::ERR_INSATLL_CHECK_PROXY_DATA_URI_FAILED, - ERROR_INSTALL_WRONG_DATA_PROXY_URI}, - { IStatusReceiver::ERR_INSATLL_CHECK_PROXY_DATA_PERMISSION_FAILED, - ERROR_INSTALL_WRONG_DATA_PROXY_PERMISSION}, - { IStatusReceiver::ERR_INSTALL_FAILED_DEBUG_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, - { IStatusReceiver::ERR_INSTALL_DISALLOWED, ERROR_DISALLOW_INSTALL}, - { IStatusReceiver::ERR_INSTALL_ISOLATION_MODE_FAILED, ERROR_INSTALL_WRONG_MODE_ISOLATION }, - { IStatusReceiver::ERR_UNINSTALL_DISALLOWED, ERROR_DISALLOW_UNINSTALL }, - { IStatusReceiver::ERR_INSTALL_CODE_SIGNATURE_FAILED, ERROR_INSTALL_CODE_SIGNATURE_FAILED }, - { IStatusReceiver::ERR_INSTALL_CODE_SIGNATURE_FILE_IS_INVALID, ERROR_INSTALL_CODE_SIGNATURE_FAILED}, - { IStatusReceiver::ERR_UNINSTALL_FROM_BMS_EXTENSION_FAILED, ERROR_BUNDLE_NOT_EXIST}, - { IStatusReceiver::ERR_INSTALL_SELF_UPDATE_NOT_MDM, ERROR_INSTALL_SELF_UPDATE_NOT_MDM}, - { IStatusReceiver::ERR_INSTALL_ENTERPRISE_BUNDLE_NOT_ALLOWED, ERROR_INSTALL_ENTERPRISE_BUNDLE_NOT_ALLOWED}, - { IStatusReceiver::ERR_INSTALL_EXISTED_ENTERPRISE_BUNDLE_NOT_ALLOWED, - ERROR_INSTALL_EXISTED_ENTERPRISE_NOT_ALLOWED_ERROR}, - { IStatusReceiver::ERR_INSTALL_SELF_UPDATE_BUNDLENAME_NOT_SAME, ERROR_INSTALL_SELF_UPDATE_BUNDLENAME_NOT_SAME}, - { IStatusReceiver::ERR_INSTALL_GWP_ASAN_ENABLED_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT}, - { IStatusReceiver::ERR_INSTALL_DEBUG_BUNDLE_NOT_ALLOWED, ERROR_INSTALL_DEBUG_BUNDLE_NOT_ALLOWED}, - { IStatusReceiver::ERR_INSTALL_CHECK_ENCRYPTION_FAILED, ERROR_INSTALL_CODE_SIGNATURE_FAILED }, - { IStatusReceiver::ERR_INSTALL_CODE_SIGNATURE_DELIVERY_FILE_FAILED, ERROR_INSTALL_CODE_SIGNATURE_FAILED}, - { IStatusReceiver::ERR_INSTALL_CODE_SIGNATURE_REMOVE_FILE_FAILED, ERROR_INSTALL_CODE_SIGNATURE_FAILED}, - { IStatusReceiver::ERR_INSTALL_CODE_APP_CONTROLLED_FAILED, ERROR_INSTALL_FAILED_CONTROLLED}, - { IStatusReceiver::ERR_APPEXECFWK_INSTALL_FORCE_UNINSTALLED_BUNDLE_NOT_ALLOW_RECOVER, - ERROR_INSTALL_FAILED_CONTROLLED}, - { IStatusReceiver::ERR_APPEXECFWK_INSTALL_PREINSTALL_BUNDLE_ONLY_ALLOW_FORCE_UNINSTALLED_BY_EDC, - ERROR_INSTALL_FAILED_CONTROLLED}, - { IStatusReceiver::ERR_INSTALL_NATIVE_FAILED, ERROR_INSTALL_NATIVE_FAILED}, - { IStatusReceiver::ERR_UNINSTALL_NATIVE_FAILED, ERROR_UNINSTALL_NATIVE_FAILED}, - { IStatusReceiver::ERR_UNINSTALL_DISPOSED_RULE_DENIED, ERROR_APPLICATION_UNINSTALL}, - { IStatusReceiver::ERR_NATIVE_HNP_EXTRACT_FAILED, ERROR_INSTALL_NATIVE_FAILED}, - { IStatusReceiver::ERR_UNINSTALL_CONTROLLED, ERROR_BUNDLE_CAN_NOT_BE_UNINSTALLED }, - { IStatusReceiver::ERR_INSTALL_DEBUG_ENCRYPTED_BUNDLE_FAILED, ERROR_INSTALL_PARSE_FAILED }, - { IStatusReceiver::ERR_APP_DISTRIBUTION_TYPE_NOT_ALLOW_INSTALL_ISR, - ERROR_APP_DISTRIBUTION_TYPE_NOT_ALLOW_INSTALL}, - { IStatusReceiver::ERR_INSTALL_FAILED_AND_RESTORE_TO_PREINSTALLED, - ERROR_INSTALL_FAILED_AND_RESTORE_TO_PREINSTALLED }, - { IStatusReceiver::ERR_INSTALL_U1ENABLE_CAN_ONLY_INSTALL_IN_U1_WITH_NOT_SINGLETON, - ERROR_INSTALL_FAILED_CONTROLLED }, - { IStatusReceiver::ERR_INSTALL_BUNDLE_EXISTED_IN_U1_AND_OTHER_USERS, - ERROR_INSTALL_FAILED_CONTROLLED }, - }; -} - -static void ConvertInstallResult(InstallResult &installResult) -{ - APP_LOGD("ConvertInstallResult msg %{public}s, errCode is %{public}d", installResult.resultMsg.c_str(), - installResult.resultCode); - std::unordered_map errCodeMap; - CreateErrCodeMap(errCodeMap); - auto iter = errCodeMap.find(installResult.resultCode); - if (iter != errCodeMap.end()) { - installResult.resultCode = iter->second; - return; - } - installResult.resultCode = ERROR_BUNDLE_SERVICE_EXCEPTION; -} - static bool ParseHashParam(napi_env env, napi_value args, std::string &key, std::string &value) { APP_LOGD("start to parse moduleName"); @@ -964,18 +755,6 @@ static bool ParseUninstallParam(napi_env env, napi_value args, UninstallParam &u return true; } -static void CreateProxyErrCode(std::unordered_map &errCodeMap) -{ - errCodeMap = { - { ERR_APPEXECFWK_INSTALL_PARAM_ERROR, IStatusReceiver::ERR_INSTALL_PARAM_ERROR }, - { ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR, IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR }, - { ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID, IStatusReceiver::ERR_INSTALL_FILE_PATH_INVALID }, - { ERR_APPEXECFWK_INSTALL_DISK_MEM_INSUFFICIENT, IStatusReceiver::ERR_INSTALL_DISK_MEM_INSUFFICIENT }, - { ERR_BUNDLEMANAGER_INSTALL_CODE_SIGNATURE_FILE_IS_INVALID, - IStatusReceiver::ERR_INSTALL_CODE_SIGNATURE_FILE_IS_INVALID} - }; -} - void InstallExecuter(napi_env env, void *data) { AsyncInstallCallbackInfo *asyncCallbackInfo = reinterpret_cast(data); @@ -1015,7 +794,7 @@ void InstallExecuter(napi_env env, void *data) } APP_LOGE("install failed due to %{public}d", res); std::unordered_map proxyErrCodeMap; - CreateProxyErrCode(proxyErrCodeMap); + InstallerHelper::CreateProxyErrCode(proxyErrCodeMap); if (proxyErrCodeMap.find(res) != proxyErrCodeMap.end()) { installResult.resultCode = proxyErrCodeMap.at(res); } else { @@ -1044,7 +823,7 @@ void OperationCompleted(napi_env env, napi_status status, void *data) AsyncInstallCallbackInfo *asyncCallbackInfo = reinterpret_cast(data); std::unique_ptr callbackPtr {asyncCallbackInfo}; napi_value result[CALLBACK_PARAM_SIZE] = {0}; - ConvertInstallResult(callbackPtr->installResult); + InstallerHelper::ConvertInstallResult(callbackPtr->installResult); if (callbackPtr->installResult.resultCode != SUCCESS) { switch (callbackPtr->option) { case InstallOption::INSTALL: diff --git a/interfaces/kits/js/installer/installer_helper.cpp b/interfaces/kits/js/installer/installer_helper.cpp new file mode 100755 index 0000000000000000000000000000000000000000..f2399339ba9ac51f011f54b63bc9846aa9aeee4b --- /dev/null +++ b/interfaces/kits/js/installer/installer_helper.cpp @@ -0,0 +1,251 @@ +/* + * Copyright (c) 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 + +#include "installer_helper.h" + +#include "appexecfwk_errors.h" +#include "app_log_wrapper.h" +#include "bundle_errors.h" +#include "status_receiver_interface.h" + + +namespace OHOS { +namespace AppExecFwk { + +void InstallerHelper::CreateErrCodeMap(std::unordered_map &errCodeMap) +{ + errCodeMap = { + { IStatusReceiver::SUCCESS, SUCCESS}, + { IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION }, + { IStatusReceiver::ERR_INSTALL_HOST_INSTALLER_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION }, + { IStatusReceiver::ERR_INSTALLD_PARAM_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION }, + { IStatusReceiver::ERR_INSTALLD_GET_PROXY_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION }, + { IStatusReceiver::ERR_INSTALL_INSTALLD_SERVICE_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION }, + { IStatusReceiver::ERR_UNINSTALL_BUNDLE_MGR_SERVICE_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION }, + { IStatusReceiver::ERR_FAILED_SERVICE_DIED, ERROR_BUNDLE_SERVICE_EXCEPTION }, + { IStatusReceiver::ERR_FAILED_GET_INSTALLER_PROXY, ERROR_BUNDLE_SERVICE_EXCEPTION }, + { IStatusReceiver::ERR_USER_CREATE_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION }, + { IStatusReceiver::ERR_USER_REMOVE_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION }, + { IStatusReceiver::ERR_UNINSTALL_KILLING_APP_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION }, + { IStatusReceiver::ERR_INSTALL_GENERATE_UID_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION }, + { IStatusReceiver::ERR_INSTALL_STATE_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION }, + { IStatusReceiver::ERR_RECOVER_NOT_ALLOWED, ERROR_BUNDLE_SERVICE_EXCEPTION }, + { IStatusReceiver::ERR_RECOVER_GET_BUNDLEPATH_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION }, + { IStatusReceiver::ERR_UNINSTALL_AND_RECOVER_NOT_PREINSTALLED_BUNDLE, ERROR_BUNDLE_NOT_PREINSTALLED }, + { IStatusReceiver::ERR_UNINSTALL_SYSTEM_APP_ERROR, ERROR_UNINSTALL_PREINSTALL_APP_FAILED }, + { IStatusReceiver::ERR_INSTALL_PARSE_FAILED, ERROR_INSTALL_PARSE_FAILED }, + { IStatusReceiver::ERR_INSTALL_PARSE_UNEXPECTED, ERROR_INSTALL_PARSE_FAILED }, + { IStatusReceiver::ERR_INSTALL_PARSE_MISSING_BUNDLE, ERROR_INSTALL_PARSE_FAILED }, + { IStatusReceiver::ERR_INSTALL_PARSE_NO_PROFILE, ERROR_INSTALL_PARSE_FAILED }, + { IStatusReceiver::ERR_INSTALL_PARSE_BAD_PROFILE, ERROR_INSTALL_PARSE_FAILED }, + { IStatusReceiver::ERR_INSTALL_PARSE_PROFILE_PROP_TYPE_ERROR, ERROR_INSTALL_PARSE_FAILED }, + { IStatusReceiver::ERR_INSTALL_PARSE_PROFILE_MISSING_PROP, ERROR_INSTALL_PARSE_FAILED }, + { IStatusReceiver::ERR_INSTALL_PARSE_PERMISSION_ERROR, ERROR_INSTALL_PARSE_FAILED }, + { IStatusReceiver::ERR_INSTALL_PARSE_PROFILE_PROP_CHECK_ERROR, ERROR_INSTALL_PARSE_FAILED }, + { IStatusReceiver::ERR_INSTALL_PARSE_RPCID_FAILED, ERROR_INSTALL_PARSE_FAILED }, + { IStatusReceiver::ERR_INSTALL_PARSE_NATIVE_SO_FAILED, ERROR_INSTALL_PARSE_FAILED }, + { IStatusReceiver::ERR_INSTALL_PARSE_AN_FAILED, ERROR_INSTALL_PARSE_FAILED }, + { IStatusReceiver::ERR_INSTALL_PARSE_MISSING_ABILITY, ERROR_INSTALL_PARSE_FAILED }, + { IStatusReceiver::ERR_INSTALL_FAILED_PROFILE_PARSE_FAIL, ERROR_INSTALL_PARSE_FAILED }, + { IStatusReceiver::ERR_INSTALL_VERIFICATION_FAILED, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, + { IStatusReceiver::ERR_INSTALL_FAILED_INCOMPATIBLE_SIGNATURE, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, + { IStatusReceiver::ERR_INSTALL_FAILED_INVALID_SIGNATURE_FILE_PATH, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, + { IStatusReceiver::ERR_INSTALL_FAILED_BAD_BUNDLE_SIGNATURE_FILE, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, + { IStatusReceiver::ERR_INSTALL_FAILED_NO_BUNDLE_SIGNATURE, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, + { IStatusReceiver::ERR_INSTALL_FAILED_VERIFY_APP_PKCS7_FAIL, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, + { IStatusReceiver::ERR_INSTALL_FAILED_APP_SOURCE_NOT_TRUESTED, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, + { IStatusReceiver::ERR_INSTALL_FAILED_BAD_DIGEST, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, + { IStatusReceiver::ERR_INSTALL_FAILED_BUNDLE_INTEGRITY_VERIFICATION_FAILURE, + ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, + { IStatusReceiver::ERR_INSTALL_FAILED_BAD_PUBLICKEY, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, + { IStatusReceiver::ERR_INSTALL_FAILED_BAD_BUNDLE_SIGNATURE, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, + { IStatusReceiver::ERR_INSTALL_FAILED_NO_PROFILE_BLOCK_FAIL, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, + { IStatusReceiver::ERR_INSTALL_FAILED_BUNDLE_SIGNATURE_VERIFICATION_FAILURE, + ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, + { IStatusReceiver::ERR_INSTALL_FAILED_VERIFY_SOURCE_INIT_FAIL, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, + { IStatusReceiver::ERR_INSTALL_FAILED_DEVICE_UNAUTHORIZED, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, + { IStatusReceiver::ERR_INSTALL_SINGLETON_INCOMPATIBLE, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, + { IStatusReceiver::ERR_INSTALL_U1_ENABLE_NOT_SAME_IN_ALL_BUNDLE_INFOS, ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, + { IStatusReceiver::ERR_INSTALL_FAILED_INCONSISTENT_SIGNATURE, ERROR_INSTALL_FAILED_INCONSISTENT_SIGNATURE }, + { IStatusReceiver::ERR_INSTALL_PARAM_ERROR, ERROR_BUNDLE_NOT_EXIST }, + { IStatusReceiver::ERR_UNINSTALL_PARAM_ERROR, ERROR_BUNDLE_NOT_EXIST }, + { IStatusReceiver::ERR_RECOVER_INVALID_BUNDLE_NAME, ERROR_BUNDLE_NOT_EXIST }, + { IStatusReceiver::ERR_UNINSTALL_INVALID_NAME, ERROR_BUNDLE_NOT_EXIST }, + { IStatusReceiver::ERR_INSTALL_INVALID_BUNDLE_FILE, ERROR_INSTALL_HAP_FILEPATH_INVALID }, + { IStatusReceiver::ERR_INSTALL_FAILED_MODULE_NAME_EMPTY, ERROR_MODULE_NOT_EXIST }, + { IStatusReceiver::ERR_INSTALL_FAILED_MODULE_NAME_DUPLICATE, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_FAILED_CHECK_HAP_HASH_PARAM, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_UNINSTALL_MISSING_INSTALLED_BUNDLE, ERROR_BUNDLE_NOT_EXIST }, + { IStatusReceiver::ERR_UNINSTALL_MISSING_INSTALLED_MODULE, ERROR_MODULE_NOT_EXIST }, + { IStatusReceiver::ERR_USER_NOT_INSTALL_HAP, ERROR_BUNDLE_NOT_EXIST }, + { IStatusReceiver::ERR_INSTALL_FILE_PATH_INVALID, ERROR_INSTALL_HAP_FILEPATH_INVALID }, + { IStatusReceiver::ERR_INSTALL_PERMISSION_DENIED, ERROR_PERMISSION_DENIED_ERROR }, + { IStatusReceiver::ERR_UNINSTALL_PERMISSION_DENIED, ERROR_PERMISSION_DENIED_ERROR }, + { IStatusReceiver::ERR_INSTALL_GRANT_REQUEST_PERMISSIONS_FAILED, ERROR_INSTALL_PERMISSION_CHECK_ERROR }, + { IStatusReceiver::ERR_INSTALL_UPDATE_HAP_TOKEN_FAILED, ERROR_INSTALL_PERMISSION_CHECK_ERROR }, + { IStatusReceiver::ERR_INSTALLD_CREATE_DIR_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION }, + { IStatusReceiver::ERR_INSTALLD_CHOWN_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION }, + { IStatusReceiver::ERR_INSTALLD_CREATE_DIR_EXIST, ERROR_BUNDLE_SERVICE_EXCEPTION }, + { IStatusReceiver::ERR_INSTALLD_REMOVE_DIR_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION }, + { IStatusReceiver::ERR_INSTALLD_EXTRACT_FILES_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION }, + { IStatusReceiver::ERR_INSTALLD_RNAME_DIR_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION }, + { IStatusReceiver::ERR_INSTALLD_CLEAN_DIR_FAILED, ERROR_BUNDLE_SERVICE_EXCEPTION }, + { IStatusReceiver::ERR_INSTALL_ENTRY_ALREADY_EXIST, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_ALREADY_EXIST, ERROR_INSTALL_ALREADY_EXIST }, + { IStatusReceiver::ERR_INSTALL_BUNDLENAME_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_VERSIONCODE_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_VERSIONNAME_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_MINCOMPATIBLE_VERSIONCODE_NOT_SAME, + ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_VENDOR_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_RELEASETYPE_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_RELEASETYPE_TARGET_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_RELEASETYPE_COMPATIBLE_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_SINGLETON_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_ZERO_USER_WITH_NO_SINGLETON, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_CHECK_SYSCAP_FAILED, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_APPTYPE_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_URI_DUPLICATE, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_VERSION_NOT_COMPATIBLE, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_APP_DISTRIBUTION_TYPE_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_APP_PROVISION_TYPE_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_SO_INCOMPATIBLE, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_AN_INCOMPATIBLE, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_TYPE_ERROR, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_TYPE_ERROR, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_NOT_UNIQUE_DISTRO_MODULE_NAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_INCONSISTENT_MODULE_NAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_INVALID_NUMBER_OF_ENTRY_HAP, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_ASAN_ENABLED_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_ASAN_ENABLED_NOT_SUPPORT, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT}, + { IStatusReceiver::ERR_INSTALL_BUNDLE_TYPE_NOT_SAME, ERROR_INSTALL_PARSE_FAILED}, + { IStatusReceiver::ERR_INSTALL_DISK_MEM_INSUFFICIENT, ERROR_INSTALL_NO_DISK_SPACE_LEFT }, + { IStatusReceiver::ERR_USER_NOT_EXIST, ERROR_INVALID_USER_ID }, + { IStatusReceiver::ERR_INSTALL_VERSION_DOWNGRADE, ERROR_INSTALL_VERSION_DOWNGRADE }, + { IStatusReceiver::ERR_INSTALL_DEVICE_TYPE_NOT_SUPPORTED, ERROR_INSTALL_PARSE_FAILED }, + { IStatusReceiver::ERR_INSTALL_CHECK_SYSCAP_FAILED_AND_DEVICE_TYPE_NOT_SUPPORTED, ERROR_INSTALL_PARSE_FAILED }, + { IStatusReceiver::ERR_INSTALL_PARSE_PROFILE_PROP_SIZE_CHECK_ERROR, ERROR_INSTALL_PARSE_FAILED }, + { IStatusReceiver::ERR_INSTALL_DEPENDENT_MODULE_NOT_EXIST, ERROR_INSTALL_DEPENDENT_MODULE_NOT_EXIST }, + { IStatusReceiver::ERR_INSTALL_SHARE_APP_LIBRARY_NOT_ALLOWED, ERROR_INSTALL_SHARE_APP_LIBRARY_NOT_ALLOWED }, + { IStatusReceiver::ERR_INSTALL_COMPATIBLE_POLICY_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_FILE_IS_SHARED_LIBRARY, ERROR_INSTALL_FILE_IS_SHARED_LIBRARY }, + { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_INTERNAL_ERROR, ERROR_BUNDLE_SERVICE_EXCEPTION }, + { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_INVALID_BUNDLE_NAME, ERROR_BUNDLE_NOT_EXIST }, + { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_INVALID_MODULE_NAME, ERROR_MODULE_NOT_EXIST}, + { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_ERROR_HAP_TYPE, ERROR_INVALID_TYPE }, + { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_ERROR_BUNDLE_TYPE, ERROR_INVALID_TYPE }, + { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_TARGET_BUNDLE_NAME_MISSED, ERROR_INSTALL_PARSE_FAILED }, + { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_TARGET_MODULE_NAME_MISSED, ERROR_INSTALL_PARSE_FAILED }, + { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_TARGET_BUNDLE_NAME_NOT_SAME, + ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_INTERNAL_EXTERNAL_OVERLAY_EXISTED_SIMULTANEOUSLY, + ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_TARGET_PRIORITY_NOT_SAME, + ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_INVALID_PRIORITY, ERROR_INSTALL_PARSE_FAILED }, + { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_INCONSISTENT_VERSION_CODE, + ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_SERVICE_EXCEPTION, ERROR_BUNDLE_SERVICE_EXCEPTION }, + { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_BUNDLE_NAME_SAME_WITH_TARGET_BUNDLE_NAME, + ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT}, + { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_NO_SYSTEM_APPLICATION_FOR_EXTERNAL_OVERLAY, + ERROR_INSTALL_HAP_OVERLAY_CHECK_FAILED }, + { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_DIFFERENT_SIGNATURE_CERTIFICATE, + ERROR_INSTALL_VERIFY_SIGNATURE_FAILED }, + { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_TARGET_BUNDLE_IS_OVERLAY_BUNDLE, + ERROR_INSTALL_HAP_OVERLAY_CHECK_FAILED }, + {IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_TARGET_MODULE_IS_OVERLAY_MODULE, + ERROR_INSTALL_HAP_OVERLAY_CHECK_FAILED }, + { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_OVERLAY_TYPE_NOT_SAME, + ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_OVERLAY_INSTALLATION_FAILED_INVALID_BUNDLE_DIR, ERROR_BUNDLE_SERVICE_EXCEPTION }, + { IStatusReceiver::ERR_APPEXECFWK_UNINSTALL_SHARE_APP_LIBRARY_IS_NOT_EXIST, + ERROR_UNINSTALL_SHARE_APP_LIBRARY_IS_NOT_EXIST}, + { IStatusReceiver::ERR_APPEXECFWK_UNINSTALL_SHARE_APP_LIBRARY_IS_RELIED, + ERROR_UNINSTALL_SHARE_APP_LIBRARY_IS_RELIED}, + { IStatusReceiver::ERR_APPEXECFWK_UNINSTALL_BUNDLE_IS_SHARED_LIBRARY, + ERROR_UNINSTALL_BUNDLE_IS_SHARED_BUNDLE}, + { IStatusReceiver::ERR_INSATLL_CHECK_PROXY_DATA_URI_FAILED, + ERROR_INSTALL_WRONG_DATA_PROXY_URI}, + { IStatusReceiver::ERR_INSATLL_CHECK_PROXY_DATA_PERMISSION_FAILED, + ERROR_INSTALL_WRONG_DATA_PROXY_PERMISSION}, + { IStatusReceiver::ERR_INSTALL_FAILED_DEBUG_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT }, + { IStatusReceiver::ERR_INSTALL_DISALLOWED, ERROR_DISALLOW_INSTALL}, + { IStatusReceiver::ERR_INSTALL_ISOLATION_MODE_FAILED, ERROR_INSTALL_WRONG_MODE_ISOLATION }, + { IStatusReceiver::ERR_UNINSTALL_DISALLOWED, ERROR_DISALLOW_UNINSTALL }, + { IStatusReceiver::ERR_INSTALL_CODE_SIGNATURE_FAILED, ERROR_INSTALL_CODE_SIGNATURE_FAILED }, + { IStatusReceiver::ERR_INSTALL_CODE_SIGNATURE_FILE_IS_INVALID, ERROR_INSTALL_CODE_SIGNATURE_FAILED}, + { IStatusReceiver::ERR_UNINSTALL_FROM_BMS_EXTENSION_FAILED, ERROR_BUNDLE_NOT_EXIST}, + { IStatusReceiver::ERR_INSTALL_SELF_UPDATE_NOT_MDM, ERROR_INSTALL_SELF_UPDATE_NOT_MDM}, + { IStatusReceiver::ERR_INSTALL_ENTERPRISE_BUNDLE_NOT_ALLOWED, ERROR_INSTALL_ENTERPRISE_BUNDLE_NOT_ALLOWED}, + { IStatusReceiver::ERR_INSTALL_EXISTED_ENTERPRISE_BUNDLE_NOT_ALLOWED, + ERROR_INSTALL_EXISTED_ENTERPRISE_NOT_ALLOWED_ERROR}, + { IStatusReceiver::ERR_INSTALL_SELF_UPDATE_BUNDLENAME_NOT_SAME, ERROR_INSTALL_SELF_UPDATE_BUNDLENAME_NOT_SAME}, + { IStatusReceiver::ERR_INSTALL_GWP_ASAN_ENABLED_NOT_SAME, ERROR_INSTALL_MULTIPLE_HAP_INFO_INCONSISTENT}, + { IStatusReceiver::ERR_INSTALL_DEBUG_BUNDLE_NOT_ALLOWED, ERROR_INSTALL_DEBUG_BUNDLE_NOT_ALLOWED}, + { IStatusReceiver::ERR_INSTALL_CHECK_ENCRYPTION_FAILED, ERROR_INSTALL_CODE_SIGNATURE_FAILED }, + { IStatusReceiver::ERR_INSTALL_CODE_SIGNATURE_DELIVERY_FILE_FAILED, ERROR_INSTALL_CODE_SIGNATURE_FAILED}, + { IStatusReceiver::ERR_INSTALL_CODE_SIGNATURE_REMOVE_FILE_FAILED, ERROR_INSTALL_CODE_SIGNATURE_FAILED}, + { IStatusReceiver::ERR_INSTALL_CODE_APP_CONTROLLED_FAILED, ERROR_INSTALL_FAILED_CONTROLLED}, + { IStatusReceiver::ERR_APPEXECFWK_INSTALL_FORCE_UNINSTALLED_BUNDLE_NOT_ALLOW_RECOVER, + ERROR_INSTALL_FAILED_CONTROLLED}, + { IStatusReceiver::ERR_APPEXECFWK_INSTALL_PREINSTALL_BUNDLE_ONLY_ALLOW_FORCE_UNINSTALLED_BY_EDC, + ERROR_INSTALL_FAILED_CONTROLLED}, + { IStatusReceiver::ERR_INSTALL_NATIVE_FAILED, ERROR_INSTALL_NATIVE_FAILED}, + { IStatusReceiver::ERR_UNINSTALL_NATIVE_FAILED, ERROR_UNINSTALL_NATIVE_FAILED}, + { IStatusReceiver::ERR_UNINSTALL_DISPOSED_RULE_DENIED, ERROR_APPLICATION_UNINSTALL}, + { IStatusReceiver::ERR_NATIVE_HNP_EXTRACT_FAILED, ERROR_INSTALL_NATIVE_FAILED}, + { IStatusReceiver::ERR_UNINSTALL_CONTROLLED, ERROR_BUNDLE_CAN_NOT_BE_UNINSTALLED }, + { IStatusReceiver::ERR_INSTALL_DEBUG_ENCRYPTED_BUNDLE_FAILED, ERROR_INSTALL_PARSE_FAILED }, + { IStatusReceiver::ERR_APP_DISTRIBUTION_TYPE_NOT_ALLOW_INSTALL_ISR, + ERROR_APP_DISTRIBUTION_TYPE_NOT_ALLOW_INSTALL}, + { IStatusReceiver::ERR_INSTALL_FAILED_AND_RESTORE_TO_PREINSTALLED, + ERROR_INSTALL_FAILED_AND_RESTORE_TO_PREINSTALLED }, + { IStatusReceiver::ERR_INSTALL_U1ENABLE_CAN_ONLY_INSTALL_IN_U1_WITH_NOT_SINGLETON, + ERROR_INSTALL_FAILED_CONTROLLED }, + { IStatusReceiver::ERR_INSTALL_BUNDLE_EXISTED_IN_U1_AND_OTHER_USERS, + ERROR_INSTALL_FAILED_CONTROLLED }, + }; +} + +void InstallerHelper::ConvertInstallResult(InstallResult &installResult) +{ + APP_LOGD("ConvertInstallResult msg %{public}s, errCode is %{public}d", installResult.resultMsg.c_str(), + installResult.resultCode); + std::unordered_map errCodeMap; + CreateErrCodeMap(errCodeMap); + auto iter = errCodeMap.find(installResult.resultCode); + if (iter != errCodeMap.end()) { + installResult.resultCode = iter->second; + return; + } + installResult.resultCode = ERROR_BUNDLE_SERVICE_EXCEPTION; +} + +void InstallerHelper::CreateProxyErrCode(std::unordered_map &errCodeMap) +{ + errCodeMap = { + { ERR_APPEXECFWK_INSTALL_PARAM_ERROR, IStatusReceiver::ERR_INSTALL_PARAM_ERROR }, + { ERR_APPEXECFWK_INSTALL_INTERNAL_ERROR, IStatusReceiver::ERR_INSTALL_INTERNAL_ERROR }, + { ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID, IStatusReceiver::ERR_INSTALL_FILE_PATH_INVALID }, + { ERR_APPEXECFWK_INSTALL_DISK_MEM_INSUFFICIENT, IStatusReceiver::ERR_INSTALL_DISK_MEM_INSUFFICIENT }, + { ERR_BUNDLEMANAGER_INSTALL_CODE_SIGNATURE_FILE_IS_INVALID, + IStatusReceiver::ERR_INSTALL_CODE_SIGNATURE_FILE_IS_INVALID} + }; +} + +} // AppExecFwk +} // OHOS \ No newline at end of file diff --git a/interfaces/kits/js/installer/installer_helper.h b/interfaces/kits/js/installer/installer_helper.h new file mode 100755 index 0000000000000000000000000000000000000000..16cab3aad33bfbc0f38b412b7add1003e4b8fb8f --- /dev/null +++ b/interfaces/kits/js/installer/installer_helper.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 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. + */ + +#ifndef FOUNDATION_BUNDLEMGR_SERVICES_KITS_INCLUDE_INSTALLER_HELPER_H +#define FOUNDATION_BUNDLEMGR_SERVICES_KITS_INCLUDE_INSTALLER_HELPER_H + +#include "base_cb_info.h" +#include "installer.h" +#include "install_param.h" +#include "napi/native_api.h" +#include "napi/native_common.h" +#include "napi/native_node_api.h" + +namespace OHOS { +namespace AppExecFwk { +class InstallerHelper { +public: + static void CreateErrCodeMap(std::unordered_map &errCodeMap); + static void ConvertInstallResult(InstallResult &installResult); + static void CreateProxyErrCode(std::unordered_map &errCodeMap); +}; +} // AppExecFwk +} // OHOS +#endif // FOUNDATION_BUNDLEMGR_SERVICES_KITS_INCLUDE_INSTALLER_HELPER_H \ No newline at end of file diff --git a/interfaces/kits/js/launcher_bundle_manager/BUILD.gn b/interfaces/kits/js/launcher_bundle_manager/BUILD.gn index 76751d4928be8d50fe10102da3c34dd27827bf4d..b56c889c10bb013dd41e537e49cc26d43e546382 100644 --- a/interfaces/kits/js/launcher_bundle_manager/BUILD.gn +++ b/interfaces/kits/js/launcher_bundle_manager/BUILD.gn @@ -14,6 +14,56 @@ import("//build/ohos.gni") import("../../../../appexecfwk.gni") +ohos_shared_library("launcherbundlemanager_common") { + sanitize = { + boundary_sanitize = true + cfi = true + cfi_cross_dso = true + debug = false + integer_overflow = true + ubsan = true + } + + defines = [ + "APP_LOG_TAG = \"BMS\"", + "LOG_DOMAIN = 0xD001120", + ] + + cflags = [ + "-Os", + "-fstack-protector-strong", + ] + + cflags_cc = [ + "-Os", + "-fstack-protector-strong", + ] + + sources = [ "js_launcher_service.cpp" ] + + deps = [ + "${base_path}:appexecfwk_base", + "${common_path}:libappexecfwk_common", + "${core_path}:appexecfwk_core", + "../common:bundle_napi_common", + ] + + external_deps = [ + "ability_base:want", + "ability_runtime:ability_manager", + "ability_runtime:ability_start_options", + "ability_runtime:napi_common", + "c_utils:utils", + "common_event_service:cesfwk_core", + "common_event_service:cesfwk_innerkits", + "hilog:libhilog", + "ipc:ipc_single", + "napi:ace_napi", + ] + subsystem_name = "bundlemanager" + part_name = "bundle_framework" +} + ohos_shared_library("launcherbundlemanager") { branch_protector_ret = "pac_ret" @@ -45,10 +95,7 @@ ohos_shared_library("launcherbundlemanager") { sources = [ "native_module.cpp" ] if (bundle_framework_launcher) { - sources += [ - "js_launcher_service.cpp", - "launcher_bundle_manager.cpp", - ] + sources += [ "launcher_bundle_manager.cpp" ] } else { sources += [ "launcher_bundle_manager_unsupported.cpp" ] } @@ -60,6 +107,10 @@ ohos_shared_library("launcherbundlemanager") { "../common:bundle_napi_common", ] + if (bundle_framework_launcher) { + deps += [ ":launcherbundlemanager_common" ] + } + external_deps = [ "ability_base:want", "ability_runtime:ability_manager", diff --git a/services/bundlemgr/include/aot/aot_args.h b/services/bundlemgr/include/aot/aot_args.h index 84ae7342a1b99668196d8c16d0af93d4943936eb..1ce490c7f80a7d5c26c2df97420fcac62b79b574 100644 --- a/services/bundlemgr/include/aot/aot_args.h +++ b/services/bundlemgr/include/aot/aot_args.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * Copyright (c) 2023-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 @@ -27,6 +27,7 @@ struct HspInfo : public Parcelable { std::string bundleName; std::string moduleName; std::string hapPath; + std::string codeLanguage; std::string ToString() const; bool ReadFromParcel(Parcel &parcel); @@ -52,8 +53,12 @@ struct AOTArgs : public Parcelable { std::string anFileName; std::string appIdentifier; std::string optBCRangeList; + std::string codeLanguage; std::vector hspVector; + bool isSysComp = false; + std::string sysCompPath; + std::string ToString() const; bool ReadFromParcel(Parcel &parcel); virtual bool Marshalling(Parcel &parcel) const override; diff --git a/services/bundlemgr/include/aot/aot_executor.h b/services/bundlemgr/include/aot/aot_executor.h index b3a210413a9f2345302277dae925de1b6ed3aeb8..a070f9f17df59a8d7e6d3906eef1b2829793f736 100644 --- a/services/bundlemgr/include/aot/aot_executor.h +++ b/services/bundlemgr/include/aot/aot_executor.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * Copyright (c) 2023-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 @@ -44,10 +44,13 @@ private: std::string DecToHex(uint32_t decimal) const; bool CheckArgs(const AOTArgs &aotArgs) const; - bool GetAbcFileInfo(const std::string &hapPath, uint32_t &offset, uint32_t &length) const; + std::string GetAbcRelativePath(const std::string &codeLanguage) const; + bool GetAbcFileInfo(const std::string &hapPath, const std::string &codeLanguage, + uint32_t &offset, uint32_t &length) const; ErrCode PrepareArgs(const AOTArgs &aotArgs, AOTArgs &completeArgs) const; nlohmann::json GetSubjectInfo(const AOTArgs &aotArgs) const; - void MapArgs(const AOTArgs &aotArgs, std::unordered_map &argsMap); + void MapSysCompArgs(const AOTArgs &aotArgs, std::unordered_map &argsMap); + void MapHapArgs(const AOTArgs &aotArgs, std::unordered_map &argsMap); ErrCode EnforceCodeSign(const std::string &anFileName, const std::vector &signData) const; ErrCode StartAOTCompiler(const AOTArgs &aotArgs, std::vector &signData); void InitState(const AOTArgs &aotArgs); diff --git a/services/bundlemgr/include/aot/aot_handler.h b/services/bundlemgr/include/aot/aot_handler.h index dc54667528d4d63c70c193cb5941fd8049bf6407..1cf861fbc1a1ac837af43102c2b94ea96ad4934a 100644 --- a/services/bundlemgr/include/aot/aot_handler.h +++ b/services/bundlemgr/include/aot/aot_handler.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * Copyright (c) 2023-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 @@ -67,6 +67,7 @@ private: InnerBundleInfo &info, std::string &compileResult) const; void ClearArkCacheDir() const; void ResetAOTFlags() const; + void HandleIdleWithSingleSysComp(const std::string &abcPath) const; void HandleIdleWithSingleHap( const InnerBundleInfo &info, const std::string &moduleName, const std::string &compileMode) const; bool CheckDeviceState() const; @@ -89,6 +90,9 @@ private: void HandleArkPathsChange() const; void DelDeprecatedArkPaths() const; void CreateArkProfilePaths() const; + std::vector GetSysCompList() const; + void IdleForSysComp() const; + void IdleForHap(const std::string &compileMode) const; private: std::atomic OTACompileDeadline_ { false }; mutable std::mutex executeMutex_; diff --git a/services/bundlemgr/include/aot/aot_sign_data_cache_mgr.h b/services/bundlemgr/include/aot/aot_sign_data_cache_mgr.h index 119b3834d04818f4741321fe9be9b85c82ec7726..f3c5aa5e5e6751fa39f592b0960e022b4be7e067 100644 --- a/services/bundlemgr/include/aot/aot_sign_data_cache_mgr.h +++ b/services/bundlemgr/include/aot/aot_sign_data_cache_mgr.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024-2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -35,8 +35,10 @@ class AOTSignDataCacheMgr final { public: static AOTSignDataCacheMgr& GetInstance(); void RegisterScreenUnlockListener(); - void AddPendSignData(const AOTArgs &aotArgs, const uint32_t versionCode, - const std::vector &pendSignData, const ErrCode ret); + void AddSignDataForSysComp(const std::string &anFileName, const std::vector &signData, + const ErrCode ret); + void AddSignDataForHap(const AOTArgs &aotArgs, const uint32_t versionCode, + const std::vector &signData, const ErrCode ret); private: AOTSignDataCacheMgr() = default; ~AOTSignDataCacheMgr() = default; @@ -45,7 +47,9 @@ private: bool RegisterScreenUnlockEvent(); void UnregisterScreenUnlockEvent(); void HandleUnlockEvent(); - ErrCode ExecutePendSign(); + bool EnforceCodeSign(); + bool EnforceCodeSignForSysComp(); + bool EnforceCodeSignForHap(); class UnlockEventSubscriber : public OHOS::EventFwk::CommonEventSubscriber { public: UnlockEventSubscriber(const OHOS::EventFwk::CommonEventSubscribeInfo &info) : CommonEventSubscriber(info) {} @@ -53,14 +57,18 @@ private: void OnReceiveEvent(const OHOS::EventFwk::CommonEventData &event) override; }; private: - struct PendingData { - uint32_t versionCode {0}; + struct HapSignData { + uint32_t versionCode = 0; + std::string bundleName; + std::string moduleName; std::vector signData; }; std::atomic isLocked_ { true }; mutable std::mutex mutex_; std::shared_ptr unlockEventSubscriber_; - std::unordered_map> pendingSignData_; + std::vector hapSignDataVector_; + // key: anFileName, value: signData + std::unordered_map> sysCompSignDataMap_; }; } // namespace AppExecFwk } // namespace OHOS diff --git a/services/bundlemgr/include/bundle_framework_services_ipc_interface_code.h b/services/bundlemgr/include/bundle_framework_services_ipc_interface_code.h index bb6ac4750a570ff5386bd18555885bce83b567d5..71d2fc16ae2a3111beac0d4173ca21b9fd44ed90 100644 --- a/services/bundlemgr/include/bundle_framework_services_ipc_interface_code.h +++ b/services/bundlemgr/include/bundle_framework_services_ipc_interface_code.h @@ -83,7 +83,8 @@ enum class InstalldInterfaceCode : uint32_t { CREATE_DATA_GROUP_DIRS = 55, DELETE_DATA_GROUP_DIRS = 56, MIGRATE_DATA = 57, - LOAD_INSTALLS = 58 + LOAD_INSTALLS = 58, + CLEAR_DIR = 59 }; } // namespace AppExecFwk diff --git a/services/bundlemgr/include/inner_bundle_info.h b/services/bundlemgr/include/inner_bundle_info.h index 248a43ab4ad0e5be0c7e715c5f90261713d188d2..1c02fe8ce50eabcd612a4d2d608ecb223e04b8a6 100644 --- a/services/bundlemgr/include/inner_bundle_info.h +++ b/services/bundlemgr/include/inner_bundle_info.h @@ -128,6 +128,7 @@ struct InnerModuleInfo { std::string appStartup; std::string abilitySrcEntryDelegator; std::string abilityStageSrcEntryDelegator; + std::string codeLanguage = Constants::CODE_LANGUAGE_1_1; Distro distro; // all user's value of isRemovable // key:userId @@ -2322,6 +2323,8 @@ public: bool UpdatePluginBundleInfo(const PluginBundleInfo &pluginBundleInfo); bool RemovePluginFromUserInfo(const std::string &pluginBundleName, const int32_t userId); void GetAllDynamicIconInfo(const int32_t userId, std::vector &dynamicIconInfos) const; + std::string GetApplicationCodeLanguage() const; + std::string GetModuleCodeLanguage(const std::string &moduleName) const; private: bool IsExistLauncherAbility() const; diff --git a/services/bundlemgr/include/installd/installd_host_impl.h b/services/bundlemgr/include/installd/installd_host_impl.h index 4c116447f6c028a37b6351279fe6a7f3d9618dac..a3462b0e271f9b40d5d7df70c22212ae5bee224f 100644 --- a/services/bundlemgr/include/installd/installd_host_impl.h +++ b/services/bundlemgr/include/installd/installd_host_impl.h @@ -254,6 +254,8 @@ public: virtual ErrCode DeleteDataGroupDirs(const std::vector &uuidList, int32_t userId) override; + virtual ErrCode ClearDir(const std::string &dir) override; + private: static std::string GetGroupDirPath(const std::string &el, int32_t userId, const std::string &uuid); std::string GetExtensionConfigPath() const; diff --git a/services/bundlemgr/include/installd/installd_operator.h b/services/bundlemgr/include/installd/installd_operator.h index c15d3f7b5c82fffb7019eaf296a22f83a53b4046..a9eab81a09b95e5a699bc3d291ff8b69215d87e6 100644 --- a/services/bundlemgr/include/installd/installd_operator.h +++ b/services/bundlemgr/include/installd/installd_operator.h @@ -317,6 +317,8 @@ public: */ static void RmvDeleteDfx(const std::string &path); + static bool ClearDir(const std::string &dir); + private: static bool ObtainNativeSoFile(const BundleExtractor &extractor, const std::string &cpuAbi, std::vector &soEntryFiles); diff --git a/services/bundlemgr/include/installd_client.h b/services/bundlemgr/include/installd_client.h index 540a63ec2ff6d9f8d40daa5b50eb951ffd2c3272..243674e9c809218e728d2c4a7c144f9391cc1a7e 100644 --- a/services/bundlemgr/include/installd_client.h +++ b/services/bundlemgr/include/installd_client.h @@ -257,6 +257,8 @@ public: ErrCode LoadInstalls(); + ErrCode ClearDir(const std::string &dir); + private: sptr GetInstalldProxy(); bool LoadInstalldService(); diff --git a/services/bundlemgr/include/ipc/installd_host.h b/services/bundlemgr/include/ipc/installd_host.h index 50876f8a6599856610bd6c75b9fb3e8badaa65f6..831afd266f95d5d1a8b0ba606ab51e65c38adbb2 100644 --- a/services/bundlemgr/include/ipc/installd_host.h +++ b/services/bundlemgr/include/ipc/installd_host.h @@ -233,6 +233,8 @@ private: bool HandleLoadInstalls(MessageParcel &data, MessageParcel &reply); + bool HandleClearDir(MessageParcel &data, MessageParcel &reply); + void AddCloseInstalldTask(); void RemoveCloseInstalldTask(); diff --git a/services/bundlemgr/include/ipc/installd_interface.h b/services/bundlemgr/include/ipc/installd_interface.h index 52a6340bddca78d63e9d1a8137b20a10ccb6ce01..bf92f0ab9a5a6c52aa5e3d9b6b76e2ed2a86bc5b 100644 --- a/services/bundlemgr/include/ipc/installd_interface.h +++ b/services/bundlemgr/include/ipc/installd_interface.h @@ -463,6 +463,11 @@ public: { return ERR_OK; } + + virtual ErrCode ClearDir(const std::string &dir) + { + return ERR_APPEXECFWK_INSTALLD_CLEAN_DIR_FAILED; + } }; #define INSTALLD_PARCEL_WRITE_INTERFACE_TOKEN(parcel, token) \ diff --git a/services/bundlemgr/include/ipc/installd_proxy.h b/services/bundlemgr/include/ipc/installd_proxy.h index 46ac6f9db3431e4eba5caeb8a87e6587567b67f7..9fa747c0b253b461e8ce021fc3c691c40fa1520a 100644 --- a/services/bundlemgr/include/ipc/installd_proxy.h +++ b/services/bundlemgr/include/ipc/installd_proxy.h @@ -250,6 +250,8 @@ public: virtual ErrCode DeleteDataGroupDirs(const std::vector &uuidList, int32_t userId) override; virtual ErrCode LoadInstalls() override; + + virtual ErrCode ClearDir(const std::string &dir) override; private: ErrCode TransactInstalldCmd(InstalldInterfaceCode code, MessageParcel &data, MessageParcel &reply, MessageOption &option); diff --git a/services/bundlemgr/src/aot/aot_args.cpp b/services/bundlemgr/src/aot/aot_args.cpp index 7ee5d102c1da6b0367332e9f1f3e356e2d4c14e4..6594901e4835dab7111d539b22fb1fad834dfbb7 100644 --- a/services/bundlemgr/src/aot/aot_args.cpp +++ b/services/bundlemgr/src/aot/aot_args.cpp @@ -37,6 +37,7 @@ bool HspInfo::ReadFromParcel(Parcel &parcel) hapPath = Str16ToStr8(hapPathVal); READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Uint32, parcel, offset); READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Uint32, parcel, length); + READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(String, parcel, codeLanguage); return true; } @@ -48,6 +49,7 @@ bool HspInfo::Marshalling(Parcel &parcel) const WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(hapPath)); WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Uint32, parcel, offset); WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Uint32, parcel, length); + WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String, parcel, codeLanguage); return true; } @@ -69,7 +71,8 @@ std::string HspInfo::ToString() const + ", versionCode = " + std::to_string(versionCode) + ", hapPath = " + hapPath + ", offset = " + std::to_string(offset) - + ", length = " + std::to_string(length) + "]"; + + ", length = " + std::to_string(length) + + ", codeLanguage = " + codeLanguage + "]"; } bool AOTArgs::ReadFromParcel(Parcel &parcel) @@ -122,6 +125,9 @@ bool AOTArgs::ReadFromParcel(Parcel &parcel) optBCRangeList = Str16ToStr8(optBCRangeVal); READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Uint32, parcel, isScreenOff); READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Uint32, parcel, isEnableBaselinePgo); + READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(String, parcel, codeLanguage); + READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isSysComp); + READ_PARCEL_AND_RETURN_FALSE_IF_FAIL(String, parcel, sysCompPath); return true; } @@ -148,6 +154,9 @@ bool AOTArgs::Marshalling(Parcel &parcel) const WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String16, parcel, Str8ToStr16(optBCRangeList)); WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Uint32, parcel, isScreenOff); WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Uint32, parcel, isEnableBaselinePgo); + WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String, parcel, codeLanguage); + WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Bool, parcel, isSysComp); + WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(String, parcel, sysCompPath); return true; } @@ -180,7 +189,10 @@ std::string AOTArgs::ToString() const + ", isEncryptedBundle = " + std::to_string(isEncryptedBundle) + ", optBCRangeList = " + optBCRangeList + ", isScreenOff = " + std::to_string(isScreenOff) - + ", isEnableBaselinePgo = " + std::to_string(isEnableBaselinePgo) + "]"; + + ", isEnableBaselinePgo = " + std::to_string(isEnableBaselinePgo) + + ", codeLanguage = " + codeLanguage + + ", isSysComp = " + (isSysComp ? "true" : "false") + + ", sysCompPath = " + sysCompPath + "]"; ret.append(" hspVector = "); for (const auto &hspInfo : hspVector) { ret.append(hspInfo.ToString()); diff --git a/services/bundlemgr/src/aot/aot_executor.cpp b/services/bundlemgr/src/aot/aot_executor.cpp index 46ee4d3dd24eeb0f65bd0547eb755ca461244585..0fe49dfc7fbcf9d6c05d38c933af73d576cffb1b 100644 --- a/services/bundlemgr/src/aot/aot_executor.cpp +++ b/services/bundlemgr/src/aot/aot_executor.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * Copyright (c) 2023-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 @@ -45,11 +45,14 @@ namespace OHOS { namespace AppExecFwk { namespace { constexpr const char* ABC_RELATIVE_PATH = "ets/modules.abc"; +constexpr const char* STATIC_ABC_RELATIVE_PATH = "ets/modules_static.abc"; constexpr const char* HEX_PREFIX = "0x"; constexpr const char* BUNDLE_NAME = "bundleName"; constexpr const char* MODULE_NAME = "moduleName"; constexpr const char* PKG_PATH = "pkgPath"; constexpr const char* ABC_NAME = "abcName"; +constexpr const char* ABC_PATH = "ABC-Path"; +constexpr const char* AN_FILE_NAME = "anFileName"; constexpr const char* ABC_OFFSET = "abcOffset"; constexpr const char* ABC_SIZE = "abcSize"; constexpr const char* PROCESS_UID = "processUid"; @@ -58,6 +61,9 @@ constexpr const char* APP_IDENTIFIER = "appIdentifier"; constexpr const char* IS_ENCRYPTED_BUNDLE = "isEncryptedBundle"; constexpr const char* IS_SCREEN_OFF = "isScreenOff"; constexpr const char* PGO_DIR = "pgoDir"; +constexpr const char* IS_SYS_COMP = "isSysComp"; +constexpr const char* IS_SYS_COMP_FALSE = "0"; +constexpr const char* IS_SYS_COMP_TRUE = "1"; #if defined(CODE_SIGNATURE_ENABLE) constexpr int16_t ERR_AOT_COMPILER_SIGN_FAILED = 10004; constexpr int16_t ERR_AOT_COMPILER_CALL_CRASH = 10008; @@ -94,14 +100,32 @@ bool AOTExecutor::CheckArgs(const AOTArgs &aotArgs) const return true; } -bool AOTExecutor::GetAbcFileInfo(const std::string &hapPath, uint32_t &offset, uint32_t &length) const +std::string AOTExecutor::GetAbcRelativePath(const std::string &codeLanguage) const +{ + if (codeLanguage == Constants::CODE_LANGUAGE_1_1) { + return ABC_RELATIVE_PATH; + } + if (codeLanguage == Constants::CODE_LANGUAGE_1_2 || codeLanguage == Constants::CODE_LANGUAGE_HYBRID) { + return STATIC_ABC_RELATIVE_PATH; + } + APP_LOGW("invalid codeLanguage : %{public}s", codeLanguage.c_str()); + return Constants::EMPTY_STRING; +} + +bool AOTExecutor::GetAbcFileInfo(const std::string &hapPath, const std::string &codeLanguage, + uint32_t &offset, uint32_t &length) const { BundleExtractor extractor(hapPath); if (!extractor.Init()) { APP_LOGE("init BundleExtractor failed"); return false; } - if (!extractor.GetFileInfo(ABC_RELATIVE_PATH, offset, length)) { + std::string abcRelativePath = GetAbcRelativePath(codeLanguage); + if (abcRelativePath.empty()) { + APP_LOGE("abcRelativePath empty"); + return false; + } + if (!extractor.GetFileInfo(abcRelativePath, offset, length)) { APP_LOGE("GetFileInfo failed"); return false; } @@ -112,18 +136,24 @@ bool AOTExecutor::GetAbcFileInfo(const std::string &hapPath, uint32_t &offset, u ErrCode AOTExecutor::PrepareArgs(const AOTArgs &aotArgs, AOTArgs &completeArgs) const { APP_LOGD("PrepareArgs begin"); + if (aotArgs.isSysComp) { + APP_LOGD("sysComp, no need to prepare args"); + completeArgs = aotArgs; + return ERR_OK; + } if (!CheckArgs(aotArgs)) { APP_LOGE("param check failed"); return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR; } completeArgs = aotArgs; - if (!GetAbcFileInfo(completeArgs.hapPath, completeArgs.offset, completeArgs.length)) { + if (!GetAbcFileInfo(completeArgs.hapPath, completeArgs.codeLanguage, + completeArgs.offset, completeArgs.length)) { APP_LOGE("GetAbcFileInfo failed"); return ERR_APPEXECFWK_INSTALLD_AOT_ABC_NOT_EXIST; } // handle hsp for (auto &hspInfo : completeArgs.hspVector) { - (void)GetAbcFileInfo(hspInfo.hapPath, hspInfo.offset, hspInfo.length); + (void)GetAbcFileInfo(hspInfo.hapPath, hspInfo.codeLanguage, hspInfo.offset, hspInfo.length); } APP_LOGD("PrepareArgs success"); return ERR_OK; @@ -139,7 +169,7 @@ nlohmann::json AOTExecutor::GetSubjectInfo(const AOTArgs &aotArgs) const subject[BUNDLE_NAME] = aotArgs.bundleName; subject[MODULE_NAME] = aotArgs.moduleName; subject[PKG_PATH] = aotArgs.hapPath; - subject[ABC_NAME] = ABC_RELATIVE_PATH; + subject[ABC_NAME] = GetAbcRelativePath(aotArgs.codeLanguage); subject[ABC_OFFSET] = DecToHex(aotArgs.offset); subject[ABC_SIZE] = DecToHex(aotArgs.length); subject[PROCESS_UID] = DecToHex(currentProcessUid); @@ -151,9 +181,23 @@ nlohmann::json AOTExecutor::GetSubjectInfo(const AOTArgs &aotArgs) const return subject; } -void AOTExecutor::MapArgs(const AOTArgs &aotArgs, std::unordered_map &argsMap) +void AOTExecutor::MapSysCompArgs(const AOTArgs &aotArgs, std::unordered_map &argsMap) { - APP_LOGI("ExecuteInCompilerServiceProcess, args %{public}s", aotArgs.ToString().c_str()); + APP_LOGI_NOFUNC("MapSysCompArgs : %{public}s", aotArgs.ToString().c_str()); + argsMap.emplace(IS_SYS_COMP, IS_SYS_COMP_TRUE); + argsMap.emplace(ABC_PATH, aotArgs.sysCompPath); + argsMap.emplace(AN_FILE_NAME, aotArgs.anFileName); + uid_t uid = getuid(); + if (uid > UINT32_MAX) { + APP_LOGE_NOFUNC("invalid uid"); + return; + } + argsMap.emplace(PROCESS_UID, DecToHex(uid)); +} + +void AOTExecutor::MapHapArgs(const AOTArgs &aotArgs, std::unordered_map &argsMap) +{ + APP_LOGI_NOFUNC("MapHapArgs : %{public}s", aotArgs.ToString().c_str()); nlohmann::json subject = GetSubjectInfo(aotArgs); nlohmann::json objectArray = nlohmann::json::array(); @@ -162,7 +206,8 @@ void AOTExecutor::MapArgs(const AOTArgs &aotArgs, std::unordered_map argsMap; - MapArgs(aotArgs, argsMap); - std::string aotFilePath = ServiceConstants::ARK_CACHE_PATH + aotArgs.bundleName; - int32_t ret = InstalldHostImpl().Mkdir(aotFilePath, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH, - aotArgs.bundleUid, aotArgs.bundleGid); - if (ret != ERR_OK) { - APP_LOGE("make aot file output directory fail"); - return ERR_APPEXECFWK_INSTALLD_AOT_EXECUTE_FAILED; + if (aotArgs.isSysComp) { + MapSysCompArgs(aotArgs, argsMap); + } else { + MapHapArgs(aotArgs, argsMap); + std::string aotFilePath = ServiceConstants::ARK_CACHE_PATH + aotArgs.bundleName; + ErrCode result = InstalldHostImpl().Mkdir(aotFilePath, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH, + aotArgs.bundleUid, aotArgs.bundleGid); + if (result != ERR_OK) { + APP_LOGE("make aot file output directory fail"); + return ERR_APPEXECFWK_INSTALLD_AOT_EXECUTE_FAILED; + } } APP_LOGI("start to aot compiler"); std::vector fileData; - ret = ArkCompiler::AotCompilerClient::GetInstance().AotCompiler(argsMap, fileData); + ErrCode ret = ArkCompiler::AotCompilerClient::GetInstance().AotCompiler(argsMap, fileData); if (ret == ERR_AOT_COMPILER_SIGN_FAILED) { APP_LOGE("aot compiler local signature fail"); return ERR_APPEXECFWK_INSTALLD_SIGN_AOT_FAILED; diff --git a/services/bundlemgr/src/aot/aot_handler.cpp b/services/bundlemgr/src/aot/aot_handler.cpp index af2a6542c2c3d6621b8a491e1a1bc325769ceaa0..a0ddf64d7c84163f570520640b927cd0d106e96c 100644 --- a/services/bundlemgr/src/aot/aot_handler.cpp +++ b/services/bundlemgr/src/aot/aot_handler.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * Copyright (c) 2023-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 @@ -17,6 +17,8 @@ #include #include +#include +#include #include #include @@ -89,6 +91,9 @@ constexpr const char* AOT_VERSION_FUNC_NAME = "GetAOTVersion"; constexpr const char* BM_AOT_TEST = "bm.aot.test"; const std::string AOT_VERSION = "aot_version"; +constexpr const char* SYS_COMP_AN_DIR = "/data/service/el1/public/for-all-app/framework_ark_cache/"; +constexpr const char* SYS_COMP_CONFIG_PATH = "/system/etc/ark/system_framework_aot_enable_list.conf"; + constexpr const char* DEPRECATED_ARK_CACHE_PATH = "/data/local/ark-cache"; constexpr const char* DEPRECATED_ARK_PROFILE_PATH = "/data/local/ark-profile"; } @@ -164,14 +169,6 @@ std::optional AOTHandler::BuildAOTArgs(const InnerBundleInfo &info, con AOTArgs aotArgs; aotArgs.bundleName = info.GetBundleName(); aotArgs.moduleName = moduleName; - if (compileMode == ServiceConstants::COMPILE_PARTIAL) { - aotArgs.arkProfilePath = FindArkProfilePath(aotArgs.bundleName, aotArgs.moduleName); - if (aotArgs.arkProfilePath.empty()) { - APP_LOGD("compile mode is partial, but ap not exist, no need to AOT"); - return std::nullopt; - } - } - aotArgs.compileMode = compileMode; aotArgs.hapPath = info.GetModuleHapPath(aotArgs.moduleName); aotArgs.coreLibPath = Constants::EMPTY_STRING; aotArgs.outputPath = ServiceConstants::ARK_CACHE_PATH + aotArgs.bundleName + ServiceConstants::PATH_SEPARATOR @@ -212,6 +209,24 @@ std::optional AOTHandler::BuildAOTArgs(const InnerBundleInfo &info, con aotArgs.isScreenOff = static_cast(deviceIsScreenOff); aotArgs.isEnableBaselinePgo = static_cast(isEnableBaselinePgo); + aotArgs.codeLanguage = installedInfo.GetModuleCodeLanguage(moduleName); + if (aotArgs.codeLanguage.empty()) { + APP_LOGE("codeLanguage empty"); + return std::nullopt; + } + std::string tmpCompileMode = compileMode; + if (aotArgs.codeLanguage == Constants::CODE_LANGUAGE_1_2 || + aotArgs.codeLanguage == Constants::CODE_LANGUAGE_HYBRID) { + tmpCompileMode = "full"; + } + if (tmpCompileMode == ServiceConstants::COMPILE_PARTIAL) { + aotArgs.arkProfilePath = FindArkProfilePath(aotArgs.bundleName, aotArgs.moduleName); + if (aotArgs.arkProfilePath.empty()) { + APP_LOGD("compile mode is partial, but ap not exist, no need to AOT"); + return std::nullopt; + } + } + aotArgs.compileMode = tmpCompileMode; APP_LOGD("args : %{public}s", aotArgs.ToString().c_str()); return aotArgs; } @@ -230,7 +245,7 @@ ErrCode AOTHandler::AOTInternal(const std::optional &aotArgs, uint32_t } APP_LOGI("ExecuteAOT ret : %{public}d", ret); #ifdef CODE_SIGNATURE_ENABLE - AOTSignDataCacheMgr::GetInstance().AddPendSignData(*aotArgs, versionCode, pendSignData, ret); + AOTSignDataCacheMgr::GetInstance().AddSignDataForHap(*aotArgs, versionCode, pendSignData, ret); #endif auto dataMgr = DelayedSingleton::GetInstance()->GetDataMgr(); if (!dataMgr) { @@ -291,6 +306,8 @@ void AOTHandler::HandleInstall(const std::unordered_mapClearDir(SYS_COMP_AN_DIR); + auto dataMgr = DelayedSingleton::GetInstance()->GetDataMgr(); if (!dataMgr) { APP_LOGE("dataMgr is null"); @@ -714,6 +731,29 @@ void AOTHandler::ReportSysEvent(const std::map &sysEvent std::thread(task).detach(); } +void AOTHandler::HandleIdleWithSingleSysComp(const std::string &abcPath) const +{ + AOTArgs aotArgs; + aotArgs.isSysComp = true; + aotArgs.sysCompPath = abcPath; + std::string abcNameNoSuffix = std::filesystem::path(abcPath).stem().string(); + std::filesystem::path tmpAnFileName = + std::filesystem::path(SYS_COMP_AN_DIR) / (abcNameNoSuffix + ServiceConstants::AN_SUFFIX); + aotArgs.anFileName = tmpAnFileName.string(); + aotArgs.outputPath = aotArgs.anFileName; + + ErrCode ret = ERR_OK; + std::vector signData; + { + std::lock_guard lock(executeMutex_); + ret = InstalldClient::GetInstance()->ExecuteAOT(aotArgs, signData); + } + APP_LOGI_NOFUNC("ExecuteAOT ret : %{public}d", ret); +#ifdef CODE_SIGNATURE_ENABLE + AOTSignDataCacheMgr::GetInstance().AddSignDataForSysComp(aotArgs.anFileName, signData, ret); +#endif +} + void AOTHandler::HandleIdleWithSingleHap( const InnerBundleInfo &info, const std::string &moduleName, const std::string &compileMode) const { @@ -781,29 +821,8 @@ void AOTHandler::HandleIdle() const APP_LOGI("device state is not suitable"); return; } - auto dataMgr = DelayedSingleton::GetInstance()->GetDataMgr(); - if (!dataMgr) { - APP_LOGE("dataMgr is null"); - return; - } - std::vector bundleNames = dataMgr->GetAllBundleName(); - std::for_each(bundleNames.cbegin(), bundleNames.cend(), [this, dataMgr, &compileMode](const auto &bundleName) { - APP_LOGD("HandleIdle bundleName : %{public}s", bundleName.c_str()); - InnerBundleInfo info; - if (!dataMgr->QueryInnerBundleInfo(bundleName, info)) { - APP_LOGE("QueryInnerBundleInfo failed"); - return; - } - if (!info.GetIsNewVersion()) { - APP_LOGD("not stage model, no need to AOT"); - return; - } - std::vector moduleNames; - info.GetModuleNames(moduleNames); - std::for_each(moduleNames.cbegin(), moduleNames.cend(), [this, &info, &compileMode](const auto &moduleName) { - HandleIdleWithSingleHap(info, moduleName, compileMode); - }); - }); + IdleForSysComp(); + IdleForHap(compileMode); APP_LOGI("HandleIdle end"); } @@ -1022,5 +1041,66 @@ void AOTHandler::CreateArkProfilePaths() const } } } + +std::vector AOTHandler::GetSysCompList() const +{ + std::ifstream configFile(SYS_COMP_CONFIG_PATH); + if (!configFile.is_open()) { + APP_LOGE_NOFUNC("open %{public}s failed", SYS_COMP_CONFIG_PATH); + return {}; + } + std::vector sysCompList; + std::string line; + while (std::getline(configFile, line)) { + if (!line.empty()) { + sysCompList.emplace_back(line); + } + } + return sysCompList; +} + +void AOTHandler::IdleForSysComp() const +{ + APP_LOGI_NOFUNC("IdleForSysComp begin"); + std::vector sysCompList = GetSysCompList(); + if (sysCompList.empty()) { + APP_LOGI_NOFUNC("sysCompList empty"); + return; + } + APP_LOGI_NOFUNC("sysCompList size : %{public}zu", sysCompList.size()); + for (const std::string &abcPath : sysCompList) { + HandleIdleWithSingleSysComp(abcPath); + } + APP_LOGI_NOFUNC("IdleForSysComp end"); +} + +void AOTHandler::IdleForHap(const std::string &compileMode) const +{ + APP_LOGI_NOFUNC("IdleForHap begin"); + auto dataMgr = DelayedSingleton::GetInstance()->GetDataMgr(); + if (!dataMgr) { + APP_LOGE_NOFUNC("dataMgr is null"); + return; + } + std::vector bundleNames = dataMgr->GetAllBundleName(); + std::for_each(bundleNames.cbegin(), bundleNames.cend(), [this, dataMgr, &compileMode](const auto &bundleName) { + APP_LOGD("HandleIdle bundleName : %{public}s", bundleName.c_str()); + InnerBundleInfo info; + if (!dataMgr->QueryInnerBundleInfo(bundleName, info)) { + APP_LOGE_NOFUNC("QueryInnerBundleInfo failed"); + return; + } + if (!info.GetIsNewVersion()) { + APP_LOGD("not stage model, no need to AOT"); + return; + } + std::vector moduleNames; + info.GetModuleNames(moduleNames); + std::for_each(moduleNames.cbegin(), moduleNames.cend(), [this, &info, &compileMode](const auto &moduleName) { + HandleIdleWithSingleHap(info, moduleName, compileMode); + }); + }); + APP_LOGI_NOFUNC("IdleForHap end"); +} } // namespace AppExecFwk } // namespace OHOS diff --git a/services/bundlemgr/src/aot/aot_sign_data_cache_mgr.cpp b/services/bundlemgr/src/aot/aot_sign_data_cache_mgr.cpp index 55f3af3293bf64189da672d0acff0248e2a555b7..3ca8a1414b7a940a94a836e01bbec53c6f77f55f 100644 --- a/services/bundlemgr/src/aot/aot_sign_data_cache_mgr.cpp +++ b/services/bundlemgr/src/aot/aot_sign_data_cache_mgr.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024-2024 Huawei Device Co., Ltd. + * Copyright (c) 2024-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 @@ -15,37 +15,19 @@ #include "aot/aot_sign_data_cache_mgr.h" +#include +#include + #include "installd_client.h" namespace OHOS { namespace AppExecFwk { -namespace { -constexpr int8_t SLEEP_TIME_FOR_WAIT_SIGN_ENABLE = 1; // 1 s -constexpr int8_t LOOP_TIMES_FOR_WAIT_SIGN_ENABLE = 5; -} - AOTSignDataCacheMgr& AOTSignDataCacheMgr::GetInstance() { static AOTSignDataCacheMgr signDataCacheMgr; return signDataCacheMgr; } -void AOTSignDataCacheMgr::AddPendSignData(const AOTArgs &aotArgs, const uint32_t versionCode, - const std::vector &pendSignData, const ErrCode ret) -{ - if (isLocked_ && (ret == ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE) && !pendSignData.empty()) { - if (aotArgs.bundleName.empty() || aotArgs.moduleName.empty()) { - APP_LOGE("empty bundle or/and module name error"); - return; - } - PendingData pendingData = {versionCode, pendSignData}; - { - std::lock_guard lock(mutex_); - pendingSignData_[aotArgs.bundleName][aotArgs.moduleName] = pendingData; - } - } -} - void AOTSignDataCacheMgr::RegisterScreenUnlockListener() { EventFwk::MatchingSkills matchingSkill; @@ -61,6 +43,34 @@ void AOTSignDataCacheMgr::RegisterScreenUnlockListener() APP_LOGI_NOFUNC("AOT register screen unlock event success"); } +void AOTSignDataCacheMgr::AddSignDataForSysComp(const std::string &anFileName, const std::vector &signData, + const ErrCode ret) +{ + if (anFileName.empty() || signData.empty()) { + APP_LOGE_NOFUNC("empty anFileName or signData"); + return; + } + if (!isLocked_ || ret != ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE) { + return; + } + std::lock_guard lock(mutex_); + sysCompSignDataMap_[anFileName] = signData; +} + +void AOTSignDataCacheMgr::AddSignDataForHap(const AOTArgs &aotArgs, const uint32_t versionCode, + const std::vector &signData, const ErrCode ret) +{ + if (aotArgs.bundleName.empty() || aotArgs.moduleName.empty() || signData.empty()) { + APP_LOGE_NOFUNC("empty bundleName or moduleName or signData"); + return; + } + if (!isLocked_ || ret != ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE) { + return; + } + std::lock_guard lock(mutex_); + hapSignDataVector_.emplace_back(HapSignData{versionCode, aotArgs.bundleName, aotArgs.moduleName, signData}); +} + void AOTSignDataCacheMgr::UnregisterScreenUnlockEvent() { const bool result = EventFwk::CommonEventManager::UnSubscribeCommonEvent(unlockEventSubscriber_); @@ -86,62 +96,66 @@ void AOTSignDataCacheMgr::UnlockEventSubscriber::OnReceiveEvent(const EventFwk:: void AOTSignDataCacheMgr::HandleUnlockEvent() { - APP_LOGI_NOFUNC("pending sign thread is wake up"); + APP_LOGI_NOFUNC("begin to sign data"); + isLocked_ = false; UnregisterScreenUnlockEvent(); - sleep(SLEEP_TIME_FOR_WAIT_SIGN_ENABLE); - isLocked_ = false; - int32_t loopTimes = 0; - while (ExecutePendSign() != ERR_OK) { - if (++loopTimes > LOOP_TIMES_FOR_WAIT_SIGN_ENABLE) { - APP_LOGE_NOFUNC("wait for enforce sign enable time out"); + uint8_t maxRetry = 5; + for (uint8_t i = 1; i <= maxRetry; ++i) { + std::this_thread::sleep_for(std::chrono::seconds(1)); + if (EnforceCodeSign()) { + APP_LOGI_NOFUNC("sign data success"); return; } - sleep(SLEEP_TIME_FOR_WAIT_SIGN_ENABLE); } - { - std::lock_guard lock(mutex_); - std::unordered_map>().swap(pendingSignData_); - } - APP_LOGI_NOFUNC("pending enforce sign success"); + std::lock_guard lock(mutex_); + std::unordered_map>().swap(sysCompSignDataMap_); + hapSignDataVector_.clear(); + APP_LOGE_NOFUNC("sign data failed"); } -ErrCode AOTSignDataCacheMgr::ExecutePendSign() +bool AOTSignDataCacheMgr::EnforceCodeSign() +{ + return EnforceCodeSignForSysComp() && EnforceCodeSignForHap(); +} + +bool AOTSignDataCacheMgr::EnforceCodeSignForSysComp() { std::lock_guard lock(mutex_); - ErrCode ret = ERR_OK; - for (auto itBundle = pendingSignData_.begin(); itBundle != pendingSignData_.end(); ++itBundle) { - auto &bundleName = itBundle->first; - auto &moduleSignData = itBundle->second; - for (auto itModule = moduleSignData.begin(); itModule != moduleSignData.end();) { - auto &moduleName = itModule->first; - auto &signData = itModule->second.signData; - std::string anFileName = ServiceConstants::ARK_CACHE_PATH + bundleName + ServiceConstants::PATH_SEPARATOR - + ServiceConstants::ARM64 + ServiceConstants::PATH_SEPARATOR + moduleName + ServiceConstants::AN_SUFFIX; + for (const auto &[anFileName, signData] : sysCompSignDataMap_) { + ErrCode signRet = InstalldClient::GetInstance()->PendSignAOT(anFileName, signData); + if (signRet == ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE) { + APP_LOGE_NOFUNC("sign service disabled"); + return false; + } + } + std::unordered_map>().swap(sysCompSignDataMap_); + return true; +} - ErrCode retCS = InstalldClient::GetInstance()->PendSignAOT(anFileName, signData); - if (retCS == ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE) { - APP_LOGE("enforce sign service is disable"); - ret = ERR_APPEXECFWK_INSTALLD_SIGN_AOT_FAILED; - ++itModule; - continue; - } else if (retCS != ERR_OK) { - itModule = moduleSignData.erase(itModule); - continue; - } +bool AOTSignDataCacheMgr::EnforceCodeSignForHap() +{ + std::lock_guard lock(mutex_); + for (const HapSignData &hapSignData : hapSignDataVector_) { + std::filesystem::path anFileName(ServiceConstants::ARK_CACHE_PATH); + anFileName /= hapSignData.bundleName; + anFileName /= ServiceConstants::ARM64; + anFileName /= hapSignData.moduleName + ServiceConstants::AN_SUFFIX; + ErrCode signRet = InstalldClient::GetInstance()->PendSignAOT(anFileName.string(), hapSignData.signData); + if (signRet == ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE) { + APP_LOGE_NOFUNC("sign service disabled"); + return false; + } + if (signRet == ERR_OK) { auto dataMgr = DelayedSingleton::GetInstance()->GetDataMgr(); - if (!dataMgr) { - APP_LOGE("dataMgr is null"); - ret = ERR_APPEXECFWK_INSTALLD_SIGN_AOT_FAILED; - ++itModule; - continue; + if (dataMgr != nullptr) { + dataMgr->SetAOTCompileStatus(hapSignData.bundleName, hapSignData.moduleName, + AOTCompileStatus::COMPILE_SUCCESS, hapSignData.versionCode); } - auto versionCode = itModule->second.versionCode; - dataMgr->SetAOTCompileStatus(bundleName, moduleName, AOTCompileStatus::COMPILE_SUCCESS, versionCode); - itModule = moduleSignData.erase(itModule); } } - return ret; + hapSignDataVector_.clear(); + return true; } } // namespace AppExecFwk } // namespace OHOS diff --git a/services/bundlemgr/src/inner_bundle_info.cpp b/services/bundlemgr/src/inner_bundle_info.cpp index 05caadecc49b9d8f4c59f6aba3f418279be79765..22dbc7e60638e516e8e4c4a0f741cde2906d23cc 100644 --- a/services/bundlemgr/src/inner_bundle_info.cpp +++ b/services/bundlemgr/src/inner_bundle_info.cpp @@ -266,6 +266,7 @@ void InnerBundleInfo::GetInternalDependentHspInfo( hspInfo.bundleName = baseApplicationInfo_->bundleName; hspInfo.moduleName = item->second.moduleName; hspInfo.hapPath = item->second.hapPath; + hspInfo.codeLanguage = item->second.codeLanguage; hspInfoVector.emplace_back(hspInfo); } } @@ -387,6 +388,7 @@ void to_json(nlohmann::json &jsonObject, const InnerModuleInfo &info) {MODULE_METADATA, info.metaData}, {MODULE_COLOR_MODE, info.colorMode}, {MODULE_DISTRO, info.distro}, + {Constants::CODE_LANGUAGE, info.codeLanguage}, {MODULE_DESCRIPTION, info.description}, {MODULE_DESCRIPTION_ID, info.descriptionId}, {MODULE_ICON, info.icon}, @@ -586,6 +588,12 @@ void from_json(const nlohmann::json &jsonObject, InnerModuleInfo &info) false, parseResult, ArrayType::NOT_ARRAY); + BMSJsonUtil::GetStrValueIfFindKey(jsonObject, + jsonObjectEnd, + Constants::CODE_LANGUAGE, + info.codeLanguage, + false, + parseResult); BMSJsonUtil::GetStrValueIfFindKey(jsonObject, jsonObjectEnd, MODULE_DESCRIPTION, @@ -1613,6 +1621,7 @@ std::optional InnerBundleInfo::FindHapModuleInfo( hapInfo.packageName = it->second.packageName; hapInfo.abilitySrcEntryDelegator = it->second.abilitySrcEntryDelegator; hapInfo.abilityStageSrcEntryDelegator = it->second.abilityStageSrcEntryDelegator; + hapInfo.codeLanguage = it->second.codeLanguage; return hapInfo; } @@ -2275,6 +2284,7 @@ void InnerBundleInfo::GetApplicationInfo(int32_t flags, int32_t userId, Applicat return; } appInfo = *baseApplicationInfo_; + appInfo.codeLanguage = GetApplicationCodeLanguage(); if (!GetApplicationInfoAdaptBundleClone(innerBundleUserInfo, appIndex, appInfo)) { return; } @@ -2336,6 +2346,7 @@ ErrCode InnerBundleInfo::GetApplicationInfoV9(int32_t flags, int32_t userId, App } appInfo = *baseApplicationInfo_; + appInfo.codeLanguage = GetApplicationCodeLanguage(); if (!GetApplicationInfoAdaptBundleClone(innerBundleUserInfo, appIndex, appInfo)) { return ERR_APPEXECFWK_CLONE_INSTALL_INVALID_APP_INDEX; } @@ -2497,6 +2508,7 @@ bool InnerBundleInfo::GetSharedBundleInfo(int32_t flags, BundleInfo &bundleInfo) bundleInfo = *baseBundleInfo_; ProcessBundleWithHapModuleInfoFlag(flags, bundleInfo, Constants::ALL_USERID); bundleInfo.applicationInfo = *baseApplicationInfo_; + bundleInfo.applicationInfo.codeLanguage = GetApplicationCodeLanguage(); return true; } @@ -4155,6 +4167,7 @@ ErrCode InnerBundleInfo::GetAppServiceHspInfo(BundleInfo &bundleInfo) const } bundleInfo = *baseBundleInfo_; bundleInfo.applicationInfo = *baseApplicationInfo_; + bundleInfo.applicationInfo.codeLanguage = GetApplicationCodeLanguage(); for (const auto &info : innerModuleInfos_) { if (info.second.distro.moduleType == Profile::MODULE_TYPE_SHARED) { auto hapmoduleinfo = FindHapModuleInfo(info.second.modulePackage, Constants::ALL_USERID); @@ -5171,5 +5184,37 @@ void InnerBundleInfo::GetAllDynamicIconInfo(const int32_t userId, std::vectorsecond.codeLanguage; +} } // namespace AppExecFwk } // namespace OHOS diff --git a/services/bundlemgr/src/installd/installd_host_impl.cpp b/services/bundlemgr/src/installd/installd_host_impl.cpp index 64074ebbd7764619ea17a2a27ab6744fbb1c3e1e..33b00390bb5a1e9530a5a8a271baaf898d267c84 100644 --- a/services/bundlemgr/src/installd/installd_host_impl.cpp +++ b/services/bundlemgr/src/installd/installd_host_impl.cpp @@ -2449,5 +2449,22 @@ ErrCode InstalldHostImpl::DeleteEl5DataGroupDirs(const std::vector } return result; } + +ErrCode InstalldHostImpl::ClearDir(const std::string &dir) +{ + if (!InstalldPermissionMgr::VerifyCallingPermission(Constants::FOUNDATION_UID)) { + LOG_E(BMS_TAG_INSTALLD, "permission denied"); + return ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED; + } + if (dir.empty()) { + LOG_E(BMS_TAG_INSTALLD, "empty dir"); + return ERR_APPEXECFWK_INSTALLD_PARAM_ERROR; + } + if (!InstalldOperator::ClearDir(dir)) { + LOG_E(BMS_TAG_INSTALLD, "ClearDir failed"); + return ERR_APPEXECFWK_INSTALLD_CLEAN_DIR_FAILED; + } + return ERR_OK; +} } // namespace AppExecFwk } // namespace OHOS diff --git a/services/bundlemgr/src/installd/installd_operator.cpp b/services/bundlemgr/src/installd/installd_operator.cpp index ce0cedaf6eeb9e0e70b8c3305ed76a78b195bef7..19e2220fa1629125a1ee0406413815ef16626559 100644 --- a/services/bundlemgr/src/installd/installd_operator.cpp +++ b/services/bundlemgr/src/installd/installd_operator.cpp @@ -2708,5 +2708,41 @@ ErrCode InstalldOperator::EnforceEncryption(std::unordered_map delPathVector; + for (; dirIter != endIter; dirIter.increment(ec)) { + if (ec) { + LOG_E(BMS_TAG_INSTALLD, "iteration failed,%{public}s,err:%{public}s", dir.c_str(), ec.message().c_str()); + return false; + } + delPathVector.emplace_back(dirIter->path()); + } + + for (const auto &delPath : delPathVector) { + std::filesystem::remove_all(delPath, ec); + if (ec) { + LOG_E(BMS_TAG_INSTALLD, "remove_all failed,%{public}s,err:%{public}s", dir.c_str(), ec.message().c_str()); + return false; + } + } + LOG_I(BMS_TAG_INSTALLD, "clearDir success"); + return true; +} } // namespace AppExecFwk } // namespace OHOS diff --git a/services/bundlemgr/src/installd_client.cpp b/services/bundlemgr/src/installd_client.cpp index ee5656a054c6bd0b2863138423176fbf86e97726..e890749787295f4e0e09b8c1b9406225a474e1dc 100644 --- a/services/bundlemgr/src/installd_client.cpp +++ b/services/bundlemgr/src/installd_client.cpp @@ -617,5 +617,10 @@ ErrCode InstalldClient::LoadInstalls() { return CallService(&IInstalld::LoadInstalls); } + +ErrCode InstalldClient::ClearDir(const std::string &dir) +{ + return CallService(&IInstalld::ClearDir, dir); +} } // namespace AppExecFwk } // namespace OHOS diff --git a/services/bundlemgr/src/ipc/installd_host.cpp b/services/bundlemgr/src/ipc/installd_host.cpp index 83030b8e605b9fde7692fa32dce6be33c3bf2ddb..c4734cb19d75e56e4ce6f0135a517aa8e771a9c7 100644 --- a/services/bundlemgr/src/ipc/installd_host.cpp +++ b/services/bundlemgr/src/ipc/installd_host.cpp @@ -233,6 +233,9 @@ int InstalldHost::OnRemoteRequest(uint32_t code, MessageParcel &data, MessagePar case static_cast(InstalldInterfaceCode::LOAD_INSTALLS): result = HandleLoadInstalls(data, reply); break; + case static_cast(InstalldInterfaceCode::CLEAR_DIR): + result = HandleClearDir(data, reply); + break; default : LOG_W(BMS_TAG_INSTALLD, "installd host receives unknown code, code = %{public}u", code); return IPCObjectStub::OnRemoteRequest(code, data, reply, option); @@ -1074,5 +1077,13 @@ void InstalldHost::AddCloseInstalldTask() handler_->PostTask(task, UNLOAD_TASK_NAME, UNLOAD_TIME); LOG_D(BMS_TAG_INSTALLD, "send unload task successfully"); } + +bool InstalldHost::HandleClearDir(MessageParcel &data, MessageParcel &reply) +{ + std::string dir = data.ReadString(); + ErrCode result = ClearDir(dir); + WRITE_PARCEL_AND_RETURN_FALSE_IF_FAIL(Int32, reply, result); + return true; +} } // namespace AppExecFwk } // namespace OHOS diff --git a/services/bundlemgr/src/ipc/installd_proxy.cpp b/services/bundlemgr/src/ipc/installd_proxy.cpp index 45f66aa8ec24fb6efa1d537b7cb88da84329a081..34ea420bab05cb02d8b731dd00d6a2851c18e699 100644 --- a/services/bundlemgr/src/ipc/installd_proxy.cpp +++ b/services/bundlemgr/src/ipc/installd_proxy.cpp @@ -1063,5 +1063,16 @@ ErrCode InstalldProxy::TransactInstalldCmd(InstalldInterfaceCode code, MessagePa } return reply.ReadInt32(); } + +ErrCode InstalldProxy::ClearDir(const std::string &dir) +{ + MessageParcel data; + INSTALLD_PARCEL_WRITE_INTERFACE_TOKEN(data, (GetDescriptor())); + INSTALLD_PARCEL_WRITE(data, String, dir); + + MessageParcel reply; + MessageOption option; + return TransactInstalldCmd(InstalldInterfaceCode::CLEAR_DIR, data, reply, option); +} } // namespace AppExecFwk } // namespace OHOS \ No newline at end of file diff --git a/services/bundlemgr/src/module_profile.cpp b/services/bundlemgr/src/module_profile.cpp index 94ab57c3595f82d1a31dff9b81236c46e2772012..441f47fe308458d47744f646fdbea84b2f3802f0 100644 --- a/services/bundlemgr/src/module_profile.cpp +++ b/services/bundlemgr/src/module_profile.cpp @@ -209,6 +209,7 @@ struct Ability { std::vector continueType; std::vector continueBundleNames; std::string process; + std::string codeLanguage = Constants::CODE_LANGUAGE_1_1; }; struct Extension { @@ -234,6 +235,7 @@ struct Extension { std::string extensionProcessMode; std::vector dataGroupIds; std::string customProcess; + std::string codeLanguage = Constants::CODE_LANGUAGE_1_1; }; struct MultiAppMode { @@ -328,6 +330,7 @@ struct Module { std::vector appEnvironments; std::string packageName; std::string appStartup; + std::string codeLanguage = Constants::CODE_LANGUAGE_1_1; }; struct ModuleJson { @@ -680,6 +683,12 @@ void from_json(const nlohmann::json &jsonObject, Ability &ability) ability.process, false, g_parseResult); + BMSJsonUtil::GetStrValueIfFindKey(jsonObject, + jsonObjectEnd, + Constants::CODE_LANGUAGE, + ability.codeLanguage, + false, + g_parseResult); BMSJsonUtil::GetStrValueIfFindKey(jsonObject, jsonObjectEnd, ABILITY_START_WINDOW, @@ -867,6 +876,12 @@ void from_json(const nlohmann::json &jsonObject, Extension &extension) extension.customProcess, false, g_parseResult); + BMSJsonUtil::GetStrValueIfFindKey(jsonObject, + jsonObjectEnd, + Constants::CODE_LANGUAGE, + extension.codeLanguage, + false, + g_parseResult); } void from_json(const nlohmann::json &jsonObject, DeviceConfig &deviceConfig) @@ -1633,6 +1648,12 @@ void from_json(const nlohmann::json &jsonObject, Module &module) module.hasInsightIntent, false, g_parseResult); + BMSJsonUtil::GetStrValueIfFindKey(jsonObject, + jsonObjectEnd, + Constants::CODE_LANGUAGE, + module.codeLanguage, + false, + g_parseResult); } void from_json(const nlohmann::json &jsonObject, ModuleJson &moduleJson) @@ -2348,6 +2369,7 @@ bool ToAbilityInfo( } abilityInfo.orientationId = ability.orientationId; abilityInfo.process = ability.process; + abilityInfo.codeLanguage = ability.codeLanguage; APP_LOGI("startWindowIconId %{public}s_%{public}s_%{public}s_%{public}d", abilityInfo.bundleName.c_str(), abilityInfo.moduleName.c_str(), abilityInfo.name.c_str(), abilityInfo.startWindowIconId); return true; @@ -2411,6 +2433,7 @@ void ToExtensionInfo( extensionInfo.dataGroupIds.emplace_back(dataGroup); } extensionInfo.customProcess = extension.customProcess; + extensionInfo.codeLanguage = extension.codeLanguage; } bool GetPermissions( @@ -2528,6 +2551,7 @@ bool ToInnerModuleInfo( innerModuleInfo.appEnvironments = moduleJson.module.appEnvironments; innerModuleInfo.packageName = moduleJson.module.packageName; innerModuleInfo.appStartup = moduleJson.module.appStartup; + innerModuleInfo.codeLanguage = moduleJson.module.codeLanguage; innerModuleInfo.debug = moduleJson.app.debug; innerModuleInfo.abilitySrcEntryDelegator = moduleJson.module.abilitySrcEntryDelegator; innerModuleInfo.abilityStageSrcEntryDelegator = moduleJson.module.abilityStageSrcEntryDelegator; diff --git a/services/bundlemgr/test/mock/src/installd_client.cpp b/services/bundlemgr/test/mock/src/installd_client.cpp index c503926d55983665ac7ef4419a262aa6c855a490..2c7e1218e2366fd7cabf3b8cbc1268c8c938fa07 100644 --- a/services/bundlemgr/test/mock/src/installd_client.cpp +++ b/services/bundlemgr/test/mock/src/installd_client.cpp @@ -541,5 +541,10 @@ ErrCode InstalldClient::LoadInstalls() { return CallService(&IInstalld::LoadInstalls); } + +ErrCode InstalldClient::ClearDir(const std::string &dir) +{ + return CallService(&IInstalld::ClearDir, dir); +} } // namespace AppExecFwk } // namespace OHOS diff --git a/services/bundlemgr/test/mock/src/mock_install_client.cpp b/services/bundlemgr/test/mock/src/mock_install_client.cpp index 4034c70231180ee1c88a387ed129d8f27dcf8305..d008fa6fe4d8d6a61eb0a80198935c9833442b45 100644 --- a/services/bundlemgr/test/mock/src/mock_install_client.cpp +++ b/services/bundlemgr/test/mock/src/mock_install_client.cpp @@ -351,5 +351,10 @@ ErrCode InstalldClient::DeleteDataGroupDirs(const std::vector &uuid { return ERR_OK; } + +ErrCode InstalldClient::ClearDir(const std::string &dir) +{ + return ERR_OK; +} } // namespace AppExecFwk } // namespace OHOS diff --git a/services/bundlemgr/test/mock/src/mock_installd_host_impl.cpp b/services/bundlemgr/test/mock/src/mock_installd_host_impl.cpp index 0b923bd601960be896004a113d051d03aad27a0f..a28907aed554f8e4a7175595661bb56877d80d93 100755 --- a/services/bundlemgr/test/mock/src/mock_installd_host_impl.cpp +++ b/services/bundlemgr/test/mock/src/mock_installd_host_impl.cpp @@ -347,5 +347,10 @@ ErrCode InstalldHostImpl::DeleteDataGroupDirs(const std::vector &uu { return ERR_OK; } + +ErrCode InstalldHostImpl::ClearDir(const std::string &dir) +{ + return ERR_OK; +} } // namespace AppExecFwk } // namespace OHOS diff --git a/services/bundlemgr/test/unittest/bms_bundle_aot_test/bms_aot_handler_test.cpp b/services/bundlemgr/test/unittest/bms_bundle_aot_test/bms_aot_handler_test.cpp index 7f7d3137dcd8d27232200557c6c9e33ef40bdce0..ba2831822f2104bafd2a69bdfc5af1f2cfb1aaa5 100644 --- a/services/bundlemgr/test/unittest/bms_bundle_aot_test/bms_aot_handler_test.cpp +++ b/services/bundlemgr/test/unittest/bms_bundle_aot_test/bms_aot_handler_test.cpp @@ -16,8 +16,10 @@ #define private public #include #include +#include #include "aot_handler.h" +#include "aot_sign_data_cache_mgr.h" #include "app_log_wrapper.h" #include "bundle_installer_host.h" #include "bundle_mgr_service.h" @@ -151,6 +153,104 @@ HWTEST_F(BmsAOTHandlerTest, HandleArkPathsChange_0100, Function | SmallTest | Le AOTHandler::GetInstance().HandleArkPathsChange(); bool isHandled = false; (void)BMSEventHandler::CheckOtaFlag(OTAFlag::DELETE_DEPRECATED_ARK_PATHS, isHandled); - EXPECT_FALSE(isHandled); + EXPECT_TRUE(isHandled); +} + +/** + * @tc.number: DelDeprecatedArkPaths_0100 + * @tc.name: test DelDeprecatedArkPaths + * @tc.desc: 1.call DelDeprecatedArkPaths, expect dirs not exist + */ +HWTEST_F(BmsAOTHandlerTest, DelDeprecatedArkPaths_0100, Function | SmallTest | Level1) +{ + AOTHandler::GetInstance().DelDeprecatedArkPaths(); + bool isExist = true; + (void)InstalldClient::GetInstance()->IsExistDir("/data/local/ark-cache", isExist); + EXPECT_FALSE(isExist); + isExist = true; + (void)InstalldClient::GetInstance()->IsExistDir("/data/local/ark-profile", isExist); + EXPECT_FALSE(isExist); +} + +/** + * @tc.number: CreateArkProfilePaths_0100 + * @tc.name: test CreateArkProfilePaths + * @tc.desc: 1.call CreateArkProfilePaths, expect dirs exist + */ +HWTEST_F(BmsAOTHandlerTest, CreateArkProfilePaths_0100, Function | SmallTest | Level1) +{ + std::string path = AOTHandler::BuildArkProfilePath(USER_ID, BUNDLE_NAME); + (void)InstalldClient::GetInstance()->RemoveDir(path); + bool isExist = true; + (void)InstalldClient::GetInstance()->IsExistDir(path, isExist); + EXPECT_FALSE(isExist); + + AOTHandler::GetInstance().CreateArkProfilePaths(); + (void)InstalldClient::GetInstance()->IsExistDir(path, isExist); + EXPECT_TRUE(isExist); +} + +/** + * @tc.number: HandleIdleWithSingleSysComp_0100 + * @tc.name: test HandleIdleWithSingleSysComp + * @tc.desc: 1.call HandleIdleWithSingleSysComp, expect sysCompSignDataMap_ size is 0 + */ +HWTEST_F(BmsAOTHandlerTest, HandleIdleWithSingleSysComp_0100, Function | SmallTest | Level1) +{ + AOTSignDataCacheMgr::GetInstance().sysCompSignDataMap_.clear(); + + std::string path; + AOTHandler::GetInstance().HandleIdleWithSingleSysComp(path); + size_t sysCompSignDataMapSize = AOTSignDataCacheMgr::GetInstance().sysCompSignDataMap_.size(); + EXPECT_EQ(sysCompSignDataMapSize, 0); +} + +/** + * @tc.number: IdleForSysComp_0100 + * @tc.name: test IdleForSysComp + * @tc.desc: 1.call IdleForSysComp, expect sysCompSignDataMap_ size is 0 + */ +HWTEST_F(BmsAOTHandlerTest, IdleForSysComp_0100, Function | SmallTest | Level1) +{ + AOTSignDataCacheMgr::GetInstance().sysCompSignDataMap_.clear(); + + AOTHandler::GetInstance().IdleForSysComp(); + size_t sysCompSignDataMapSize = AOTSignDataCacheMgr::GetInstance().sysCompSignDataMap_.size(); + EXPECT_EQ(sysCompSignDataMapSize, 0); +} + +/** + * @tc.number: IdleForHap_0100 + * @tc.name: test IdleForHap + * @tc.desc: 1.call IdleForHap, expect sysCompSignDataMap_ size is 0 + */ +HWTEST_F(BmsAOTHandlerTest, IdleForHap_0100, Function | SmallTest | Level1) +{ + AOTSignDataCacheMgr::GetInstance().sysCompSignDataMap_.clear(); + + std::string compilePartial = "partial"; + AOTHandler::GetInstance().IdleForHap(compilePartial); + size_t sysCompSignDataMapSize = AOTSignDataCacheMgr::GetInstance().sysCompSignDataMap_.size(); + EXPECT_EQ(sysCompSignDataMapSize, 0); +} + +/** + * @tc.number: GetSysCompList_0100 + * @tc.name: test GetSysCompList + * @tc.desc: 1.call GetSysCompList, if file exist and not empty, expect sysCompList not empty + * 2.call GetSysCompList, if file not exist, expect sysCompList empty + */ +HWTEST_F(BmsAOTHandlerTest, GetSysCompList_0100, Function | SmallTest | Level1) +{ + std::string sysCompConfigPath = "/system/etc/ark/system_framework_aot_enable_list.conf"; + std::vector sysCompList = AOTHandler::GetInstance().GetSysCompList(); + struct stat st; + int32_t ret = stat(sysCompConfigPath.c_str(), &st); + if (ret == 0 && S_ISREG(st.st_mode) && st.st_size > 0) { + EXPECT_FALSE(sysCompList.empty()); + } else { + EXPECT_TRUE(sysCompList.empty()); + } } } // OHOS + \ No newline at end of file diff --git a/services/bundlemgr/test/unittest/bms_bundle_aot_test/bms_data_aot_test.cpp b/services/bundlemgr/test/unittest/bms_bundle_aot_test/bms_data_aot_test.cpp index c19a398b909b08ec7a2a71a1c32512c6e5363fbe..1967788c460c1e91dfbbc940a700c72fe94db594 100644 --- a/services/bundlemgr/test/unittest/bms_bundle_aot_test/bms_data_aot_test.cpp +++ b/services/bundlemgr/test/unittest/bms_bundle_aot_test/bms_data_aot_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * Copyright (c) 2023-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 @@ -54,12 +54,17 @@ const std::string HAP_PATH = "/system/etc/graphic/bootpic.zip"; const std::string NOHAP_PATH = "/data/test/resource/bms/aot_bundle/....right.hap"; const std::string OUT_PUT_PATH = "/data/test/resource/bms/aot_bundle/"; const std::string ABC_RELATIVE_PATH = "ets/modules.abc"; +const std::string STATIC_ABC_RELATIVE_PATH = "ets/modules_static.abc"; const std::string AOT_BUNDLE_NAME = "aotBundleName"; const std::string AOT_MODULE_NAME = "aotModuleName"; const std::string STRING_TYPE_ONE = "string1"; const std::string STRING_TYPE_TWO = "string2"; const std::string STRING_EMPTY = ""; const std::string AOT_VERSION = "aot_version"; +const std::string AN_FILE_NAME = "anFileName"; +const std::string IS_SYS_COMP = "isSysComp"; +const std::string IS_SYS_COMP_FALSE = "0"; +const std::string IS_SYS_COMP_TRUE = "1"; const int32_t USERID_ONE = 100; const int32_t USERID_TWO = -1; constexpr uint32_t VERSION_CODE = 3; @@ -144,6 +149,7 @@ HspInfo BmsAOTMgrTest::CreateHspInfo() const hspInfo.hapPath = "hapPath"; hspInfo.offset = OFFSET; hspInfo.length = LENGTH; + hspInfo.codeLanguage = Constants::CODE_LANGUAGE_1_2; return hspInfo; } @@ -155,6 +161,7 @@ void BmsAOTMgrTest::CheckHspInfo(HspInfo &sourceHspInfo, HspInfo &targetHspInfo) EXPECT_EQ(sourceHspInfo.hapPath, targetHspInfo.hapPath); EXPECT_EQ(sourceHspInfo.offset, targetHspInfo.offset); EXPECT_EQ(sourceHspInfo.length, targetHspInfo.length); + EXPECT_EQ(sourceHspInfo.codeLanguage, targetHspInfo.codeLanguage); } void BmsAOTMgrTest::ClearDataMgr() @@ -358,6 +365,38 @@ HWTEST_F(BmsAOTMgrTest, AOTExecutor_1100, Function | SmallTest | Level0) EXPECT_EQ(AOTExecutor::GetInstance().state_.outputPath, ""); } +/** + * @tc.number: MapSysCompArgs_0100 + * @tc.name: test MapSysCompArgs + * @tc.desc: 1. call MapSysCompArgs, expect get set value + */ +HWTEST_F(BmsAOTMgrTest, MapSysCompArgs_0100, Function | SmallTest | Level0) +{ + AOTArgs aotArgs; + aotArgs.anFileName = "anFileName"; + std::unordered_map argsMap; + + AOTExecutor::GetInstance().MapSysCompArgs(aotArgs, argsMap); + EXPECT_EQ(argsMap[IS_SYS_COMP], IS_SYS_COMP_TRUE); + EXPECT_EQ(argsMap[AN_FILE_NAME], aotArgs.anFileName); +} + +/** + * @tc.number: MapHapArgs_0100 + * @tc.name: test MapHapArgs + * @tc.desc: 1. call MapHapArgs, expect get set value + */ +HWTEST_F(BmsAOTMgrTest, MapHapArgs_0100, Function | SmallTest | Level0) +{ + AOTArgs aotArgs; + aotArgs.anFileName = "anFileName"; + std::unordered_map argsMap; + + AOTExecutor::GetInstance().MapHapArgs(aotArgs, argsMap); + EXPECT_EQ(argsMap[IS_SYS_COMP], IS_SYS_COMP_FALSE); + EXPECT_EQ(argsMap[AN_FILE_NAME], aotArgs.anFileName); +} + /** * @tc.number: AOTHandler_0100 * @tc.name: test AOTHandler @@ -721,6 +760,9 @@ HWTEST_F(BmsAOTMgrTest, AOTArgs_0200, Function | SmallTest | Level1) aotArgs.length = LENGTH; aotArgs.hspVector.emplace_back(CreateHspInfo()); aotArgs.hspVector.emplace_back(CreateHspInfo()); + aotArgs.codeLanguage = Constants::CODE_LANGUAGE_1_2; + aotArgs.isSysComp = true; + aotArgs.sysCompPath = "sysCompPath"; Parcel parcel; bool ret = aotArgs.Marshalling(parcel); @@ -741,6 +783,9 @@ HWTEST_F(BmsAOTMgrTest, AOTArgs_0200, Function | SmallTest | Level1) for (size_t i = 0; i < aotArgsPtr->hspVector.size(); ++i) { CheckHspInfo(aotArgsPtr->hspVector[i], aotArgs.hspVector[i]); } + EXPECT_EQ(aotArgsPtr->codeLanguage, aotArgs.codeLanguage); + EXPECT_EQ(aotArgsPtr->isSysComp, aotArgs.isSysComp); + EXPECT_EQ(aotArgsPtr->sysCompPath, aotArgs.sysCompPath); APP_LOGI("AOTArgs_0200 end"); } @@ -1116,8 +1161,8 @@ HWTEST_F(BmsAOTMgrTest, AOTExecutor_1200, Function | SmallTest | Level0) /** * @tc.number: AOTExecutor_1300 - * @tc.name: test MapArgs - * @tc.desc: test MapArgs function running normally + * @tc.name: test MapHapArgs + * @tc.desc: test MapHapArgs function running normally */ HWTEST_F(BmsAOTMgrTest, AOTExecutor_1300, Function | SmallTest | Level0) { @@ -1134,7 +1179,7 @@ HWTEST_F(BmsAOTMgrTest, AOTExecutor_1300, Function | SmallTest | Level0) aotArgs.hspVector.emplace_back(CreateHspInfo()); aotArgs.hspVector.emplace_back(CreateHspInfo()); std::unordered_map argsMap; - AOTExecutor::GetInstance().MapArgs(aotArgs, argsMap); + AOTExecutor::GetInstance().MapHapArgs(aotArgs, argsMap); EXPECT_EQ(argsMap.empty(), false); } @@ -1154,7 +1199,7 @@ HWTEST_F(BmsAOTMgrTest, AOTExecutor_1400, Function | SmallTest | Level0) /** * @tc.number: AOTSignDataCacheMgr_0100 * @tc.name: test AOTSignDataCacheMgr - * @tc.desc: test AddPendSignData function running normally + * @tc.desc: test AddSignDataForHap function running normally */ HWTEST_F(BmsAOTMgrTest, AOTSignDataCacheMgr_0100, Function | SmallTest | Level0) { @@ -1166,15 +1211,15 @@ HWTEST_F(BmsAOTMgrTest, AOTSignDataCacheMgr_0100, Function | SmallTest | Level0) int32_t versionCode = 1; std::vector pendSignData(HAP_PATH.begin(), HAP_PATH.end()); ErrCode ret = ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE; - AOTSignDataCacheMgr::GetInstance().AddPendSignData(*aotArgs, versionCode, pendSignData, ret); - EXPECT_EQ(AOTSignDataCacheMgr::GetInstance().pendingSignData_.empty(), false); - AOTSignDataCacheMgr::GetInstance().pendingSignData_.clear(); + AOTSignDataCacheMgr::GetInstance().AddSignDataForHap(*aotArgs, versionCode, pendSignData, ret); + EXPECT_EQ(AOTSignDataCacheMgr::GetInstance().hapSignDataVector_.empty(), false); + AOTSignDataCacheMgr::GetInstance().hapSignDataVector_.clear(); } /** * @tc.number: AOTSignDataCacheMgr_0200 * @tc.name: test AOTSignDataCacheMgr - * @tc.desc: test AddPendSignData function running with exception parameter + * @tc.desc: test AddSignDataForHap function running with exception parameter */ HWTEST_F(BmsAOTMgrTest, AOTSignDataCacheMgr_0200, Function | SmallTest | Level0) { @@ -1197,32 +1242,32 @@ HWTEST_F(BmsAOTMgrTest, AOTSignDataCacheMgr_0200, Function | SmallTest | Level0) ErrCode ret = ERR_OK; AOTSignDataCacheMgr& signDataCacheMgr = AOTSignDataCacheMgr::GetInstance(); signDataCacheMgr.isLocked_ = false; - signDataCacheMgr.AddPendSignData(*aotArgs, versionCode, pendSignData, ret); - EXPECT_EQ(signDataCacheMgr.pendingSignData_.empty(), true); + signDataCacheMgr.AddSignDataForHap(*aotArgs, versionCode, pendSignData, ret); + EXPECT_EQ(signDataCacheMgr.hapSignDataVector_.empty(), true); signDataCacheMgr.isLocked_ = true; - signDataCacheMgr.AddPendSignData(*aotArgs, versionCode, pendSignData, ret); - EXPECT_EQ(signDataCacheMgr.pendingSignData_.empty(), true); + signDataCacheMgr.AddSignDataForHap(*aotArgs, versionCode, pendSignData, ret); + EXPECT_EQ(signDataCacheMgr.hapSignDataVector_.empty(), true); ret = ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE; - signDataCacheMgr.AddPendSignData(*aotArgs, versionCode, pendSignData, ret); - EXPECT_EQ(signDataCacheMgr.pendingSignData_.empty(), true); + signDataCacheMgr.AddSignDataForHap(*aotArgs, versionCode, pendSignData, ret); + EXPECT_EQ(signDataCacheMgr.hapSignDataVector_.empty(), true); signDataCacheMgr.isLocked_ = false; - signDataCacheMgr.AddPendSignData(*aotArgs, versionCode, pendSignData, ret); - EXPECT_EQ(signDataCacheMgr.pendingSignData_.empty(), true); + signDataCacheMgr.AddSignDataForHap(*aotArgs, versionCode, pendSignData, ret); + EXPECT_EQ(signDataCacheMgr.hapSignDataVector_.empty(), true); ret = ERR_OK; - signDataCacheMgr.AddPendSignData(*aotArgs, versionCode, pendSignData2, ret); - EXPECT_EQ(signDataCacheMgr.pendingSignData_.empty(), true); + signDataCacheMgr.AddSignDataForHap(*aotArgs, versionCode, pendSignData2, ret); + EXPECT_EQ(signDataCacheMgr.hapSignDataVector_.empty(), true); ret = ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE; - signDataCacheMgr.AddPendSignData(*aotArgs, versionCode, pendSignData2, ret); - EXPECT_EQ(signDataCacheMgr.pendingSignData_.empty(), true); + signDataCacheMgr.AddSignDataForHap(*aotArgs, versionCode, pendSignData2, ret); + EXPECT_EQ(signDataCacheMgr.hapSignDataVector_.empty(), true); ret = ERR_OK; signDataCacheMgr.isLocked_ = true; - signDataCacheMgr.AddPendSignData(*aotArgs, versionCode, pendSignData2, ret); - EXPECT_EQ(signDataCacheMgr.pendingSignData_.empty(), true); + signDataCacheMgr.AddSignDataForHap(*aotArgs, versionCode, pendSignData2, ret); + EXPECT_EQ(signDataCacheMgr.hapSignDataVector_.empty(), true); ret = ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE; - signDataCacheMgr.AddPendSignData(*aotArgs2, versionCode, pendSignData2, ret); - EXPECT_EQ(signDataCacheMgr.pendingSignData_.empty(), true); - signDataCacheMgr.AddPendSignData(*aotArgs3, versionCode, pendSignData2, ret); - EXPECT_EQ(signDataCacheMgr.pendingSignData_.empty(), true); + signDataCacheMgr.AddSignDataForHap(*aotArgs2, versionCode, pendSignData2, ret); + EXPECT_EQ(signDataCacheMgr.hapSignDataVector_.empty(), true); + signDataCacheMgr.AddSignDataForHap(*aotArgs3, versionCode, pendSignData2, ret); + EXPECT_EQ(signDataCacheMgr.hapSignDataVector_.empty(), true); } /** @@ -1252,15 +1297,14 @@ HWTEST_F(BmsAOTMgrTest, AOTSignDataCacheMgr_0400, Function | SmallTest | Level0) /** * @tc.number: AOTSignDataCacheMgr_0500 - * @tc.name: test ExecutePendSign - * @tc.desc: test ExecutePendSign function running normally + * @tc.name: test EnforceCodeSign + * @tc.desc: test EnforceCodeSign function running normally */ HWTEST_F(BmsAOTMgrTest, AOTSignDataCacheMgr_0500, Function | SmallTest | Level0) { AOTSignDataCacheMgr& signDataCacheMgr = AOTSignDataCacheMgr::GetInstance(); - ErrCode ret = ERR_OK; - ret = signDataCacheMgr.ExecutePendSign(); - EXPECT_EQ(ret, ERR_OK); + bool ret = signDataCacheMgr.EnforceCodeSign(); + EXPECT_TRUE(ret); } /** @@ -1304,10 +1348,10 @@ HWTEST_F(BmsAOTMgrTest, AOTExecutor_1700, Function | SmallTest | Level0) std::string hapPath = ""; uint32_t offset = OFFSET; uint32_t length = LENGTH; - bool result = AOTExecutor::GetInstance().GetAbcFileInfo(hapPath, offset, length); + bool result = AOTExecutor::GetInstance().GetAbcFileInfo(hapPath, Constants::CODE_LANGUAGE_1_1, offset, length); EXPECT_FALSE(result); hapPath = HAP_PATH; - result = AOTExecutor::GetInstance().GetAbcFileInfo(hapPath, offset, length); + result = AOTExecutor::GetInstance().GetAbcFileInfo(hapPath, Constants::CODE_LANGUAGE_1_1, offset, length); EXPECT_FALSE(result); } @@ -1369,6 +1413,18 @@ HWTEST_F(BmsAOTMgrTest, AOTExecutor_2100, Function | SmallTest | Level0) EXPECT_EQ(res, ERR_APPEXECFWK_INSTALLD_AOT_EXECUTE_FAILED); } +/** + * @tc.number: AOTExecutor_2200 + * @tc.name: test GetAbcRelativePath + * @tc.desc: system running normally + */ +HWTEST_F(BmsAOTMgrTest, AOTExecutor_2200, Function | SmallTest | Level0) +{ + EXPECT_EQ(AOTExecutor::GetInstance().GetAbcRelativePath(Constants::CODE_LANGUAGE_1_1), ABC_RELATIVE_PATH); + EXPECT_EQ(AOTExecutor::GetInstance().GetAbcRelativePath(Constants::CODE_LANGUAGE_1_2), STATIC_ABC_RELATIVE_PATH); + EXPECT_EQ(AOTExecutor::GetInstance().GetAbcRelativePath(Constants::EMPTY_STRING), Constants::EMPTY_STRING); +} + /** * @tc.number: AOTHandler_3200 * @tc.name: test MkApDestDirIfNotExist @@ -1706,8 +1762,8 @@ HWTEST_F(BmsAOTMgrTest, AOTArgs_0300, Function | SmallTest | Level1) /** * @tc.number: AOTSignDataCacheMgr_0600 - * @tc.name: test ExecutePendSign - * @tc.desc: test ExecutePendSign function running normally + * @tc.name: test EnforceCodeSign + * @tc.desc: test EnforceCodeSign function running normally */ HWTEST_F(BmsAOTMgrTest, AOTSignDataCacheMgr_0600, Function | SmallTest | Level0) { @@ -1719,10 +1775,10 @@ HWTEST_F(BmsAOTMgrTest, AOTSignDataCacheMgr_0600, Function | SmallTest | Level0) aotArgs = aotArg; int32_t versionCode = 1; std::vector pendSignData(HAP_PATH.begin(), HAP_PATH.end()); - ErrCode ret = ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE; - AOTSignDataCacheMgr::GetInstance().AddPendSignData(*aotArgs, versionCode, pendSignData, ret); - ret = signDataCacheMgr.ExecutePendSign(); - EXPECT_EQ(ret, ERR_OK); + ErrCode result = ERR_OK; + AOTSignDataCacheMgr::GetInstance().AddSignDataForHap(*aotArgs, versionCode, pendSignData, result); + bool ret = signDataCacheMgr.EnforceCodeSign(); + EXPECT_TRUE(ret); } /** @@ -1732,75 +1788,57 @@ HWTEST_F(BmsAOTMgrTest, AOTSignDataCacheMgr_0600, Function | SmallTest | Level0) */ HWTEST_F(BmsAOTMgrTest, AOTSignDataCacheMgr_0700, Function | SmallTest | Level1) { - AOTSignDataCacheMgr &signDataCacheMgr = AOTSignDataCacheMgr::GetInstance(); - signDataCacheMgr.isLocked_ = true; - std::string key = "key"; - AppExecFwk::AOTSignDataCacheMgr::PendingData data; - std::unordered_map datas; - datas.emplace(key, data); - auto dataMgr = DelayedSingleton::GetInstance()->GetDataMgr(); - DelayedSingleton::GetInstance()->dataMgr_ = nullptr; - signDataCacheMgr.pendingSignData_.emplace(key, datas); - signDataCacheMgr.HandleUnlockEvent(); - EXPECT_FALSE(signDataCacheMgr.isLocked_); - DelayedSingleton::GetInstance()->dataMgr_ = dataMgr; + AOTSignDataCacheMgr::GetInstance().isLocked_ = true; + AOTSignDataCacheMgr::GetInstance().HandleUnlockEvent(); + EXPECT_FALSE(AOTSignDataCacheMgr::GetInstance().isLocked_); } /** * @tc.number: AOTSignDataCacheMgr_0800 - * @tc.name: Test ExecutePendSign - * @tc.desc: 1.ExecutePendSign + * @tc.name: Test EnforceCodeSign + * @tc.desc: 1.EnforceCodeSign */ HWTEST_F(BmsAOTMgrTest, AOTSignDataCacheMgr_0800, Function | SmallTest | Level1) { AOTSignDataCacheMgr &signDataCacheMgr = AOTSignDataCacheMgr::GetInstance(); - std::string key = "key"; - AppExecFwk::AOTSignDataCacheMgr::PendingData data; - std::unordered_map datas; - datas.emplace(key, data); - signDataCacheMgr.pendingSignData_[key]= datas; + AppExecFwk::AOTSignDataCacheMgr::HapSignData data; + signDataCacheMgr.hapSignDataVector_.emplace_back(data); SetPendSignAOTCode(ERR_OK); InstalldClient::GetInstance()->installdProxy_ = new (std::nothrow) MockInstalldProxy(nullptr); - auto ret = signDataCacheMgr.ExecutePendSign(); - EXPECT_EQ(ret, ERR_OK); + bool ret = signDataCacheMgr.EnforceCodeSign(); + EXPECT_TRUE(ret); } /** * @tc.number: AOTSignDataCacheMgr_0900 - * @tc.name: Test ExecutePendSign - * @tc.desc: 1.ExecutePendSign + * @tc.name: Test EnforceCodeSign + * @tc.desc: 1.EnforceCodeSign */ HWTEST_F(BmsAOTMgrTest, AOTSignDataCacheMgr_0900, Function | SmallTest | Level1) { AOTSignDataCacheMgr &signDataCacheMgr = AOTSignDataCacheMgr::GetInstance(); - std::string key = "key"; - AppExecFwk::AOTSignDataCacheMgr::PendingData data; - std::unordered_map datas; - datas.emplace(key, data); - signDataCacheMgr.pendingSignData_[key] = datas; + AppExecFwk::AOTSignDataCacheMgr::HapSignData data; + signDataCacheMgr.hapSignDataVector_.emplace_back(data); SetPendSignAOTCode(ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE); InstalldClient::GetInstance()->installdProxy_ = new (std::nothrow) MockInstalldProxy(nullptr); - auto ret = signDataCacheMgr.ExecutePendSign(); - EXPECT_EQ(ret, ERR_APPEXECFWK_INSTALLD_SIGN_AOT_FAILED); + bool ret = signDataCacheMgr.EnforceCodeSign(); + EXPECT_FALSE(ret); } /** * @tc.number: AOTSignDataCacheMgr_1000 - * @tc.name: Test ExecutePendSign - * @tc.desc: 1.ExecutePendSign + * @tc.name: Test EnforceCodeSign + * @tc.desc: 1.EnforceCodeSign */ HWTEST_F(BmsAOTMgrTest, AOTSignDataCacheMgr_1000, Function | SmallTest | Level1) { AOTSignDataCacheMgr &signDataCacheMgr = AOTSignDataCacheMgr::GetInstance(); - std::string key = "key"; - AppExecFwk::AOTSignDataCacheMgr::PendingData data; - std::unordered_map datas; - datas.emplace(key, data); - signDataCacheMgr.pendingSignData_[key] = datas; + AppExecFwk::AOTSignDataCacheMgr::HapSignData data; + signDataCacheMgr.hapSignDataVector_.emplace_back(data); SetPendSignAOTCode(ERR_APPEXECFWK_INSTALLD_PARAM_ERROR); InstalldClient::GetInstance()->installdProxy_ = new (std::nothrow) MockInstalldProxy(nullptr); - auto ret = signDataCacheMgr.ExecutePendSign(); - EXPECT_EQ(ret, ERR_OK); + bool ret = signDataCacheMgr.EnforceCodeSign(); + EXPECT_TRUE(ret); InstalldClient::GetInstance()->installdProxy_ = nullptr; InstalldClient::GetInstance()->GetInstalldProxy(); } @@ -1945,4 +1983,257 @@ HWTEST_F(BmsAOTMgrTest, GetBundleNamesForNewUser_0100, Function | SmallTest | Le dataMgr->bundleInfos_.clear(); OHOS::system::SetParameter(ServiceConstants::IS_DRIVER_FOR_ALL_USERS, "true"); } -} // OHOS + +/** + * @tc.number: AddSignDataForSysComp_0100 + * @tc.name: Test AddSignDataForSysComp + * @tc.desc: 1.AddSignDataForSysComp success testcase + */ +HWTEST_F(BmsAOTMgrTest, AddSignDataForSysComp_0100, Function | SmallTest | Level1) +{ + AOTSignDataCacheMgr::GetInstance().sysCompSignDataMap_.clear(); + + std::string anFileName = "anFileName"; + std::vector signData = {0}; + AOTSignDataCacheMgr::GetInstance().isLocked_ = true; + ErrCode ret = ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE; + AOTSignDataCacheMgr::GetInstance().AddSignDataForSysComp(anFileName, signData, ret); + size_t size = AOTSignDataCacheMgr::GetInstance().sysCompSignDataMap_.size(); + EXPECT_NE(size, 0); + + AOTSignDataCacheMgr::GetInstance().sysCompSignDataMap_.clear(); +} + +/** + * @tc.number: AddSignDataForSysComp_0200 + * @tc.name: Test AddSignDataForSysComp + * @tc.desc: 1.AddSignDataForSysComp, anFileName is empty + */ +HWTEST_F(BmsAOTMgrTest, AddSignDataForSysComp_0200, Function | SmallTest | Level1) +{ + AOTSignDataCacheMgr::GetInstance().sysCompSignDataMap_.clear(); + + std::string anFileName; + std::vector signData = {0}; + AOTSignDataCacheMgr::GetInstance().isLocked_ = true; + ErrCode ret = ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE; + AOTSignDataCacheMgr::GetInstance().AddSignDataForSysComp(anFileName, signData, ret); + size_t size = AOTSignDataCacheMgr::GetInstance().sysCompSignDataMap_.size(); + EXPECT_EQ(size, 0); +} + +/** + * @tc.number: AddSignDataForSysComp_0300 + * @tc.name: Test AddSignDataForSysComp + * @tc.desc: 1.AddSignDataForSysComp, signData is empty + */ +HWTEST_F(BmsAOTMgrTest, AddSignDataForSysComp_0300, Function | SmallTest | Level1) +{ + AOTSignDataCacheMgr::GetInstance().sysCompSignDataMap_.clear(); + + std::string anFileName = "anFileName"; + std::vector signData; + AOTSignDataCacheMgr::GetInstance().isLocked_ = true; + ErrCode ret = ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE; + AOTSignDataCacheMgr::GetInstance().AddSignDataForSysComp(anFileName, signData, ret); + size_t size = AOTSignDataCacheMgr::GetInstance().sysCompSignDataMap_.size(); + EXPECT_EQ(size, 0); +} + +/** + * @tc.number: AddSignDataForSysComp_0400 + * @tc.name: Test AddSignDataForSysComp + * @tc.desc: 1.AddSignDataForSysComp, isLocked_ is false + */ +HWTEST_F(BmsAOTMgrTest, AddSignDataForSysComp_0400, Function | SmallTest | Level1) +{ + AOTSignDataCacheMgr::GetInstance().sysCompSignDataMap_.clear(); + + std::string anFileName = "anFileName"; + std::vector signData = {0}; + AOTSignDataCacheMgr::GetInstance().isLocked_ = false; + ErrCode ret = ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE; + AOTSignDataCacheMgr::GetInstance().AddSignDataForSysComp(anFileName, signData, ret); + size_t size = AOTSignDataCacheMgr::GetInstance().sysCompSignDataMap_.size(); + EXPECT_EQ(size, 0); +} + +/** + * @tc.number: AddSignDataForSysComp_0500 + * @tc.name: Test AddSignDataForSysComp + * @tc.desc: 1.AddSignDataForSysComp, ret is ERR_OK + */ +HWTEST_F(BmsAOTMgrTest, AddSignDataForSysComp_0500, Function | SmallTest | Level1) +{ + AOTSignDataCacheMgr::GetInstance().sysCompSignDataMap_.clear(); + + std::string anFileName = "anFileName"; + std::vector signData = {0}; + AOTSignDataCacheMgr::GetInstance().isLocked_ = true; + ErrCode ret = ERR_OK; + AOTSignDataCacheMgr::GetInstance().AddSignDataForSysComp(anFileName, signData, ret); + size_t size = AOTSignDataCacheMgr::GetInstance().sysCompSignDataMap_.size(); + EXPECT_EQ(size, 0); +} + +/** + * @tc.number: AddSignDataForHap_0100 + * @tc.name: Test AddSignDataForHap + * @tc.desc: 1.AddSignDataForHap success testcase + */ +HWTEST_F(BmsAOTMgrTest, AddSignDataForHap_0100, Function | SmallTest | Level1) +{ + AOTSignDataCacheMgr::GetInstance().hapSignDataVector_.clear(); + + AOTArgs aotArgs; + aotArgs.bundleName = "bundleName"; + aotArgs.moduleName = "moduleName"; + std::vector signData = {0}; + AOTSignDataCacheMgr::GetInstance().isLocked_ = true; + ErrCode ret = ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE; + + AOTSignDataCacheMgr::GetInstance().AddSignDataForHap(aotArgs, 0, signData, ret); + size_t size = AOTSignDataCacheMgr::GetInstance().hapSignDataVector_.size(); + EXPECT_NE(size, 0); + + AOTSignDataCacheMgr::GetInstance().hapSignDataVector_.clear(); +} + +/** + * @tc.number: AddSignDataForHap_0200 + * @tc.name: Test AddSignDataForHap + * @tc.desc: 1.AddSignDataForHap failed testcase, bundleName is empty + */ +HWTEST_F(BmsAOTMgrTest, AddSignDataForHap_0200, Function | SmallTest | Level1) +{ + AOTSignDataCacheMgr::GetInstance().hapSignDataVector_.clear(); + + AOTArgs aotArgs; + aotArgs.bundleName; + aotArgs.moduleName = "moduleName"; + std::vector signData = {0}; + AOTSignDataCacheMgr::GetInstance().isLocked_ = true; + ErrCode ret = ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE; + + AOTSignDataCacheMgr::GetInstance().AddSignDataForHap(aotArgs, 0, signData, ret); + size_t size = AOTSignDataCacheMgr::GetInstance().hapSignDataVector_.size(); + EXPECT_EQ(size, 0); +} + +/** + * @tc.number: AddSignDataForHap_0300 + * @tc.name: Test AddSignDataForHap + * @tc.desc: 1.AddSignDataForHap failed testcase, moduleName is empty + */ +HWTEST_F(BmsAOTMgrTest, AddSignDataForHap_0300, Function | SmallTest | Level1) +{ + AOTSignDataCacheMgr::GetInstance().hapSignDataVector_.clear(); + + AOTArgs aotArgs; + aotArgs.bundleName = "bundleName"; + aotArgs.moduleName; + std::vector signData = {0}; + AOTSignDataCacheMgr::GetInstance().isLocked_ = true; + ErrCode ret = ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE; + + AOTSignDataCacheMgr::GetInstance().AddSignDataForHap(aotArgs, 0, signData, ret); + size_t size = AOTSignDataCacheMgr::GetInstance().hapSignDataVector_.size(); + EXPECT_EQ(size, 0); +} + +/** + * @tc.number: AddSignDataForHap_0400 + * @tc.name: Test AddSignDataForHap + * @tc.desc: 1.AddSignDataForHap failed testcase, signData is empty + */ +HWTEST_F(BmsAOTMgrTest, AddSignDataForHap_0400, Function | SmallTest | Level1) +{ + AOTSignDataCacheMgr::GetInstance().hapSignDataVector_.clear(); + + AOTArgs aotArgs; + aotArgs.bundleName = "bundleName"; + aotArgs.moduleName = "moduleName"; + std::vector signData; + AOTSignDataCacheMgr::GetInstance().isLocked_ = true; + ErrCode ret = ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE; + + AOTSignDataCacheMgr::GetInstance().AddSignDataForHap(aotArgs, 0, signData, ret); + size_t size = AOTSignDataCacheMgr::GetInstance().hapSignDataVector_.size(); + EXPECT_EQ(size, 0); +} + +/** + * @tc.number: AddSignDataForHap_0500 + * @tc.name: Test AddSignDataForHap + * @tc.desc: 1.AddSignDataForHap failed testcase, isLocked_ is false + */ +HWTEST_F(BmsAOTMgrTest, AddSignDataForHap_0500, Function | SmallTest | Level1) +{ + AOTSignDataCacheMgr::GetInstance().hapSignDataVector_.clear(); + + AOTArgs aotArgs; + aotArgs.bundleName = "bundleName"; + aotArgs.moduleName = "moduleName"; + std::vector signData = {0}; + AOTSignDataCacheMgr::GetInstance().isLocked_ = false; + ErrCode ret = ERR_APPEXECFWK_INSTALLD_SIGN_AOT_DISABLE; + + AOTSignDataCacheMgr::GetInstance().AddSignDataForHap(aotArgs, 0, signData, ret); + size_t size = AOTSignDataCacheMgr::GetInstance().hapSignDataVector_.size(); + EXPECT_EQ(size, 0); +} + +/** + * @tc.number: AddSignDataForHap_0600 + * @tc.name: Test AddSignDataForHap + * @tc.desc: 1.AddSignDataForHap failed testcase, ret is ERR_OK + */ +HWTEST_F(BmsAOTMgrTest, AddSignDataForHap_0600, Function | SmallTest | Level1) +{ + AOTSignDataCacheMgr::GetInstance().hapSignDataVector_.clear(); + + AOTArgs aotArgs; + aotArgs.bundleName = "bundleName"; + aotArgs.moduleName = "moduleName"; + std::vector signData = {0}; + AOTSignDataCacheMgr::GetInstance().isLocked_ = true; + ErrCode ret = ERR_OK; + + AOTSignDataCacheMgr::GetInstance().AddSignDataForHap(aotArgs, 0, signData, ret); + size_t size = AOTSignDataCacheMgr::GetInstance().hapSignDataVector_.size(); + EXPECT_EQ(size, 0); +} + +/** + * @tc.number: EnforceCodeSign_0100 + * @tc.name: Test EnforceCodeSign + * @tc.desc: 1.EnforceCodeSign success testcase + */ +HWTEST_F(BmsAOTMgrTest, EnforceCodeSign_0100, Function | SmallTest | Level1) +{ + bool ret = AOTSignDataCacheMgr::GetInstance().EnforceCodeSign(); + EXPECT_TRUE(ret); +} + +/** + * @tc.number: EnforceCodeSignForSysComp_0100 + * @tc.name: Test EnforceCodeSignForSysComp + * @tc.desc: 1.EnforceCodeSignForSysComp success testcase + */ +HWTEST_F(BmsAOTMgrTest, EnforceCodeSignForSysComp_0100, Function | SmallTest | Level1) +{ + bool ret = AOTSignDataCacheMgr::GetInstance().EnforceCodeSignForSysComp(); + EXPECT_TRUE(ret); +} + +/** + * @tc.number: EnforceCodeSignForHap_0100 + * @tc.name: Test EnforceCodeSignForHap + * @tc.desc: 1.EnforceCodeSignForHap success testcase + */ +HWTEST_F(BmsAOTMgrTest, EnforceCodeSignForHap_0100, Function | SmallTest | Level1) +{ + bool ret = AOTSignDataCacheMgr::GetInstance().EnforceCodeSignForHap(); + EXPECT_TRUE(ret); +} +} // OHOS \ No newline at end of file diff --git a/services/bundlemgr/test/unittest/bms_bundle_data_storage_test/bms_bundle_data_storage_database_test.cpp b/services/bundlemgr/test/unittest/bms_bundle_data_storage_test/bms_bundle_data_storage_database_test.cpp index 2441f1306339b0126201d8eeffe71fc8a612eb38..ad925fa069ce4ba7f3ac1859dad782c3a53b5517 100644 --- a/services/bundlemgr/test/unittest/bms_bundle_data_storage_test/bms_bundle_data_storage_database_test.cpp +++ b/services/bundlemgr/test/unittest/bms_bundle_data_storage_test/bms_bundle_data_storage_database_test.cpp @@ -73,6 +73,7 @@ int32_t userId = 1; int32_t userId2 = 2; int32_t appIndex = 1; const int32_t FLAG = 0; +const int32_t INFO_COUNT = 16; const nlohmann::json EXTEND_RESOURCE_INFO_ERROR_JSON = R"( { "moduleName":[] @@ -853,6 +854,7 @@ protected: "applicationName": "com.ohos.launcher", "backgroundModes": 0, "bundleName": "com.ohos.launcher", + "codeLanguage": "1.1", "codePath": "", "compileMode": 0, "configChanges": [ @@ -1109,6 +1111,7 @@ protected: "asanLogPath": "", "bundleName": "com.ohos.launcher", "cacheDir": "/data/app/el2/100/base/com.ohos.launcher/cache", + "codeLanguage": "1.1", "codePath": "/data/app/el1/bundle/public/com.ohos.launcher", "compileSdkType":"OpenHarmony", "compileSdkVersion":"", @@ -5117,4 +5120,309 @@ HWTEST_F(BmsBundleDataStorageDatabaseTest, InnerBundleInfo_13200, Function | Sma auto iter2 = info.FindHapModuleInfo(TEST_NAME, 100); EXPECT_EQ(iter2->hasIntent, true); } + +/** + * @tc.number: GetApplicationCodeLanguage_0001 + * @tc.name: test GetApplicationCodeLanguage + * @tc.desc: 1. test GetApplicationCodeLanguage of InnerBundleInfo on empty innerModuleInfos_ + */ +HWTEST_F(BmsBundleDataStorageDatabaseTest, GetApplicationCodeLanguage_0001, Function | SmallTest | Level1) + +{ + InnerBundleInfo innerBundleInfo; + EXPECT_EQ(innerBundleInfo.GetApplicationCodeLanguage(), Constants::CODE_LANGUAGE_1_1); +} + +/** + * @tc.number: GetApplicationCodeLanguage_0002 + * @tc.name: test GetApplicationCodeLanguage + * @tc.desc: 1. test GetApplicationCodeLanguage of InnerBundleInfo + */ +HWTEST_F(BmsBundleDataStorageDatabaseTest, GetApplicationCodeLanguage_0002, Function | SmallTest | Level1) +{ + InnerBundleInfo innerBundleInfo; + + for (int32_t i = 0; i < INFO_COUNT; ++i) { + InnerModuleInfo innerModuleInfo; + innerModuleInfo.codeLanguage = Constants::CODE_LANGUAGE_1_1; + innerBundleInfo.innerModuleInfos_.insert(std::make_pair(std::to_string(i), innerModuleInfo)); + } + + EXPECT_EQ(innerBundleInfo.GetApplicationCodeLanguage(), Constants::CODE_LANGUAGE_1_1); +} + +/** + * @tc.number: GetApplicationCodeLanguage_0003 + * @tc.name: test GetApplicationCodeLanguage + * @tc.desc: 1. test GetApplicationCodeLanguage of InnerBundleInfo + */ +HWTEST_F(BmsBundleDataStorageDatabaseTest, GetApplicationCodeLanguage_0003, Function | SmallTest | Level1) +{ + InnerBundleInfo innerBundleInfo; + + for (int32_t i = 0; i < INFO_COUNT; ++i) { + InnerModuleInfo innerModuleInfo; + innerModuleInfo.codeLanguage = Constants::CODE_LANGUAGE_1_2; + innerBundleInfo.innerModuleInfos_.insert(std::make_pair(std::to_string(i), innerModuleInfo)); + } + + EXPECT_EQ(innerBundleInfo.GetApplicationCodeLanguage(), Constants::CODE_LANGUAGE_1_2); +} + +/** + * @tc.number: GetApplicationCodeLanguage_0004 + * @tc.name: test GetApplicationCodeLanguage + * @tc.desc: 1. test GetApplicationCodeLanguage of InnerBundleInfo + */ +HWTEST_F(BmsBundleDataStorageDatabaseTest, GetApplicationCodeLanguage_0004, Function | SmallTest | Level1) +{ + InnerBundleInfo innerBundleInfo; + + for (int32_t i = 0; i < INFO_COUNT; ++i) { + InnerModuleInfo innerModuleInfo; + innerModuleInfo.codeLanguage = i % 3 == 0 ? Constants::CODE_LANGUAGE_1_2 : Constants::CODE_LANGUAGE_1_1; + innerBundleInfo.innerModuleInfos_.insert(std::make_pair(std::to_string(i), innerModuleInfo)); + } + + EXPECT_EQ(innerBundleInfo.GetApplicationCodeLanguage(), Constants::CODE_LANGUAGE_HYBRID); +} + +/** + * @tc.number: GetModuleCodeLanguage_0001 + * @tc.name: test GetModuleCodeLanguage + * @tc.desc: 1. test GetModuleCodeLanguage of InnerBundleInfo + */ +HWTEST_F(BmsBundleDataStorageDatabaseTest, GetModuleCodeLanguage_0001, Function | SmallTest | Level1) +{ + InnerBundleInfo innerBundleInfo; + + for (int32_t i = 0; i < INFO_COUNT; ++i) { + InnerModuleInfo innerModuleInfo; + innerModuleInfo.codeLanguage = i % 3 == 0 ? Constants::CODE_LANGUAGE_1_2 : Constants::CODE_LANGUAGE_1_1; + innerBundleInfo.innerModuleInfos_.insert(std::make_pair(std::to_string(i), innerModuleInfo)); + } + + std::string result = innerBundleInfo.GetModuleCodeLanguage(std::to_string(INFO_COUNT)); + EXPECT_EQ(result, Constants::EMPTY_STRING); + for (int32_t i = 0; i < INFO_COUNT; ++i) { + result = innerBundleInfo.GetModuleCodeLanguage(std::to_string(i)); + EXPECT_EQ(result, i % 3 == 0 ? Constants::CODE_LANGUAGE_1_2 : Constants::CODE_LANGUAGE_1_1); + } +} + +/** + * @tc.number: AbilityInfo_0001 + * @tc.name: test AbilityInfo + * @tc.desc: 1. test AbilityInfo fromJson/toJson + */ +HWTEST_F(BmsBundleDataStorageDatabaseTest, AbilityInfo_0001, Function | SmallTest | Level1) +{ + AbilityInfo sourceInfo; + nlohmann::json jsonObject = sourceInfo; + AbilityInfo fromJsonInfo = jsonObject; + EXPECT_EQ(fromJsonInfo.codeLanguage, Constants::CODE_LANGUAGE_1_1); + + sourceInfo.codeLanguage = Constants::CODE_LANGUAGE_1_1; + jsonObject = sourceInfo; + fromJsonInfo = jsonObject; + EXPECT_EQ(fromJsonInfo.codeLanguage, Constants::CODE_LANGUAGE_1_1); + + sourceInfo.codeLanguage = Constants::CODE_LANGUAGE_1_2; + jsonObject = sourceInfo; + fromJsonInfo = jsonObject; + EXPECT_EQ(fromJsonInfo.codeLanguage, Constants::CODE_LANGUAGE_1_2); +} + +/** + * @tc.number: AbilityInfo_0002 + * @tc.name: test AbilityInfo + * @tc.desc: 1. test AbilityInfo Marshalling/ReadFromParcel + */ +HWTEST_F(BmsBundleDataStorageDatabaseTest, AbilityInfo_0002, Function | SmallTest | Level1) +{ + AbilityInfo sourceInfo; + Parcel parcel; + bool ret = sourceInfo.Marshalling(parcel); + EXPECT_EQ(ret, true); + AbilityInfo targetInfo; + ret = targetInfo.ReadFromParcel(parcel); + EXPECT_EQ(ret, true); + EXPECT_EQ(targetInfo.codeLanguage, Constants::CODE_LANGUAGE_1_1); + + sourceInfo.codeLanguage = Constants::CODE_LANGUAGE_1_1; + ret = sourceInfo.Marshalling(parcel); + EXPECT_EQ(ret, true); + ret = targetInfo.ReadFromParcel(parcel); + EXPECT_EQ(ret, true); + EXPECT_EQ(targetInfo.codeLanguage, Constants::CODE_LANGUAGE_1_1); + + sourceInfo.codeLanguage = Constants::CODE_LANGUAGE_1_2; + ret = sourceInfo.Marshalling(parcel); + EXPECT_EQ(ret, true); + ret = targetInfo.ReadFromParcel(parcel); + EXPECT_EQ(ret, true); + EXPECT_EQ(targetInfo.codeLanguage, Constants::CODE_LANGUAGE_1_2); +} + +/** + * @tc.number: ExtensionAbilityInfo_0001 + * @tc.name: test ExtensionAbilityInfo + * @tc.desc: 1. test ExtensionAbilityInfo fromJson/toJson + */ +HWTEST_F(BmsBundleDataStorageDatabaseTest, ExtensionAbilityInfo_0001, Function | SmallTest | Level1) +{ + ExtensionAbilityInfo sourceInfo; + nlohmann::json jsonObject = sourceInfo; + ExtensionAbilityInfo fromJsonInfo = jsonObject; + EXPECT_EQ(fromJsonInfo.codeLanguage, Constants::CODE_LANGUAGE_1_1); + + sourceInfo.codeLanguage = Constants::CODE_LANGUAGE_1_1; + jsonObject = sourceInfo; + fromJsonInfo = jsonObject; + EXPECT_EQ(fromJsonInfo.codeLanguage, Constants::CODE_LANGUAGE_1_1); + + sourceInfo.codeLanguage = Constants::CODE_LANGUAGE_1_2; + jsonObject = sourceInfo; + fromJsonInfo = jsonObject; + EXPECT_EQ(fromJsonInfo.codeLanguage, Constants::CODE_LANGUAGE_1_2); +} + +/** + * @tc.number: ExtensionAbilityInfo_0002 + * @tc.name: test ExtensionAbilityInfo + * @tc.desc: 1. test ExtensionAbilityInfo Marshalling/ReadFromParcel + */ +HWTEST_F(BmsBundleDataStorageDatabaseTest, ExtensionAbilityInfo_0002, Function | SmallTest | Level1) +{ + ExtensionAbilityInfo sourceInfo; + Parcel parcel; + bool ret = sourceInfo.Marshalling(parcel); + EXPECT_EQ(ret, true); + ExtensionAbilityInfo targetInfo; + ret = targetInfo.ReadFromParcel(parcel); + EXPECT_EQ(ret, true); + EXPECT_EQ(targetInfo.codeLanguage, Constants::CODE_LANGUAGE_1_1); + + sourceInfo.codeLanguage = Constants::CODE_LANGUAGE_1_1; + ret = sourceInfo.Marshalling(parcel); + EXPECT_EQ(ret, true); + ret = targetInfo.ReadFromParcel(parcel); + EXPECT_EQ(ret, true); + EXPECT_EQ(targetInfo.codeLanguage, Constants::CODE_LANGUAGE_1_1); + + sourceInfo.codeLanguage = Constants::CODE_LANGUAGE_1_2; + ret = sourceInfo.Marshalling(parcel); + EXPECT_EQ(ret, true); + ret = targetInfo.ReadFromParcel(parcel); + EXPECT_EQ(ret, true); + EXPECT_EQ(targetInfo.codeLanguage, Constants::CODE_LANGUAGE_1_2); +} + +/** + * @tc.number: HapModuleInfo_0001 + * @tc.name: test HapModuleInfo + * @tc.desc: 1. test HapModuleInfo fromJson/toJson + */ +HWTEST_F(BmsBundleDataStorageDatabaseTest, HapModuleInfo_0001, Function | SmallTest | Level1) +{ + HapModuleInfo sourceInfo; + nlohmann::json jsonObject = sourceInfo; + HapModuleInfo fromJsonInfo = jsonObject; + EXPECT_EQ(fromJsonInfo.codeLanguage, Constants::CODE_LANGUAGE_1_1); + + sourceInfo.codeLanguage = Constants::CODE_LANGUAGE_1_1; + jsonObject = sourceInfo; + fromJsonInfo = jsonObject; + EXPECT_EQ(fromJsonInfo.codeLanguage, Constants::CODE_LANGUAGE_1_1); + + sourceInfo.codeLanguage = Constants::CODE_LANGUAGE_1_2; + jsonObject = sourceInfo; + fromJsonInfo = jsonObject; + EXPECT_EQ(fromJsonInfo.codeLanguage, Constants::CODE_LANGUAGE_1_2); +} + +/** + * @tc.number: HapModuleInfo_0002 + * @tc.name: test HapModuleInfo + * @tc.desc: 1. test HapModuleInfo Marshalling/ReadFromParcel + */ +HWTEST_F(BmsBundleDataStorageDatabaseTest, HapModuleInfo_0002, Function | SmallTest | Level1) +{ + HapModuleInfo sourceInfo; + Parcel parcel; + bool ret = sourceInfo.Marshalling(parcel); + EXPECT_EQ(ret, true); + HapModuleInfo targetInfo; + ret = targetInfo.ReadFromParcel(parcel); + EXPECT_EQ(ret, true); + EXPECT_EQ(targetInfo.codeLanguage, Constants::CODE_LANGUAGE_1_1); + + sourceInfo.codeLanguage = Constants::CODE_LANGUAGE_1_1; + ret = sourceInfo.Marshalling(parcel); + EXPECT_EQ(ret, true); + ret = targetInfo.ReadFromParcel(parcel); + EXPECT_EQ(ret, true); + EXPECT_EQ(targetInfo.codeLanguage, Constants::CODE_LANGUAGE_1_1); + + sourceInfo.codeLanguage = Constants::CODE_LANGUAGE_1_2; + ret = sourceInfo.Marshalling(parcel); + EXPECT_EQ(ret, true); + ret = targetInfo.ReadFromParcel(parcel); + EXPECT_EQ(ret, true); + EXPECT_EQ(targetInfo.codeLanguage, Constants::CODE_LANGUAGE_1_2); +} + +/** + * @tc.number: ApplicationInfo_0001 + * @tc.name: test ApplicationInfo + * @tc.desc: 1. test ApplicationInfo fromJson/toJson + */ +HWTEST_F(BmsBundleDataStorageDatabaseTest, ApplicationInfo_0001, Function | SmallTest | Level1) +{ + ApplicationInfo sourceInfo; + nlohmann::json jsonObject = sourceInfo; + ApplicationInfo fromJsonInfo = jsonObject; + EXPECT_EQ(fromJsonInfo.codeLanguage, Constants::EMPTY_STRING); + + sourceInfo.codeLanguage = Constants::CODE_LANGUAGE_1_1; + jsonObject = sourceInfo; + fromJsonInfo = jsonObject; + EXPECT_EQ(fromJsonInfo.codeLanguage, Constants::CODE_LANGUAGE_1_1); + + sourceInfo.codeLanguage = Constants::CODE_LANGUAGE_1_2; + jsonObject = sourceInfo; + fromJsonInfo = jsonObject; + EXPECT_EQ(fromJsonInfo.codeLanguage, Constants::CODE_LANGUAGE_1_2); +} + +/** + * @tc.number: ApplicationInfo_0002 + * @tc.name: test ApplicationInfo + * @tc.desc: 1. test ApplicationInfo Marshalling/ReadFromParcel + */ +HWTEST_F(BmsBundleDataStorageDatabaseTest, ApplicationInfo_0002, Function | SmallTest | Level1) +{ + ApplicationInfo sourceInfo; + Parcel parcel; + bool ret = sourceInfo.Marshalling(parcel); + EXPECT_EQ(ret, true); + ApplicationInfo targetInfo; + ret = targetInfo.ReadFromParcel(parcel); + EXPECT_EQ(ret, true); + EXPECT_EQ(targetInfo.codeLanguage, Constants::EMPTY_STRING); + + sourceInfo.codeLanguage = Constants::CODE_LANGUAGE_1_1; + ret = sourceInfo.Marshalling(parcel); + EXPECT_EQ(ret, true); + ret = targetInfo.ReadFromParcel(parcel); + EXPECT_EQ(ret, true); + EXPECT_EQ(targetInfo.codeLanguage, Constants::CODE_LANGUAGE_1_1); + + sourceInfo.codeLanguage = Constants::CODE_LANGUAGE_1_2; + ret = sourceInfo.Marshalling(parcel); + EXPECT_EQ(ret, true); + ret = targetInfo.ReadFromParcel(parcel); + EXPECT_EQ(ret, true); + EXPECT_EQ(targetInfo.codeLanguage, Constants::CODE_LANGUAGE_1_2); +} } // OHOS \ No newline at end of file diff --git a/services/bundlemgr/test/unittest/bms_bundle_default_app_test/bms_bundle_default_app_test.cpp b/services/bundlemgr/test/unittest/bms_bundle_default_app_test/bms_bundle_default_app_test.cpp index 1e6141c5df871bdd124691c94ac0ac7a18d723f5..57624200e17d6ab2f35b7f076101ceae96b65bec 100644 --- a/services/bundlemgr/test/unittest/bms_bundle_default_app_test/bms_bundle_default_app_test.cpp +++ b/services/bundlemgr/test/unittest/bms_bundle_default_app_test/bms_bundle_default_app_test.cpp @@ -1776,7 +1776,7 @@ HWTEST_F(BmsBundleDefaultAppTest, AOT_EXECUTOR_0100, Function | SmallTest | Leve std::string hapPath = "/data/test.hap"; uint32_t offset = 0; uint32_t length = 0; - ret = AOTExecutor::GetInstance().GetAbcFileInfo(hapPath, offset, length); + ret = AOTExecutor::GetInstance().GetAbcFileInfo(hapPath, Constants::CODE_LANGUAGE_1_1, offset, length); EXPECT_EQ(ret, false); AOTArgs completeArgs; diff --git a/services/bundlemgr/test/unittest/bms_installd_client_test/bms_installd_client_test.cpp b/services/bundlemgr/test/unittest/bms_installd_client_test/bms_installd_client_test.cpp index bf71ade29d61eab2a6915860deae222cf5443152..49d25fecc657a22930794a8251f923ce7d5f0277 100644 --- a/services/bundlemgr/test/unittest/bms_installd_client_test/bms_installd_client_test.cpp +++ b/services/bundlemgr/test/unittest/bms_installd_client_test/bms_installd_client_test.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023-2024 Huawei Device Co., Ltd. + * Copyright (c) 2023-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 @@ -13,7 +13,10 @@ * limitations under the License. */ +#include +#include #include +#include #define private public #define protected public @@ -48,10 +51,12 @@ const std::string DIFF_FILE_PATH = "diffFilePath"; const std::string NEW_SO_PATH = "newSoPath"; const std::string SOURCE_DIR = "sourceDir"; const std::string DESTINATION_DIR = "destinationDir"; +const std::string TMP_DIR = "/data/app/el1/bundle/public/bms-test/"; const int32_t USERID = 100; const int32_t UID = 1000; const int32_t GID = 1000; const std::string EMPTY_STRING = ""; +constexpr uint32_t INSTALLS_UID = 3060; } // namespace class BmsInstalldClientTest : public testing::Test { @@ -498,9 +503,7 @@ HWTEST_F(BmsInstalldClientTest, BmsInstalldClientTest_RemoveBundleDataDir_0300, HWTEST_F(BmsInstalldClientTest, BmsInstalldClientTest_RemoveModuleDataDir_0100, TestSize.Level1) { GTEST_LOG_(INFO) << "BmsInstalldClientTest_RemoveModuleDataDir_0100 start"; - std::string ModuleName = EMPTY_STRING; - int userid = USERID; - ErrCode result = installClient_->RemoveModuleDataDir(ModuleName, userid); + ErrCode result = installClient_->RemoveModuleDataDir(EMPTY_STRING, USERID); EXPECT_EQ(result, ERR_APPEXECFWK_INSTALLD_PARAM_ERROR); GTEST_LOG_(INFO) << "BmsInstalldClientTest_RemoveModuleDataDir_0100 end"; } @@ -513,9 +516,8 @@ HWTEST_F(BmsInstalldClientTest, BmsInstalldClientTest_RemoveModuleDataDir_0100, HWTEST_F(BmsInstalldClientTest, BmsInstalldClientTest_RemoveModuleDataDir_0200, TestSize.Level1) { GTEST_LOG_(INFO) << "BmsInstalldClientTest_RemoveModuleDataDir_0200 start"; - std::string ModuleName = MODULE_NAME; int userid = -1; - ErrCode result = installClient_->RemoveModuleDataDir(ModuleName, userid); + ErrCode result = installClient_->RemoveModuleDataDir(MODULE_NAME, userid); EXPECT_EQ(result, ERR_APPEXECFWK_INSTALLD_PARAM_ERROR); GTEST_LOG_(INFO) << "BmsInstalldClientTest_RemoveModuleDataDir_0200 end"; } @@ -528,10 +530,8 @@ HWTEST_F(BmsInstalldClientTest, BmsInstalldClientTest_RemoveModuleDataDir_0200, HWTEST_F(BmsInstalldClientTest, BmsInstalldClientTest_RemoveModuleDataDir_0300, TestSize.Level1) { GTEST_LOG_(INFO) << "BmsInstalldClientTest_RemoveModuleDataDir_0300 start"; - std::string ModuleName = MODULE_NAME; - int userid = USERID; - ErrCode result = installClient_->RemoveModuleDataDir(ModuleName, userid); - EXPECT_EQ(result, installClient_->CallService(&IInstalld::RemoveModuleDataDir, ModuleName, userid)); + ErrCode result = installClient_->RemoveModuleDataDir(MODULE_NAME, USERID); + EXPECT_EQ(result, installClient_->CallService(&IInstalld::RemoveModuleDataDir, MODULE_NAME, USERID)); GTEST_LOG_(INFO) << "BmsInstalldClientTest_RemoveModuleDataDir_0300 end"; } @@ -1744,5 +1744,123 @@ HWTEST_F(BmsInstalldClientTest, BmsInstalld_LoadInstalls0001, TestSize.Level0) auto result = installClient_->LoadInstalls(); EXPECT_EQ(result, ERR_APPEXECFWK_INSTALLD_GET_PROXY_ERROR); } + +/** + * @tc.number: BmsInstalldClientTest_ClearDir_0100 + * @tc.name: ClearDir_0100 + * @tc.desc: ClearDir success testcase + */ +HWTEST_F(BmsInstalldClientTest, ClearDir_0100, TestSize.Level0) +{ + uid_t uid = getuid(); + setuid(Constants::FOUNDATION_UID); + + (void)InstalldClient::GetInstance()->RemoveDir(TMP_DIR); + // create dir + int32_t ret = mkdir(TMP_DIR.c_str(), 0777); + EXPECT_EQ(ret, 0); + // create file + std::string tmpFile = TMP_DIR + "test.txt"; + std::ofstream ofs(tmpFile); + if (ofs.is_open()) { + ofs << "test" << std::endl; + ofs.close(); + } else { + EXPECT_TRUE(false); + } + // expect file exist + struct stat st; + ret = stat(tmpFile.c_str(), &st); + EXPECT_EQ(ret, 0); + // clear dir + ErrCode clearRet = InstalldClient::GetInstance()->ClearDir(TMP_DIR); + EXPECT_EQ(clearRet, 0); + + // expect file not exist + ret = stat(tmpFile.c_str(), &st); + EXPECT_NE(ret, 0); + // expect dir exist + bool isDirExist = stat(TMP_DIR.c_str(), &st) == 0 && S_ISDIR(st.st_mode); + EXPECT_TRUE(isDirExist); + + (void)InstalldClient::GetInstance()->RemoveDir(TMP_DIR); + setuid(uid); +} + +/** + * @tc.number: BmsInstalldClientTest_ClearDir_0200 + * @tc.name: ClearDir_0200 + * @tc.desc: ClearDir failed testcase, permission denied + */ +HWTEST_F(BmsInstalldClientTest, ClearDir_0200, TestSize.Level0) +{ + ErrCode ret = InstalldClient::GetInstance()->ClearDir(TMP_DIR); + EXPECT_EQ(ret, ERR_APPEXECFWK_INSTALLD_PERMISSION_DENIED); +} + +/** + * @tc.number: BmsInstalldClientTest_ClearDir_0300 + * @tc.name: ClearDir_0300 + * @tc.desc: ClearDir failed testcase, empty dir + */ +HWTEST_F(BmsInstalldClientTest, ClearDir_0300, TestSize.Level0) +{ + uid_t uid = getuid(); + setuid(Constants::FOUNDATION_UID); + + std::string emptyDir; + ErrCode ret = InstalldClient::GetInstance()->ClearDir(emptyDir); + EXPECT_EQ(ret, ERR_APPEXECFWK_INSTALLD_PARAM_ERROR); + + setuid(uid); +} + +/** + * @tc.number: BmsInstalldClientTest_ClearDir_0400 + * @tc.name: ClearDir_0400 + * @tc.desc: ClearDir failed testcase, not exit dir + */ +HWTEST_F(BmsInstalldClientTest, ClearDir_0400, TestSize.Level0) +{ + uid_t uid = getuid(); + setuid(Constants::FOUNDATION_UID); + + std::string notExistDir = "/bms/not/exist/dir"; + ErrCode ret = InstalldClient::GetInstance()->ClearDir(notExistDir); + EXPECT_EQ(ret, ERR_APPEXECFWK_INSTALLD_CLEAN_DIR_FAILED); + + setuid(uid); +} + +/** + * @tc.number: BmsInstalldClientTest_ClearDir_0500 + * @tc.name: ClearDir_0500 + * @tc.desc: ClearDir failed testcase, not dir + */ +HWTEST_F(BmsInstalldClientTest, ClearDir_0500, TestSize.Level0) +{ + uid_t uid = getuid(); + setuid(Constants::FOUNDATION_UID); + + // create file + std::string tmpFile = "/data/app/el1/bundle/public/bms-test-file.txt"; + std::ofstream ofs(tmpFile); + if (ofs.is_open()) { + ofs << "test" << std::endl; + ofs.close(); + } else { + EXPECT_TRUE(false); + } + // expect file exist + struct stat st; + int32_t ret = stat(tmpFile.c_str(), &st); + EXPECT_EQ(ret, 0); + // clear dir + ErrCode clearRet = InstalldClient::GetInstance()->ClearDir(tmpFile); + EXPECT_EQ(clearRet, ERR_APPEXECFWK_INSTALLD_CLEAN_DIR_FAILED); + + (void)std::remove(tmpFile.c_str()); + setuid(uid); +} } // namespace AppExecFwk } // namespace OHOS