From 33138de3f7835904b7ebf753343e7b2009ac6bd4 Mon Sep 17 00:00:00 2001 From: lanhaoyu Date: Fri, 25 Apr 2025 09:13:32 +0800 Subject: [PATCH] add general C++ Signed-off-by: lanhaoyu --- packing_tool/frameworks/BUILD.gn | 1 + packing_tool/frameworks/include/constants.h | 27 +- .../frameworks/include/general_normalize.h | 54 ++ .../frameworks/include/json/module_json.h | 40 +- .../frameworks/include/json/pack_info.h | 13 +- .../frameworks/include/json/pt_json.h | 3 + packing_tool/frameworks/include/utils.h | 7 +- .../frameworks/src/general_normalize.cpp | 747 ++++++++++++++++++ .../frameworks/src/json/module_json.cpp | 248 +++++- .../frameworks/src/json/module_json_fa.cpp | 215 ++++- .../frameworks/src/json/module_json_stage.cpp | 192 ++++- .../frameworks/src/json/pack_info.cpp | 326 +++++++- packing_tool/frameworks/src/json/pt_json.cpp | 49 ++ packing_tool/frameworks/src/shell_command.cpp | 7 +- packing_tool/frameworks/src/utils.cpp | 53 +- .../test/unittest/shell_command_test/BUILD.gn | 1 + 16 files changed, 1971 insertions(+), 12 deletions(-) create mode 100644 packing_tool/frameworks/include/general_normalize.h create mode 100644 packing_tool/frameworks/src/general_normalize.cpp diff --git a/packing_tool/frameworks/BUILD.gn b/packing_tool/frameworks/BUILD.gn index acfc1298..0094eb89 100644 --- a/packing_tool/frameworks/BUILD.gn +++ b/packing_tool/frameworks/BUILD.gn @@ -44,6 +44,7 @@ ohos_executable("ohos_packing_tool") { "src/app_packager.cpp", "src/appqf_packager.cpp", "src/fast_app_packager.cpp", + "src/general_normalize.cpp", "src/hap_packager.cpp", "src/hqf_packager.cpp", "src/hqf_verify.cpp", diff --git a/packing_tool/frameworks/include/constants.h b/packing_tool/frameworks/include/constants.h index 2654eecb..b1eac9a6 100644 --- a/packing_tool/frameworks/include/constants.h +++ b/packing_tool/frameworks/include/constants.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 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 @@ -34,6 +34,7 @@ const std::string MODE_APPQF = "appqf"; const std::string MODE_MULTIAPP = "multiApp"; const std::string MODE_VERSION_NORMALIZE = "versionNormalize"; const std::string MODE_PACKAGE_NORMALIZE = "packageNormalize"; +const std::string MODE_GENERAL_NORMALIZE = "generalNormalize"; const std::string MODE_FAST_APP = "fastApp"; const std::string MODE_RES = "res"; const std::string COMPRESSOR_TEMP_DIR = "temp"; @@ -42,6 +43,7 @@ const std::string COMPRESSOR_FAST_APP_TEMP_DIR = "fastApp_"; const std::string COMPRESSOR_MULTIAPP_TEMP_DIR = "multiApp_"; const std::string COMPRESSOR_PACKAGENORMALIZE_TEMP_DIR = "packageNormalize_"; const std::string COMPRESSOR_VERSIONNORMALIZE_TEMP_DIR = "versionNormalize_"; +const std::string COMPRESSOR_GENERALNORMALIZE_TEMP_DIR = "generalNormalize_"; const std::string PARAM_PREFIX = "--"; const std::string PARAM_MODE = "mode"; const std::string PARAM_JSON_PATH = "json-path"; @@ -85,6 +87,15 @@ const std::string PARAM_HQF_LIST = "hqf-list"; const std::string PARAM_INPUT_LIST = "input-list"; const std::string PARAM_VERSION_CODE = "version-code"; const std::string PARAM_VERSION_NAME = "version-name"; +const std::string PARAM_DEVICE_TYPES = "device-types"; +const std::string PARAM_MIN_COMPATIBLE_VERSION_CODE = "min-compatible-version-code"; +const std::string PARAM_MIN_API_VERSION = "min-api-version"; +const std::string PARAM_COMPILE_SDK_TYPE = "compile-sdk-type"; +const std::string PARAM_TARGET_API_VERSION = "target-api-version"; +const std::string PARAM_API_RELEASE_TYPE = "api-release-type"; +const std::string PARAM_BUNDLE_TYPE = "bundle-type"; +const std::string PARAM_INSTALLATION_FREE = "installation-free"; +const std::string PARAM_DELIVERY_WITH_INSTALL = "delivery-with-install"; const std::string PARAM_APP_PATH = "app-path"; const std::string PARAM_RPCID = "rpcid"; const std::string PARAM_APPQF_PATH = "appqf-path"; @@ -129,9 +140,12 @@ const std::string NULL_DIR_NAME = ""; const std::string DEVICE_TYPE_FITNESSWATCH = "fitnessWatch"; const std::string DEVICE_TYPE_FITNESSWATCH_NEW = "liteWearable"; const std::string VERSION_RECORD = "version_record.json"; +const std::string GENERAL_RECORD = "general_record.json"; const std::string VERSION_NAME_PATTERN = "^[0-9.]+|(?=.*[{])(?=.*[}])[0-9a-zA-Z_.{}]+$"; const std::string BUNDLE_NAME_PATTERN = "([a-zA-Z]|[a-zA-Z]+(_*[0-9a-zA-Z])+)(\\.[0-9a-zA-Z]|\\.[0-9a-zA-Z]+(_*[0-9a-zA-Z])+){2,}"; +const std::string API_RELEASE_TYPE_PATTERN = "^(Canary[1-9]\\d*)|(Beta[1-9]\\d*)|(Release[1-9]\\d*)$"; +const std::vector BUNDLE_TYPE_LIST = {"app", "appService", "atomicService", "shared", "appPlugin"}; const std::string JSON_SUFFIX = ".json"; const std::string HAP_SUFFIX = ".hap"; @@ -152,6 +166,8 @@ const int32_t BUNDLE_NAME_LEN_MIN = 7; const int32_t BUNDLE_NAME_LEN_MAX = 128; const int32_t APP_SUFFIX_LENGTH = 4; const char COMMA_SPLIT = ','; +const int32_t MAX_VERSION_NAME_LENGTH = 127; +const int32_t MAX_VERSION_CODE = 2147483647; constexpr const char* SHORT_OPTIONS = ""; const struct option LONG_OPTIONS[] = { @@ -199,6 +215,15 @@ const struct option LONG_OPTIONS[] = { {PARAM_ENTRYCARD_PATH.c_str(), required_argument, nullptr, 43}, {PARAM_BUNDLE_NAME.c_str(), required_argument, nullptr, 44}, {PARAM_TOTAL_LIMIT.c_str(), required_argument, nullptr, 45}, + {PARAM_DEVICE_TYPES.c_str(), required_argument, nullptr, 46}, + {PARAM_MIN_COMPATIBLE_VERSION_CODE.c_str(), required_argument, nullptr, 47}, + {PARAM_MIN_API_VERSION.c_str(), required_argument, nullptr, 48}, + {PARAM_COMPILE_SDK_TYPE.c_str(), required_argument, nullptr, 49}, + {PARAM_TARGET_API_VERSION.c_str(), required_argument, nullptr, 50}, + {PARAM_API_RELEASE_TYPE.c_str(), required_argument, nullptr, 51}, + {PARAM_BUNDLE_TYPE.c_str(), required_argument, nullptr, 52}, + {PARAM_INSTALLATION_FREE.c_str(), required_argument, nullptr, 53}, + {PARAM_DELIVERY_WITH_INSTALL.c_str(), required_argument, nullptr, 54}, {nullptr, 0, nullptr, 0}, }; constexpr const int32_t OPTIONS_SIZE = sizeof(LONG_OPTIONS) / sizeof(LONG_OPTIONS[0]); diff --git a/packing_tool/frameworks/include/general_normalize.h b/packing_tool/frameworks/include/general_normalize.h new file mode 100644 index 00000000..971e2ac8 --- /dev/null +++ b/packing_tool/frameworks/include/general_normalize.h @@ -0,0 +1,54 @@ +/* + * 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 DEVELOPTOOLS_PACKING_TOOL_APT_FRAMEWORKS_INCLUDE_GENERAL_NORMALIZE_H +#define DEVELOPTOOLS_PACKING_TOOL_APT_FRAMEWORKS_INCLUDE_GENERAL_NORMALIZE_H + +#include "json/module_json.h" +#include "packager.h" +#include "unzip_wrapper.h" +#include "zip_wrapper.h" + +namespace OHOS { +namespace AppPackingTool { + +class GeneralNormalize : public Packager { +public: + GeneralNormalize(const std::map ¶meterMap, std::string &resultReceiver); + ~GeneralNormalize() override {} + +protected: + int32_t InitAllowedParam() override; + int32_t PreProcess() override; + int32_t Process() override; + int32_t PostProcess() override; + +private: + bool ModifyModuleJson(const std::string &moduleJsonPath, std::map &modifyMap, + std::string &bundleName, std::string &moduleName); + bool ModifyConfigJson(const std::string &moduleJsonPath, std::map &modifyMap, + std::string &bundleName, std::string &moduleName); + bool ModifyPackInfo(const std::string &packInfoPath); + bool ProcessJsonFiles(const std::string &tempPath, std::list> &modifyMapList, + std::string &bundleName, std::string &moduleName); + bool CompressDirToHap(const std::string &tempDir, const std::string &modifiedHapPath); + std::string ConvertMapListToString(const std::list>& modifyMapList); + ZipWrapper zipWrapper_; + UnzipWrapper unzipWrapper_; + std::list hspOrhapList_; +}; +} // namespace AppExecFwk +} // namespace OHOS +#endif // DEVELOPTOOLS_PACKING_TOOL_APT_FRAMEWORKS_INCLUDE_GENERAL_NORMALIZE_H \ No newline at end of file diff --git a/packing_tool/frameworks/include/json/module_json.h b/packing_tool/frameworks/include/json/module_json.h index ed158cf2..ab20207c 100644 --- a/packing_tool/frameworks/include/json/module_json.h +++ b/packing_tool/frameworks/include/json/module_json.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 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 @@ -52,6 +52,27 @@ public: bool GetApiVersionObject(std::unique_ptr& apiVersionObj); // stage funcs, module.json + bool SetStageBundleName(const std::string& bundleName); + bool SetStageMinCompatibleVersionCode(const int32_t& minCompatibleVersionCode); + bool SetStageMinAPIVersion(const int32_t& minAPIVersion); + bool SetStageTargetAPIVersion(const int32_t& targetAPIVersion); + bool SetStageApiReleaseType(const std::string& apiReleaseType); + bool SetStageBundleType(const std::string& bundleType); + bool SetStageInstallationFree(const bool& installationFree); + bool SetStageDeliveryWithInstall(const bool& deliveryWithInstall); + bool SetStageDeviceTypes(const std::list& deviceType); + + // fa funcs, module.json + bool SetFaBundleName(const std::string& bundleName); + bool SetFaMinCompatibleVersionCode(const int32_t& minCompatibleVersionCode); + bool SetFaMinAPIVersion(const int32_t& minAPIVersion); + bool SetFaTargetAPIVersion(const int32_t& targetAPIVersion); + bool SetFaApiReleaseType(const std::string& apiReleaseType); + bool SetFaBundleType(const std::string& bundleType); + bool SetFaInstallationFree(const bool& installationFree); + bool SetFaDeliveryWithInstall(const bool& deliveryWithInstall); + bool SetFaDeviceTypes(const std::list& deviceType); + bool GetStageVersion(Version& version); bool GetStageVersionByAppObj(std::unique_ptr& appObj, Version& version); bool SetStageVersionCode(const int32_t& versionCode); @@ -141,6 +162,7 @@ public: bool GetFaAsanEnabledByAppObj(std::unique_ptr& appObj, bool& asanEnabled); bool GetFaReleaseType(std::string& releaseType); bool GetFaReleaseTypeByAppObj(std::unique_ptr& appObj, std::string& releaseType); + bool GetFaDeliveryWithInstall(bool& deliveryWithInstall); // common funcs bool GetBundleName(std::string& bundleName); @@ -158,6 +180,7 @@ public: bool GetTargetPriorityByAppObj(std::unique_ptr& appObj, int32_t& targetPriority); bool GetTargetModulePriority(int32_t& targetModulePriority); bool GetTargetModulePriorityByModuleObj(std::unique_ptr& moduleObj, int32_t& targetModulePriority); + // config.json or module.json bool GetAbilityNames(std::list& abilityNames); bool GetAbilityNamesByModuleObj(std::unique_ptr& moduleObj, std::list& abilityNames); @@ -177,6 +200,9 @@ public: bool GetMultiAppMode(MultiAppMode& multiAppMode); bool GetMultiAppModeByAppObj(std::unique_ptr& appObj, MultiAppMode& multiAppMode); + bool GetMinApiVersion(int32_t& minAPIVersion); + bool GetTargetApiVersion(int32_t& targetAPIVersion); + bool GetDeliveryWithInstall(bool& deliveryWithInstall); bool IsModuleAtomicServiceValid(); bool CheckEntryInAtomicService(); @@ -198,6 +224,18 @@ public: // json function for hqf bool GetPatchModuleName(std::string& patchModuleName); + bool SetBundleName(const std::string& bundleName, const bool& isStage); + bool SetMinCompatibleVersionCode(const int32_t& minCompatibleVersionCode, const bool& isStage); + bool SetMinAPIVersion(const int32_t& minAPIVersion, const bool& isStage); + bool SetTargetAPIVersion(const int32_t& targetAPIVersion, const bool& isStage); + bool SetApiReleaseType(const std::string& apiReleaseType, const bool& isStage); + bool SetBundleType(const std::string& bundleType, const bool& isStage); + bool SetInstallationFree(const bool& installationFree, const bool& isStage); + bool SetDeliveryWithInstall(const bool& deliveryWithInstall, const bool& isStage); + bool SetVersionCode(const int32_t& versionCode, const bool& isStage); + bool SetVersionName(const std::string& versionName, const bool& isStage); + bool SetDeviceTypes(const std::list& deviceTypes, const bool& isStage); + protected: bool CheckStageBundleType(const std::string& moduleName, const std::string& moduleType, const std::string& bundleType, const bool& installationFree); diff --git a/packing_tool/frameworks/include/json/pack_info.h b/packing_tool/frameworks/include/json/pack_info.h index 2c6380cc..35c61d93 100644 --- a/packing_tool/frameworks/include/json/pack_info.h +++ b/packing_tool/frameworks/include/json/pack_info.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 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 @@ -51,6 +51,8 @@ public: int32_t moduleIndex, std::unique_ptr& distroObj); bool GetDistroObjectByModuleObj(const std::unique_ptr& moduleObj, std::unique_ptr& distroObj); + bool GetApiVersionObjectByModuleObj(const std::unique_ptr& moduleObj, + std::unique_ptr& distroObj); bool GetPackageObject(int32_t packageIndex, std::unique_ptr& packageObj); bool GetExtensionAbilitiesObj(int32_t moduleIndex, std::unique_ptr& extensionAbilitiesObj); bool GetExtensionAbilitiesObjByModulesObj(const std::unique_ptr& modulesObj, @@ -85,6 +87,15 @@ public: bool GetPackageNames(std::list &packageNames); bool GetPackageNamesByPackagesObj(const std::unique_ptr& appObj, std::list &packageNames); + bool SetMinCompatibleVersionCode(const int32_t& minCompatibleVersionCode); + bool SetMinAPIVersion(const int32_t& minAPIVersion); + bool SetTargetAPIVersion(const int32_t& targetAPIVersion); + bool SetApiReleaseType(const std::string& apiReleaseType); + bool SetBundleType(const std::string& bundleType); + bool SetInstallationFree(const bool& installationFree); + bool SetDeliveryWithInstall(const bool& deliveryWithInstall); + bool SetDeviceTypes(const std::list& deviceTypes); + private: std::unique_ptr root_ = nullptr; }; diff --git a/packing_tool/frameworks/include/json/pt_json.h b/packing_tool/frameworks/include/json/pt_json.h index 05aa12b7..1c6c8e6c 100644 --- a/packing_tool/frameworks/include/json/pt_json.h +++ b/packing_tool/frameworks/include/json/pt_json.h @@ -16,6 +16,7 @@ #ifndef DEVELOPTOOLS_PACKING_TOOL_APT_FRAMEWORKS_INCLUDE_JSON_PT_JSON_H #define DEVELOPTOOLS_PACKING_TOOL_APT_FRAMEWORKS_INCLUDE_JSON_PT_JSON_H +#include #include #include @@ -56,6 +57,7 @@ public: bool Add(const char *key, double value) const; bool Add(const char *key, const char *value) const; bool Add(const char *key, const std::unique_ptr &value) const; + bool Add(const char *key, const std::list& values) const; // Push back to array bool Push(bool value) const; @@ -116,6 +118,7 @@ public: Result SetUInt64(const char *key, const uint64_t& value); Result SetDouble(const char *key, const double& value); Result SetString(const char *key, const std::string& value); + Result SetArray(const char *key, const std::list& value); private: cJSON *object_ = nullptr; diff --git a/packing_tool/frameworks/include/utils.h b/packing_tool/frameworks/include/utils.h index 7b610a2c..33ef76ce 100644 --- a/packing_tool/frameworks/include/utils.h +++ b/packing_tool/frameworks/include/utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 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 @@ -46,6 +46,8 @@ public: static bool IsPositiveInteger(const std::string& str, int min = 0, int max = INT32_MAX); static std::string ReplaceAll(std::string str, const std::string& from, const std::string& to); static bool EndsWith(const std::string& str, const std::string& suffix); + static bool StringToBool(const std::string& str); + static bool StringToArray(const std::string& str, std::list& array); // Algorithm static std::string GetSha256Str(const std::string &str); @@ -71,6 +73,9 @@ public: static bool GetFormattedPath(const std::string& path, std::string& formattedPath); static bool GetRealPath(const std::string& path, std::string& realPath); static bool GetRealPathOfNoneExistFile(const std::string& path, std::string& realPath); + static bool RemoveAllFilesInDirectory(const std::string& directoryPath); + static std::string ArrayToString(const std::list &array); + static std::string BoolToString(bool value); }; } // namespace AppPackingTool } // namespace OHOS diff --git a/packing_tool/frameworks/src/general_normalize.cpp b/packing_tool/frameworks/src/general_normalize.cpp new file mode 100644 index 00000000..dee595e1 --- /dev/null +++ b/packing_tool/frameworks/src/general_normalize.cpp @@ -0,0 +1,747 @@ +/* + * 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 "general_normalize.h" + +#include "hap_packager.h" +#include "hqf_packager.h" +#include "hsp_packager.h" +#include "json/json_utils.h" +#include "json/module_json.h" +#include "json/normalize_version_utils.h" +#include "json/pack_info.h" +#include "log.h" +#include "utils.h" +#include "zip_utils.h" + +namespace OHOS { +namespace AppPackingTool { +namespace { +const std::string BUNDLE_TYPE = "bundleType"; +const std::string BUNDLE_NAME = "bundleName"; +const std::string VERSION_CODE = "versionCode"; +const std::string VERSION_NAME = "versionName"; +const std::string MIN_COMPATIBLE_VERSION_CODE = "minCompatibleVersionCode"; +const std::string MIN_API_VERSION = "minAPIVersion"; +const std::string TARGET_API_VERSION = "targetAPIVersion"; +const std::string API_RELEASE_TYPE = "apiReleaseType"; +const std::string DEVICE_TYPES = "deviceTypes"; +const std::string INSTALLATION_FREE = "installationFree"; +const std::string DELIVERY_WITH_INSTALL = "deliveryWithInstall"; +const std::string MODULE_NAME = "moduleName"; +const std::vector DEVICE_TYPE_LIST = {"default", "tablet", "tv", "wearable", "car", "2in1"}; +} +GeneralNormalize::GeneralNormalize(const std::map ¶meterMap, std::string &resultReceiver) + : Packager(parameterMap, resultReceiver) +{} + +int32_t GeneralNormalize::InitAllowedParam() +{ + allowedParameters_ = { + {} + }; + return ERR_OK; +} + +int32_t GeneralNormalize::PreProcess() +{ + auto it = parameterMap_.find(Constants::PARAM_INPUT_LIST); + if (it == parameterMap_.end()) { + LOGE("Input input-list is empty."); + return ERR_INVALID_VALUE; + } + if (!CompatibleProcess(it->second, hspOrhapList_, Constants::HAP_SUFFIX, Constants::HSP_SUFFIX)) { + LOGE("Input input-list is invalid."); + return ERR_INVALID_VALUE; + } + if (hspOrhapList_.size() == 0) { + LOGE("Input input-list is empty."); + return ERR_INVALID_VALUE; + } + + it = parameterMap_.find(Constants::PARAM_VERSION_NAME); + std::regex pattern(Constants::VERSION_NAME_PATTERN); + if (it != parameterMap_.end()) { + if (!std::regex_match(it->second, pattern) || it->second.size() > Constants::MAX_VERSION_NAME_LENGTH) { + LOGE("Input version-name is not valid."); + return ERR_INVALID_VALUE; + } + } + + it = parameterMap_.find(Constants::PARAM_VERSION_CODE); + if (it != parameterMap_.end()) { + if (!Utils::IsPositiveInteger(it->second) || stoi(it->second)> Constants::MAX_VERSION_CODE) { + LOGE("Input version-code is invalid."); + return ERR_INVALID_VALUE; + } + } + + it = parameterMap_.find(Constants::PARAM_DEVICE_TYPES); + if (it != parameterMap_.end()) { + std::list deviceTypeList; + if (!Utils::StringToArray(it->second, deviceTypeList)) { + LOGE("Input device-type is invalid."); + return ERR_INVALID_VALUE; + } + for (auto& item : deviceTypeList) { + if ((std::find(DEVICE_TYPE_LIST.begin(), DEVICE_TYPE_LIST.end(), item) == DEVICE_TYPE_LIST.end())) { + LOGE("Input device-type is invalid."); + return ERR_INVALID_VALUE; + } + } + } + + it = parameterMap_.find(Constants::PARAM_BUNDLE_NAME); + std::regex bundleNamePattern(Constants::BUNDLE_NAME_PATTERN); + if (it != parameterMap_.end()) { + if (!std::regex_match(it->second, bundleNamePattern) || it->second.length() < Constants::BUNDLE_NAME_LEN_MIN || + it->second.length() > Constants::BUNDLE_NAME_LEN_MAX) { + LOGE("Input bundle-name is invalid."); + return ERR_INVALID_VALUE; + } + } + + it = parameterMap_.find(Constants::PARAM_MIN_COMPATIBLE_VERSION_CODE); + if (it != parameterMap_.end()) { + if (!Utils::IsPositiveInteger(it->second) || stoi(it->second) > Constants::MAX_VERSION_CODE) { + LOGE("Input min-compatible-version-code is invalid."); + return ERR_INVALID_VALUE; + } + } + + it = parameterMap_.find(Constants::PARAM_MIN_API_VERSION); + if (it != parameterMap_.end()) { + if (!Utils::IsPositiveInteger(it->second) || stoi(it->second) > Constants::MAX_VERSION_CODE) { + LOGE("Input min-api-version is invalid."); + return ERR_INVALID_VALUE; + } + } + + it = parameterMap_.find(Constants::PARAM_TARGET_API_VERSION); + if (it != parameterMap_.end()) { + if (!Utils::IsPositiveInteger(it->second) || stoi(it->second) > Constants::MAX_VERSION_CODE) { + LOGE("Input target-api-version is invalid."); + return ERR_INVALID_VALUE; + } + } + + it = parameterMap_.find(Constants::PARAM_API_RELEASE_TYPE); + std::regex releaseTypePattern(Constants::API_RELEASE_TYPE_PATTERN); + if (it != parameterMap_.end()) { + if (!std::regex_match(it->second, releaseTypePattern)) { + LOGE("Input api-release-type is invalid."); + return ERR_INVALID_VALUE; + } + } + + it = parameterMap_.find(Constants::PARAM_BUNDLE_TYPE); + if (it != parameterMap_.end()) { + if ((std::find(Constants::BUNDLE_TYPE_LIST.begin(), Constants::BUNDLE_TYPE_LIST.end(), it->second) == + Constants::BUNDLE_TYPE_LIST.end())) { + LOGE("Input bundle-type is invalid."); + return ERR_INVALID_VALUE; + } + } + + it = parameterMap_.find(Constants::PARAM_INSTALLATION_FREE); + if (it != parameterMap_.end()) { + if (it->second != "true" && it->second != "false") { + LOGE("Input installation-free is invalid."); + return ERR_INVALID_VALUE; + } + } + + it = parameterMap_.find(Constants::PARAM_DELIVERY_WITH_INSTALL); + if (it != parameterMap_.end()) { + if (it->second != "true" && it->second != "false") { + LOGE("Input delivery-with-install is invalid."); + return ERR_INVALID_VALUE; + } + } + + if (!IsOutDirectoryValid()) { + return ERR_INVALID_VALUE; + } + return ERR_OK; +} + +bool GeneralNormalize::ModifyModuleJson(const std::string &moduleJsonPath, + std::map &modifyMap, std::string &bundleName, std::string &moduleName) +{ + ModuleJson moduleJson; + if (!moduleJson.ParseFromFile(moduleJsonPath)) { + LOGE("Parse and modify module.json failed, parse module.json is null."); + return false; + } + auto it = parameterMap_.find(Constants::PARAM_VERSION_CODE); + if (it != parameterMap_.end()) { + int32_t versionCode = std::stoi(parameterMap_.at(Constants::PARAM_VERSION_CODE)); + Version version; + moduleJson.GetStageVersion(version); + modifyMap[VERSION_CODE] = std::to_string(version.versionCode); + if (!moduleJson.SetVersionCode(versionCode, true)) { + LOGE("SetVersionCode failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_VERSION_NAME); + if (it != parameterMap_.end()) { + std::string versionName = parameterMap_.at(Constants::PARAM_VERSION_NAME); + Version version; + moduleJson.GetStageVersion(version); + modifyMap[VERSION_NAME] = version.versionName; + if (!moduleJson.SetVersionName(versionName, true)) { + LOGE("SetVersionName failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_BUNDLE_NAME); + if (it != parameterMap_.end()) { + std::string targetBundleName = parameterMap_.at(Constants::PARAM_BUNDLE_NAME); + std::string originBundleName; + moduleJson.GetBundleName(originBundleName); + modifyMap[BUNDLE_NAME] = originBundleName; + if (!moduleJson.SetBundleName(targetBundleName, true)) { + LOGE("SetBundleName failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_MIN_COMPATIBLE_VERSION_CODE); + if (it != parameterMap_.end()) { + Version version; + moduleJson.GetStageVersion(version); + modifyMap[MIN_COMPATIBLE_VERSION_CODE] = std::to_string(version.minCompatibleVersionCode); + int32_t minCompatibleVersionCode = std::stoi(parameterMap_.at(Constants::PARAM_MIN_COMPATIBLE_VERSION_CODE)); + if (!moduleJson.SetMinCompatibleVersionCode(minCompatibleVersionCode, true)) { + LOGE("SetMinCompatibleVersionCode failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_MIN_API_VERSION); + if (it != parameterMap_.end()) { + int32_t minAPIVersion = std::stoi(parameterMap_.at(Constants::PARAM_MIN_API_VERSION)); + int32_t originMinAPIVersion = -1; + moduleJson.GetMinApiVersion(originMinAPIVersion); + modifyMap[MIN_API_VERSION] = std::to_string(originMinAPIVersion); + if (!moduleJson.SetMinAPIVersion(minAPIVersion, true)) { + LOGE("SetMinAPIVersion failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_TARGET_API_VERSION); + if (it != parameterMap_.end()) { + int32_t targetAPIVersion = std::stoi(parameterMap_.at(Constants::PARAM_TARGET_API_VERSION)); + int32_t originTargetAPIVersion = -1; + moduleJson.GetTargetApiVersion(originTargetAPIVersion); + modifyMap[TARGET_API_VERSION] = std::to_string(originTargetAPIVersion); + if (!moduleJson.SetTargetAPIVersion(targetAPIVersion, true)) { + LOGE("SetTargetAPIVersion failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_API_RELEASE_TYPE); + if (it != parameterMap_.end()) { + std::string apiReleaseType = parameterMap_.at(Constants::PARAM_API_RELEASE_TYPE); + std::string originApiReleaseType; + moduleJson.GetStageApiReleaseType(originApiReleaseType); + modifyMap[API_RELEASE_TYPE] = originApiReleaseType; + if (!moduleJson.SetApiReleaseType(apiReleaseType, true)) { + LOGE("SetApiReleaseType failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_BUNDLE_TYPE); + if (it != parameterMap_.end()) { + std::string bundleType = parameterMap_.at(Constants::PARAM_BUNDLE_TYPE); + std::string originBundleType; + moduleJson.GetStageBundleType(originBundleType); + modifyMap[BUNDLE_TYPE] = originBundleType; + if (!moduleJson.SetBundleType(bundleType, true)) { + LOGE("SetBundleType failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_INSTALLATION_FREE); + if (it != parameterMap_.end()) { + bool installationFree = Utils::StringToBool(parameterMap_.at(Constants::PARAM_INSTALLATION_FREE)); + bool originInstallationFree; + moduleJson.GetStageInstallationFree(originInstallationFree); + modifyMap[INSTALLATION_FREE] = Utils::BoolToString(originInstallationFree); + if (!moduleJson.SetInstallationFree(installationFree, true)) { + LOGE("SetInstallationFree failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_DELIVERY_WITH_INSTALL); + if (it != parameterMap_.end()) { + bool deliveryWithInstall = Utils::StringToBool(parameterMap_.at(Constants::PARAM_DELIVERY_WITH_INSTALL)); + bool originDeliveryWithInstall; + moduleJson.GetDeliveryWithInstall(originDeliveryWithInstall); + modifyMap[DELIVERY_WITH_INSTALL] = Utils::BoolToString(originDeliveryWithInstall); + if (!moduleJson.SetDeliveryWithInstall(deliveryWithInstall, true)) { + LOGE("SetDeliveryWithInstall failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_DEVICE_TYPES); + if (it != parameterMap_.end()) { + std::list deviceTypes; + Utils::StringToArray(parameterMap_.at(Constants::PARAM_DEVICE_TYPES), deviceTypes); + std::list originDeviceTypes; + moduleJson.GetStageDeviceTypes(originDeviceTypes); + modifyMap[DEVICE_TYPES] = Utils::ArrayToString(originDeviceTypes); + if (!moduleJson.SetDeviceTypes(deviceTypes, true)) { + LOGE("SetDeviceTypes failed"); + return false; + } + } + + moduleJson.GetBundleName(bundleName); + moduleJson.GetModuleName(moduleName); + modifyMap[MODULE_NAME] = moduleName; + if (!JsonUtils::StrToFile(moduleJson.ToString(), moduleJsonPath)) { + LOGE("Parse and modify module.json failed, write Json failed."); + return false; + } + return true; +} + +bool GeneralNormalize::ModifyConfigJson(const std::string &configJsonPath, + std::map &modifyMap, std::string &bundleName, std::string &moduleName) +{ + ModuleJson configJson; + if (!configJson.ParseFromFile(configJsonPath)) { + LOGE("Parse and modify config.json failed, parse json is null."); + return false; + } + auto it = parameterMap_.find(Constants::PARAM_VERSION_CODE); + if (it != parameterMap_.end()) { + Version version; + configJson.GetFaVersion(version); + modifyMap[VERSION_CODE] = std::to_string(version.versionCode); + int32_t versionCode = std::stoi(parameterMap_.at(Constants::PARAM_VERSION_CODE)); + if (!configJson.SetVersionCode(versionCode, false)) { + LOGE("SetVersionCode failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_VERSION_NAME); + if (it != parameterMap_.end()) { + Version version; + configJson.GetFaVersion(version); + modifyMap[VERSION_NAME] = version.versionName; + std::string versionName = parameterMap_.at(Constants::PARAM_VERSION_NAME); + if (!configJson.SetVersionName(versionName, false)) { + LOGE("SetVersionName failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_BUNDLE_NAME); + if (it != parameterMap_.end()) { + std::string originBundleName; + configJson.GetBundleName(originBundleName); + modifyMap[BUNDLE_NAME] = originBundleName; + std::string targetBundleName = parameterMap_.at(Constants::PARAM_BUNDLE_NAME); + if (!configJson.SetBundleName(targetBundleName, false)) { + LOGE("SetBundleName failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_MIN_COMPATIBLE_VERSION_CODE); + if (it != parameterMap_.end()) { + Version version; + configJson.GetFaVersion(version); + modifyMap[MIN_COMPATIBLE_VERSION_CODE] = std::to_string(version.minCompatibleVersionCode); + int32_t minCompatibleVersionCode = std::stoi(parameterMap_.at(Constants::PARAM_MIN_COMPATIBLE_VERSION_CODE)); + if (!configJson.SetMinCompatibleVersionCode(minCompatibleVersionCode, false)) { + LOGE("SetMinCompatibleVersionCode failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_MIN_API_VERSION); + if (it != parameterMap_.end()) { + ModuleApiVersion moduleApiVersion; + configJson.GetFaModuleApiVersion(moduleApiVersion); + modifyMap[MIN_API_VERSION] = std::to_string(moduleApiVersion.compatibleApiVersion); + int32_t minAPIVersion = std::stoi(parameterMap_.at(Constants::PARAM_MIN_API_VERSION)); + if (!configJson.SetMinAPIVersion(minAPIVersion, false)) { + LOGE("SetMinAPIVersion failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_TARGET_API_VERSION); + if (it != parameterMap_.end()) { + ModuleApiVersion moduleApiVersion; + configJson.GetFaModuleApiVersion(moduleApiVersion); + modifyMap[TARGET_API_VERSION] = std::to_string(moduleApiVersion.targetApiVersion); + int32_t targetAPIVersion = std::stoi(parameterMap_.at(Constants::PARAM_TARGET_API_VERSION)); + if (!configJson.SetTargetAPIVersion(targetAPIVersion, false)) { + LOGE("SetTargetAPIVersion failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_API_RELEASE_TYPE); + if (it != parameterMap_.end()) { + ModuleApiVersion moduleApiVersion; + configJson.GetFaModuleApiVersion(moduleApiVersion); + modifyMap[API_RELEASE_TYPE] = moduleApiVersion.releaseType; + std::string apiReleaseType = parameterMap_.at(Constants::PARAM_API_RELEASE_TYPE); + if (!configJson.SetApiReleaseType(apiReleaseType, false)) { + LOGE("SetApiReleaseType failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_BUNDLE_TYPE); + if (it != parameterMap_.end()) { + std::string originBundleType; + configJson.GetFaBundleType(originBundleType); + modifyMap[BUNDLE_TYPE] = originBundleType; + std::string bundleType = parameterMap_.at(Constants::PARAM_BUNDLE_TYPE); + if (!configJson.SetBundleType(bundleType, false)) { + LOGE("SetBundleType failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_INSTALLATION_FREE); + if (it != parameterMap_.end()) { + bool originInstallationFree; + configJson.GetFaInstallationFree(originInstallationFree); + modifyMap[INSTALLATION_FREE] = Utils::BoolToString(originInstallationFree); + bool installationFree = Utils::StringToBool(parameterMap_.at(Constants::PARAM_INSTALLATION_FREE)); + if (!configJson.SetInstallationFree(installationFree, false)) { + LOGE("SetInstallationFree failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_DELIVERY_WITH_INSTALL); + if (it != parameterMap_.end()) { + bool originDeliveryWithInstall; + configJson.GetFaDeliveryWithInstall(originDeliveryWithInstall); + modifyMap[DELIVERY_WITH_INSTALL] = Utils::BoolToString(originDeliveryWithInstall); + bool deliveryWithInstall = Utils::StringToBool(parameterMap_.at(Constants::PARAM_DELIVERY_WITH_INSTALL)); + if (!configJson.SetDeliveryWithInstall(deliveryWithInstall, false)) { + LOGE("SetDeliveryWithInstall failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_DEVICE_TYPES); + if (it != parameterMap_.end()) { + std::list originDeviceTypes; + configJson.GetFaDeviceTypes(originDeviceTypes); + modifyMap[DEVICE_TYPES] = Utils::ArrayToString(originDeviceTypes); + std::list deviceTypes; + Utils::StringToArray(parameterMap_.at(Constants::PARAM_DEVICE_TYPES), deviceTypes); + if (!configJson.SetDeviceTypes(deviceTypes, false)) { + LOGE("SetDeviceTypes failed"); + return false; + } + } + + configJson.GetBundleName(bundleName); + configJson.GetFaModuleName(moduleName); + modifyMap[MODULE_NAME] = moduleName; + if (!JsonUtils::StrToFile(configJson.ToString(), configJsonPath)) { + LOGE("Parse and modify config.json failed, writeJson failed."); + return false; + } + return true; +} + +bool GeneralNormalize::ModifyPackInfo(const std::string &packInfoPath) +{ + PackInfo packInfo; + if (!packInfo.ParseFromFile(packInfoPath)) { + LOGW("Parse and modify packInfo failed, json format invalid."); + return false; + } + + auto it = parameterMap_.find(Constants::PARAM_VERSION_CODE); + if (it != parameterMap_.end()) { + int32_t versionCode = std::stoi(parameterMap_.at(Constants::PARAM_VERSION_CODE)); + if (!packInfo.SetVersionCode(versionCode)) { + LOGW("SetVersionCode packInfo failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_VERSION_NAME); + if (it != parameterMap_.end()) { + std::string versionName = parameterMap_.at(Constants::PARAM_VERSION_NAME); + if (!packInfo.SetVersionName(versionName)) { + LOGW("SetVersionName packInfo failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_BUNDLE_NAME); + if (it != parameterMap_.end()) { + std::string bundleName = parameterMap_.at(Constants::PARAM_BUNDLE_NAME); + if (!packInfo.SetBundleName(bundleName)) { + LOGW("SetBundleName failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_MIN_COMPATIBLE_VERSION_CODE); + if (it != parameterMap_.end()) { + int32_t minCompatibleVersionCode = std::stoi(parameterMap_.at(Constants::PARAM_MIN_COMPATIBLE_VERSION_CODE)); + if (!packInfo.SetMinCompatibleVersionCode(minCompatibleVersionCode)) { + LOGW("SetMinCompatibleVersionCode failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_MIN_API_VERSION); + if (it != parameterMap_.end()) { + int32_t minAPIVersion = std::stoi(parameterMap_.at(Constants::PARAM_MIN_API_VERSION)); + if (!packInfo.SetMinAPIVersion(minAPIVersion)) { + LOGW("SetMinAPIVersion failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_TARGET_API_VERSION); + if (it != parameterMap_.end()) { + int32_t targetAPIVersion = std::stoi(parameterMap_.at(Constants::PARAM_TARGET_API_VERSION)); + if (!packInfo.SetTargetAPIVersion(targetAPIVersion)) { + LOGW("SetTargetAPIVersion failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_API_RELEASE_TYPE); + if (it != parameterMap_.end()) { + std::string apiReleaseType = parameterMap_.at(Constants::PARAM_API_RELEASE_TYPE); + if (!packInfo.SetApiReleaseType(apiReleaseType)) { + LOGW("SetApiReleaseType failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_BUNDLE_TYPE); + if (it != parameterMap_.end()) { + std::string bundleType = parameterMap_.at(Constants::PARAM_BUNDLE_TYPE); + if (!packInfo.SetBundleType(bundleType)) { + LOGW("SetBundleType failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_INSTALLATION_FREE); + if (it != parameterMap_.end()) { + bool installationFree = Utils::StringToBool(parameterMap_.at(Constants::PARAM_INSTALLATION_FREE)); + if (!packInfo.SetInstallationFree(installationFree)) { + LOGW("SetInstallationFree failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_DELIVERY_WITH_INSTALL); + if (it != parameterMap_.end()) { + bool deliveryWithInstall = Utils::StringToBool(parameterMap_.at(Constants::PARAM_DELIVERY_WITH_INSTALL)); + if (!packInfo.SetDeliveryWithInstall(deliveryWithInstall)) { + LOGW("SetDeliveryWithInstall failed"); + return false; + } + } + + it = parameterMap_.find(Constants::PARAM_DEVICE_TYPES); + if (it != parameterMap_.end()) { + std::list deviceTypes; + Utils::StringToArray(parameterMap_.at(Constants::PARAM_DEVICE_TYPES), deviceTypes); + if (!packInfo.SetDeviceTypes(deviceTypes)) { + LOGW("SetDeviceTypes failed"); + return false; + } + } + + if (!JsonUtils::StrToFile(packInfo.ToString(), packInfoPath)) { + LOGW("Parse and modify packInfo failed, writeJson failed."); + return false; + } + return true; +} + +bool GeneralNormalize::CompressDirToHap(const std::string &sourceDir, const std::string &zipFilePath) +{ + std::map parameterMap; + std::string resultReceiver = ""; + parameterMap[Constants::PARAM_OUT_PATH] = zipFilePath; + std::unique_ptr packager = nullptr; + for (const auto& entry : fs::directory_iterator(fs::path(sourceDir))) { + std::string fileName = entry.path().filename().string(); + std::string filePath = entry.path().string(); + if (fileName == Constants::ETS_PATH) { + parameterMap[Constants::PARAM_ETS_PATH] = filePath; + } else if (fileName == Constants::HNP_PATH) { + parameterMap[Constants::PARAM_HNP_PATH] = filePath; + } else if (fileName == Constants::LIB_PATH) { + parameterMap[Constants::PARAM_LIB_PATH] = filePath; + } else if (fileName == Constants::AN_PATH) { + parameterMap[Constants::PARAM_AN_PATH] = filePath; + } else if (fileName == Constants::AP_PATH) { + parameterMap[Constants::PARAM_AP_PATH] = filePath; + } else if (fileName == Constants::RESOURCES_PATH) { + parameterMap[Constants::PARAM_RESOURCES_PATH] = filePath; + } else if (fileName == Constants::JS_PATH) { + parameterMap[Constants::PARAM_JS_PATH] = filePath; + } else if (fileName == Constants::ASSETS_PATH) { + parameterMap[Constants::PARAM_ASSETS_PATH] = filePath; + } else if (fileName == Constants::SO_DIR) { + parameterMap[Constants::PARAM_MAPLE_SO_DIR] = filePath; + } else if (fileName == Constants::SHARED_LIBS_DIR) { + parameterMap[Constants::PARAM_SHAREDLIBS_PATH] = filePath; + } else if (fileName == Constants::CONFIG_JSON) { + parameterMap[Constants::PARAM_JSON_PATH] = filePath; + } else if (fileName == Constants::MODULE_JSON) { + parameterMap[Constants::PARAM_JSON_PATH] = filePath; + } else if (fileName == Constants::RESOURCES_INDEX) { + parameterMap[Constants::PARAM_INDEX_PATH] = filePath; + } else if (fileName == Constants::PACK_INFO) { + parameterMap[Constants::PARAM_PACK_INFO_PATH] = filePath; + } else if (fileName == Constants::RPCID_SC) { + parameterMap[Constants::PARAM_RPCID_PATH] = filePath; + } + } + if (Utils::EndsWith(zipFilePath, Constants::HAP_SUFFIX)) { + packager = std::make_unique(parameterMap, resultReceiver); + } else if (Utils::EndsWith(zipFilePath, Constants::HSP_SUFFIX)) { + packager = std::make_unique(parameterMap, resultReceiver); + } + + if (packager == nullptr || packager->PreProcess() != ERR_OK || packager->Process() != ERR_OK) { + return false; + } + return true; +} + + +bool GeneralNormalize::ProcessJsonFiles(const std::string &tempPath, + std::list> &modifyMapList, std::string &bundleName, std::string &moduleName) +{ + std::map modifyMap; + std::string moduleJsonPath = tempPath + Constants::LINUX_FILE_SEPARATOR + Constants::MODULE_JSON; + std::string configJsonPath = tempPath + Constants::LINUX_FILE_SEPARATOR + Constants::CONFIG_JSON; + std::string packInfoPath = tempPath + Constants::LINUX_FILE_SEPARATOR + Constants::PACK_INFO; + + bool isModuleFileExists = fs::exists(moduleJsonPath); + bool isConfigFileExists = fs::exists(configJsonPath); + bool isPackInfoFileExists = fs::exists(packInfoPath); + if (isModuleFileExists == isConfigFileExists) { + LOGE("GeneralNormalize failed, invalid hap structure."); + return false; + } + + bool modifyJsonSuccess = false; + if (isModuleFileExists) { + modifyJsonSuccess = ModifyModuleJson(moduleJsonPath, modifyMap, bundleName, moduleName); + } else { + modifyJsonSuccess = ModifyConfigJson(configJsonPath, modifyMap, bundleName, moduleName); + } + + if (!modifyJsonSuccess) { + modifyMapList.push_back(modifyMap); + return false; + } + + if (isPackInfoFileExists) { + if (!ModifyPackInfo(packInfoPath)) { + modifyMapList.push_back(modifyMap); + return false; + } + } + modifyMapList.push_back(modifyMap); + return true; +} + +int32_t GeneralNormalize::Process() +{ + std::string outPath = parameterMap_.at(Constants::PARAM_OUT_PATH); + std::string tempPath = outPath + Constants::LINUX_FILE_SEPARATOR + Constants::COMPRESSOR_GENERALNORMALIZE_TEMP_DIR + + Utils::GenerateUUID(); + std::list> modifyMapList; + bool isSuccess = true; + std::string bundleName; + std::string moduleName; + for (const std::string& path : hspOrhapList_) { + ZipUtils::Unzip(path, tempPath); + if (!ProcessJsonFiles(tempPath, modifyMapList, bundleName, moduleName)) { + Utils::ForceRemoveDirectory(tempPath); + isSuccess = false; + break; + } + if (!CompressDirToHap(tempPath, + outPath + Constants::LINUX_FILE_SEPARATOR + fs::path(path).filename().string())) { + Utils::ForceRemoveDirectory(tempPath); + isSuccess = false; + break; + } + Utils::ForceRemoveDirectory(tempPath); + } + if (!isSuccess) { + LOGE("GeneralNormalize failed, bundleName: %s, moduleName: %s", bundleName.c_str(), moduleName.c_str()); + Utils::RemoveAllFilesInDirectory(outPath); + return ERR_INVALID_VALUE; + } + if (!JsonUtils::StrToFile(ConvertMapListToString(modifyMapList), outPath + + Constants::LINUX_FILE_SEPARATOR + Constants::GENERAL_RECORD)) { + LOGE("WriteVersionRecord failed."); + return ERR_INVALID_VALUE; + } + return ERR_OK; +} + +std::string GeneralNormalize::ConvertMapListToString(const std::list>& + modifyMapList) +{ + std::unique_ptr jArray = PtJson::CreateArray(); + for (const auto& map : modifyMapList) { + std::unique_ptr jMap = PtJson::CreateObject(); + for (const auto& pair : map) { + if (!jMap->Add(pair.first.c_str(), pair.second.c_str())) { + return ""; + } + } + jArray->Push(jMap); + } + return jArray->Stringify(); +} + +int32_t GeneralNormalize::PostProcess() +{ + return ERR_OK; +} +} // namespace AppPackingTool +} // namespace OHOS \ No newline at end of file diff --git a/packing_tool/frameworks/src/json/module_json.cpp b/packing_tool/frameworks/src/json/module_json.cpp index bc3065f2..5472375e 100644 --- a/packing_tool/frameworks/src/json/module_json.cpp +++ b/packing_tool/frameworks/src/json/module_json.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 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 @@ -36,6 +36,7 @@ const std::string API_RELEASE_TYPE = "apiReleaseType"; const std::string DEBUG = "debug"; const std::string COMPATIBLE = "compatible"; const std::string RELEASE_TYPE = "releaseType"; +const std::string DELIVERY_WITH_INSTALL = "deliveryWithInstall"; const std::string TARGET = "target"; const std::string VERSION = "version"; const std::string CODE = "code"; @@ -242,8 +243,13 @@ bool ModuleJson::GetApiVersionObject(std::unique_ptr& apiVersionObj) return false; } if (!appObj->Contains(API_VERSION.c_str())) { - LOGE("App node has no %s node!", API_VERSION.c_str()); - return false; + cJSON *apiVersion = cJSON_CreateObject(); + apiVersionObj = std::make_unique(apiVersion); + if (appObj->Add(API_VERSION.c_str(), apiVersionObj)) { + LOGE("App node add %s node failed!", API_VERSION.c_str()); + return false; + } + return true; } if (appObj->GetObject(API_VERSION.c_str(), &apiVersionObj) != Result::SUCCESS) { LOGE("App node get %s node failed!", API_VERSION.c_str()); @@ -1405,5 +1411,241 @@ bool ModuleJson::SetBuildHash(const std::string& buildHash) } return true; } + +bool ModuleJson::SetVersionCode(const int32_t& versionCode, const bool& isStage) +{ + if (isStage) { + if (!SetStageVersionCode(versionCode)) { + LOGE("SetStageVersionCode failed!"); + return false; + } + } else { + if (!SetFaVersionCode(versionCode)) { + LOGE("SetFaVersionCode failed!"); + return false; + } + } + return true; +} + +bool ModuleJson::SetVersionName(const std::string& versionName, const bool& isStage) +{ + if (isStage) { + if (!SetStageVersionName(versionName)) { + LOGE("SetStageVersionName failed!"); + return false; + } + } else { + if (!SetFaVersionName(versionName)) { + LOGE("SetFaVersionName failed!"); + return false; + } + } + return true; +} + +bool ModuleJson::SetBundleName(const std::string& bundleName, const bool& isStage) +{ + if (isStage) { + if (!SetStageBundleName(bundleName)) { + LOGE("SetStageBundleName failed!"); + return false; + } + } else { + if (!SetFaBundleName(bundleName)) { + LOGE("SetFaBundleName failed!"); + return false; + } + } + return true; +} + +bool ModuleJson::SetMinCompatibleVersionCode(const int32_t& minCompatibleVersionCode, const bool& isStage) +{ + if (isStage) { + if (!SetStageMinCompatibleVersionCode(minCompatibleVersionCode)) { + LOGE("SetStageMinCompatibleVersionCode failed!"); + return false; + } + } else { + if (!SetFaMinCompatibleVersionCode(minCompatibleVersionCode)) { + LOGE("SetFaMinCompatibleVersionCode failed!"); + return false; + } + } + return true; +} + +bool ModuleJson::SetMinAPIVersion(const int32_t& minAPIVersion, const bool& isStage) +{ + if (isStage) { + if (!SetStageMinAPIVersion(minAPIVersion)) { + LOGE("SetStageMinAPIVersion failed!"); + return false; + } + } else { + if (!SetFaMinAPIVersion(minAPIVersion)) { + LOGE("SetFaMinAPIVersion failed!"); + return false; + } + } + return true; +} + +bool ModuleJson::SetTargetAPIVersion(const int32_t& targetAPIVersion, const bool& isStage) +{ + if (isStage) { + if (!SetStageTargetAPIVersion(targetAPIVersion)) { + LOGE("SetStageTargetAPIVersion failed!"); + return false; + } + } else { + if (!SetFaTargetAPIVersion(targetAPIVersion)) { + LOGE("SetFaTargetAPIVersion failed!"); + return false; + } + } + return true; +} + +bool ModuleJson::SetApiReleaseType(const std::string& apiReleaseType, const bool& isStage) +{ + if (isStage) { + if (!SetStageApiReleaseType(apiReleaseType)) { + LOGE("SetStageApiReleaseType failed!"); + return false; + } + } else { + if (!SetFaApiReleaseType(apiReleaseType)) { + LOGE("SetFaApiReleaseType failed!"); + return false; + } + } + return true; +} + +bool ModuleJson::SetBundleType(const std::string& bundleType, const bool& isStage) +{ + if (isStage) { + if (!SetStageBundleType(bundleType)) { + LOGE("SetStageBundleType failed!"); + return false; + } + } else { + if (!SetFaBundleType(bundleType)) { + LOGE("SetFaBundleType failed!"); + return false; + } + } + return true; +} + +bool ModuleJson::SetInstallationFree(const bool& installationFree, const bool& isStage) +{ + if (isStage) { + if (!SetStageInstallationFree(installationFree)) { + LOGE("SetStageInstallationFree failed!"); + return false; + } + } else { + if (!SetFaInstallationFree(installationFree)) { + LOGE("SetFaInstallationFree failed!"); + return false; + } + } + return true; +} + +bool ModuleJson::SetDeliveryWithInstall(const bool& deliveryWithInstall, const bool& isStage) +{ + if (isStage) { + if (!SetStageDeliveryWithInstall(deliveryWithInstall)) { + LOGE("SetStageDeliveryWithInstall failed!"); + return false; + } + } else { + if (!SetFaDeliveryWithInstall(deliveryWithInstall)) { + LOGE("SetFaDeliveryWithInstall failed!"); + return false; + } + } + return true; +} + +bool ModuleJson::SetDeviceTypes(const std::list& deviceTypes, const bool& isStage) +{ + if (isStage) { + if (!SetStageDeviceTypes(deviceTypes)) { + LOGE("SetStageDeviceTypen failed!"); + return false; + } + } else { + if (!SetFaDeviceTypes(deviceTypes)) { + LOGE("SetFaDeviceTypen failed!"); + return false; + } + } + return true; +} + +bool ModuleJson::GetMinApiVersion(int32_t& minAPIVersion) +{ + std::unique_ptr appObj; + if (!GetAppObject(appObj)) { + LOGE("GetAppObject failed!"); + return false; + } + if (!appObj) { + LOGE("App node is null!"); + return false; + } + if (appObj->Contains(MIN_API_VERSION.c_str())) { + if (appObj->GetInt(MIN_API_VERSION.c_str(), &minAPIVersion) != Result::SUCCESS) { + LOGE("App node get %s failed!", MIN_API_VERSION.c_str()); + return false; + } + } + return true; +} + +bool ModuleJson::GetTargetApiVersion(int32_t& targetAPIVersion) +{ + std::unique_ptr appObj; + if (!GetAppObject(appObj)) { + LOGE("GetAppObject failed!"); + return false; + } + if (!appObj) { + LOGE("App node is null!"); + return false; + } + if (appObj->Contains(TARGET_API_VERSION.c_str())) { + if (appObj->GetInt(TARGET_API_VERSION.c_str(), &targetAPIVersion) != Result::SUCCESS) { + LOGE("App node get %s failed!", TARGET_API_VERSION.c_str()); + return false; + } + } + return true; +} + +bool ModuleJson::GetDeliveryWithInstall(bool& deliveryWithInstall) +{ + std::unique_ptr moduleObj; + if (!GetModuleObject(moduleObj)) { + LOGE("GetModuleObject failed!"); + return false; + } + if (!moduleObj) { + LOGE("Module node is null!"); + return false; + } + if (moduleObj->Contains(DELIVERY_WITH_INSTALL.c_str())) { + if (moduleObj->GetBool(DELIVERY_WITH_INSTALL.c_str(), &deliveryWithInstall) != Result::SUCCESS) { + LOGE("Module node get %s failed!", DELIVERY_WITH_INSTALL.c_str()); + return false; + } + } + return true; +} } // namespace AppPackingTool } // namespace OHOS diff --git a/packing_tool/frameworks/src/json/module_json_fa.cpp b/packing_tool/frameworks/src/json/module_json_fa.cpp index aa4a3acd..1f712381 100644 --- a/packing_tool/frameworks/src/json/module_json_fa.cpp +++ b/packing_tool/frameworks/src/json/module_json_fa.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 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 @@ -36,6 +36,7 @@ const std::string API_RELEASE_TYPE = "apiReleaseType"; const std::string DEBUG = "debug"; const std::string COMPATIBLE = "compatible"; const std::string RELEASE_TYPE = "releaseType"; +const std::string DELIVERY_WITH_INSTALL = "deliveryWithInstall"; const std::string TARGET = "target"; const std::string VERSION = "version"; const std::string CODE = "code"; @@ -221,6 +222,29 @@ bool ModuleJson::GetFaInstallationFreeByDistroObj(std::unique_ptr& distr return true; } +bool ModuleJson::GetFaDeliveryWithInstall(bool& deliveryWithInstall) +{ + std::unique_ptr distroObj; + if (!GetDistroObject(distroObj)) { + LOGE("GetDistroObject failed!"); + return false; + } + if (!distroObj) { + LOGE("Distro node is null!"); + return false; + } + if (distroObj->Contains(DELIVERY_WITH_INSTALL.c_str())) { + if (distroObj->GetBool(DELIVERY_WITH_INSTALL.c_str(), &deliveryWithInstall) != Result::SUCCESS) { + LOGE("Distro node get %s failed!", DELIVERY_WITH_INSTALL.c_str()); + return false; + } + } else { + LOGE("Distro node has no %s node!", DELIVERY_WITH_INSTALL.c_str()); + return false; + } + return true; +} + bool ModuleJson::GetFaBundleType(std::string& bundleType) { bool installationFree = false; @@ -814,5 +838,194 @@ bool ModuleJson::SetFaHapVerifyInfoByModuleObj(std::unique_ptr& moduleOb hapVerifyInfo.SetInstallationFree(installationFree); return true; } + +bool ModuleJson::SetFaBundleName(const std::string& bundleName) +{ + std::unique_ptr appObj; + if (!GetAppObject(appObj)) { + LOGE("GetAppObject failed!"); + return false; + } + if (!appObj->Contains(BUNDLE_NAME.c_str())) { + if (!appObj->Add(BUNDLE_NAME.c_str(), bundleName.c_str())) { + LOGE("App node add %s failed!", BUNDLE_NAME.c_str()); + return false; + } + return true; + } + if (appObj->SetString(BUNDLE_NAME.c_str(), bundleName) != Result::SUCCESS) { + LOGE("App node set %s failed!", BUNDLE_NAME.c_str()); + return false; + } + return true; +} + +bool ModuleJson::SetFaMinCompatibleVersionCode(const int32_t& minCompatibleVersionCode) +{ + std::unique_ptr versionObj; + if (!GetVersionObject(versionObj)) { + LOGE("GetVersionObject failed!"); + return false; + } + if (!versionObj->Contains(MIN_COMPATIBLE_VERSION_CODE.c_str())) { + if (!versionObj->Add(MIN_COMPATIBLE_VERSION_CODE.c_str(), minCompatibleVersionCode)) { + LOGE("Version node add %s failed!", MIN_COMPATIBLE_VERSION_CODE.c_str()); + return false; + } + return true; + } + if (versionObj->SetInt(MIN_COMPATIBLE_VERSION_CODE.c_str(), minCompatibleVersionCode) != Result::SUCCESS) { + LOGE("Version node set %s failed!", MIN_COMPATIBLE_VERSION_CODE.c_str()); + return false; + } + return true; +} + +bool ModuleJson::SetFaMinAPIVersion(const int32_t& minAPIVersion) +{ + std::unique_ptr apiVersionObj; + if (!GetApiVersionObject(apiVersionObj)) { + LOGE("GetAppObject failed!"); + return false; + } + if (!apiVersionObj->Contains(COMPATIBLE.c_str())) { + if (!apiVersionObj->Add(COMPATIBLE.c_str(), minAPIVersion)) { + LOGE("ApiVersion node add %s failed!", COMPATIBLE.c_str()); + return false; + } + return true; + } + if (apiVersionObj->SetInt(COMPATIBLE.c_str(), minAPIVersion) != Result::SUCCESS) { + LOGE("ApiVersion node set %s failed!", COMPATIBLE.c_str()); + return false; + } + return true; +} + +bool ModuleJson::SetFaTargetAPIVersion(const int32_t& targetAPIVersion) +{ + std::unique_ptr apiVersionObj; + if (!GetApiVersionObject(apiVersionObj)) { + LOGE("GetApiVersionObject failed!"); + return false; + } + if (!apiVersionObj->Contains(TARGET.c_str())) { + if (!apiVersionObj->Add(TARGET.c_str(), targetAPIVersion)) { + LOGE("ApiVersion node add %s failed!", TARGET.c_str()); + return false; + } + return true; + } + if (apiVersionObj->SetInt(TARGET.c_str(), targetAPIVersion) != Result::SUCCESS) { + LOGE("ApiVersion node set %s failed!", TARGET.c_str()); + return false; + } + return true; +} + +bool ModuleJson::SetFaApiReleaseType(const std::string& apiReleaseType) +{ + std::unique_ptr apiVersionObj; + if (!GetApiVersionObject(apiVersionObj)) { + LOGE("GetApiVersionObject failed!"); + return false; + } + if (!apiVersionObj->Contains(RELEASE_TYPE.c_str())) { + if (!apiVersionObj->Add(RELEASE_TYPE.c_str(), apiReleaseType.c_str())) { + LOGE("ApiVersion node add %s failed!", RELEASE_TYPE.c_str()); + return false; + } + return true; + } + if (apiVersionObj->SetString(RELEASE_TYPE.c_str(), apiReleaseType) != Result::SUCCESS) { + LOGE("ApiVersion node set %s failed!", RELEASE_TYPE.c_str()); + return false; + } + return true; +} + +bool ModuleJson::SetFaBundleType(const std::string& bundleType) +{ + std::unique_ptr appObj; + if (!GetAppObject(appObj)) { + LOGE("GetAppObject failed!"); + return false; + } + if (!appObj->Contains(BUNDLE_TYPE.c_str())) { + if (!appObj->Add(BUNDLE_TYPE.c_str(), bundleType.c_str())) { + LOGE("App node add %s failed!", BUNDLE_TYPE.c_str()); + return false; + } + return true; + } + if (appObj->SetString(BUNDLE_TYPE.c_str(), bundleType) != Result::SUCCESS) { + LOGE("App node set %s failed!", BUNDLE_TYPE.c_str()); + return false; + } + return true; +} + +bool ModuleJson::SetFaInstallationFree(const bool& installationFree) +{ + std::unique_ptr distroObj; + if (!GetDistroObject(distroObj)) { + LOGE("GetDistroObject failed!"); + return false; + } + if (!distroObj->Contains(INSTALLATION_FREE.c_str())) { + if (!distroObj->Add(INSTALLATION_FREE.c_str(), installationFree)) { + LOGE("Distro node add %s failed!", INSTALLATION_FREE.c_str()); + return false; + } + return true; + } + if (distroObj->SetBool(INSTALLATION_FREE.c_str(), installationFree) != Result::SUCCESS) { + LOGE("Distro node set %s failed!", INSTALLATION_FREE.c_str()); + return false; + } + return true; +} + +bool ModuleJson::SetFaDeliveryWithInstall(const bool& deliveryWithInstall) +{ + std::unique_ptr distroObj; + if (!GetDistroObject(distroObj)) { + LOGE("GetDistroObject failed!"); + return false; + } + if (!distroObj->Contains(DELIVERY_WITH_INSTALL.c_str())) { + if (!distroObj->Add(DELIVERY_WITH_INSTALL.c_str(), deliveryWithInstall)) { + LOGE("Distro node add %s failed!", DELIVERY_WITH_INSTALL.c_str()); + return false; + } + return true; + } + if (distroObj->SetBool(DELIVERY_WITH_INSTALL.c_str(), deliveryWithInstall) != Result::SUCCESS) { + LOGE("Distro node set %s failed!", DELIVERY_WITH_INSTALL.c_str()); + return false; + } + return true; +} + +bool ModuleJson::SetFaDeviceTypes(const std::list& deviceTypes) +{ + std::unique_ptr moduleObj; + if (!GetModuleObject(moduleObj)) { + LOGE("GetModuleObject failed!"); + return false; + } + if (!moduleObj->Contains(DEVICE_TYPE.c_str())) { + if (!moduleObj->Add(DEVICE_TYPE.c_str(), deviceTypes)) { + LOGE("Module node add %s failed!", DEVICE_TYPE.c_str()); + return false; + } + return true; + } + if (moduleObj->SetArray(DEVICE_TYPE.c_str(), deviceTypes) != Result::SUCCESS) { + LOGE("Module node set %s failed!", DEVICE_TYPE.c_str()); + return false; + } + return true; +} } // namespace AppPackingTool } // namespace OHOS diff --git a/packing_tool/frameworks/src/json/module_json_stage.cpp b/packing_tool/frameworks/src/json/module_json_stage.cpp index dfb25e1b..c500083f 100644 --- a/packing_tool/frameworks/src/json/module_json_stage.cpp +++ b/packing_tool/frameworks/src/json/module_json_stage.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 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 @@ -36,6 +36,7 @@ const std::string API_RELEASE_TYPE = "apiReleaseType"; const std::string DEBUG = "debug"; const std::string COMPATIBLE = "compatible"; const std::string RELEASE_TYPE = "releaseType"; +const std::string DELIVERY_WITH_INSTALL = "deliveryWithInstall"; const std::string TARGET = "target"; const std::string VERSION = "version"; const std::string CODE = "code"; @@ -123,6 +124,195 @@ bool ModuleJson::SetStageVersionName(const std::string& versionName) return true; } +bool ModuleJson::SetStageBundleName(const std::string& bundleName) +{ + std::unique_ptr appObj; + if (!GetAppObject(appObj)) { + LOGE("GetAppObject failed!"); + return false; + } + if (!appObj->Contains(BUNDLE_NAME.c_str())) { + if (!appObj->Add(BUNDLE_NAME.c_str(), bundleName.c_str())) { + LOGE("App node add %s failed!", BUNDLE_NAME.c_str()); + return false; + } + return true; + } + if (appObj->SetString(BUNDLE_NAME.c_str(), bundleName) != Result::SUCCESS) { + LOGE("App node set %s failed!", BUNDLE_NAME.c_str()); + return false; + } + return true; +} + +bool ModuleJson::SetStageMinCompatibleVersionCode(const int32_t& minCompatibleVersionCode) +{ + std::unique_ptr appObj; + if (!GetAppObject(appObj)) { + LOGE("GetAppObject failed!"); + return false; + } + if (!appObj->Contains(MIN_COMPATIBLE_VERSION_CODE.c_str())) { + if (!appObj->Add(MIN_COMPATIBLE_VERSION_CODE.c_str(), minCompatibleVersionCode)) { + LOGE("App node add %s failed!", MIN_COMPATIBLE_VERSION_CODE.c_str()); + return false; + } + return true; + } + if (appObj->SetInt(MIN_COMPATIBLE_VERSION_CODE.c_str(), minCompatibleVersionCode) != Result::SUCCESS) { + LOGE("App node set %s failed!", MIN_COMPATIBLE_VERSION_CODE.c_str()); + return false; + } + return true; +} + +bool ModuleJson::SetStageMinAPIVersion(const int32_t& minAPIVersion) +{ + std::unique_ptr appObj; + if (!GetAppObject(appObj)) { + LOGE("GetAppObject failed!"); + return false; + } + if (!appObj->Contains(MIN_API_VERSION.c_str())) { + if (!appObj->Add(MIN_API_VERSION.c_str(), minAPIVersion)) { + LOGE("App node add %s failed!", MIN_API_VERSION.c_str()); + return false; + } + return true; + } + if (appObj->SetInt(MIN_API_VERSION.c_str(), minAPIVersion) != Result::SUCCESS) { + LOGE("App node set %s failed!", MIN_API_VERSION.c_str()); + return false; + } + return true; +} + +bool ModuleJson::SetStageTargetAPIVersion(const int32_t& targetAPIVersion) +{ + std::unique_ptr appObj; + if (!GetAppObject(appObj)) { + LOGE("GetAppObject failed!"); + return false; + } + if (!appObj->Contains(TARGET_API_VERSION.c_str())) { + if (!appObj->Add(TARGET_API_VERSION.c_str(), targetAPIVersion)) { + LOGE("App node add %s failed!", TARGET_API_VERSION.c_str()); + return false; + } + return true; + } + if (appObj->SetInt(TARGET_API_VERSION.c_str(), targetAPIVersion) != Result::SUCCESS) { + LOGE("App node set %s failed!", TARGET_API_VERSION.c_str()); + return false; + } + return true; +} + +bool ModuleJson::SetStageApiReleaseType(const std::string& apiReleaseType) +{ + std::unique_ptr appObj; + if (!GetAppObject(appObj)) { + LOGE("GetAppObject failed!"); + return false; + } + if (!appObj->Contains(API_RELEASE_TYPE.c_str())) { + if (!appObj->Add(API_RELEASE_TYPE.c_str(), apiReleaseType.c_str())) { + LOGE("App node add %s failed!", API_RELEASE_TYPE.c_str()); + return false; + } + return true; + } + if (appObj->SetString(API_RELEASE_TYPE.c_str(), apiReleaseType) != Result::SUCCESS) { + LOGE("App node set %s failed!", API_RELEASE_TYPE.c_str()); + return false; + } + return true; +} + +bool ModuleJson::SetStageBundleType(const std::string& bundleType) +{ + std::unique_ptr appObj; + if (!GetAppObject(appObj)) { + LOGE("GetAppObject failed!"); + return false; + } + if (!appObj->Contains(BUNDLE_TYPE.c_str())) { + if (!appObj->Add(BUNDLE_TYPE.c_str(), bundleType.c_str())) { + LOGE("App node add %s failed!", BUNDLE_TYPE.c_str()); + return false; + } + return true; + } + if (appObj->SetString(BUNDLE_TYPE.c_str(), bundleType) != Result::SUCCESS) { + LOGE("App node set %s failed!", BUNDLE_TYPE.c_str()); + return false; + } + return true; +} + +bool ModuleJson::SetStageInstallationFree(const bool& installationFree) +{ + std::unique_ptr moduleObj; + if (!GetModuleObject(moduleObj)) { + LOGE("GetModuleObject failed!"); + return false; + } + if (!moduleObj->Contains(INSTALLATION_FREE.c_str())) { + if (!moduleObj->Add(INSTALLATION_FREE.c_str(), installationFree)) { + LOGE("App node add %s failed!", INSTALLATION_FREE.c_str()); + return false; + } + return true; + } + if (moduleObj->SetBool(INSTALLATION_FREE.c_str(), installationFree) != Result::SUCCESS) { + LOGE("Module node set %s failed!", INSTALLATION_FREE.c_str()); + return false; + } + return true; +} + +bool ModuleJson::SetStageDeliveryWithInstall(const bool& deliveryWithInstall) +{ + std::unique_ptr moduleObj; + if (!GetModuleObject(moduleObj)) { + LOGE("GetModuleObject failed!"); + return false; + } + if (!moduleObj->Contains(DELIVERY_WITH_INSTALL.c_str())) { + if (!moduleObj->Add(DELIVERY_WITH_INSTALL.c_str(), deliveryWithInstall)) { + LOGE("App node add %s failed!", DELIVERY_WITH_INSTALL.c_str()); + return false; + } + return true; + } + if (moduleObj->SetBool(DELIVERY_WITH_INSTALL.c_str(), deliveryWithInstall) != Result::SUCCESS) { + LOGE("Module node set %s failed!", DELIVERY_WITH_INSTALL.c_str()); + return false; + } + return true; +} + +bool ModuleJson::SetStageDeviceTypes(const std::list& deviceTypes) +{ + std::unique_ptr moduleObj; + if (!GetModuleObject(moduleObj)) { + LOGE("GetModuleObject failed!"); + return false; + } + if (!moduleObj->Contains(DEVICE_TYPES.c_str())) { + if (!moduleObj->Add(DEVICE_TYPES.c_str(), deviceTypes)) { + LOGE("App node add %s failed!", DEVICE_TYPES.c_str()); + return false; + } + return true; + } + if (moduleObj->SetArray(DEVICE_TYPES.c_str(), deviceTypes) != Result::SUCCESS) { + LOGE("Module node set %s failed!", DEVICE_TYPES.c_str()); + return false; + } + return true; +} + bool ModuleJson::GetStageVersion(Version& version) { std::unique_ptr appObj; diff --git a/packing_tool/frameworks/src/json/pack_info.cpp b/packing_tool/frameworks/src/json/pack_info.cpp index d15db147..9cebaccf 100644 --- a/packing_tool/frameworks/src/json/pack_info.cpp +++ b/packing_tool/frameworks/src/json/pack_info.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 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 @@ -40,6 +40,18 @@ const std::string FORMS = "forms"; const std::string DEFAULT_DIMENSION = "defaultDimension"; const std::string SUPPORT_DIMENSIONS = "supportDimensions"; const char ASTERISK = '*'; +const std::string MIN_COMPATIBLE_VERSION_CODE = "minCompatibleVersionCode"; +const std::string MIN_API_VERSION = "minAPIVersion"; +const std::string TARGET_API_VERSION = "targetAPIVersion"; +const std::string API_RELEASE_TYPE = "apiReleaseType"; +const std::string INSTALLATION_FREE = "installationFree"; +const std::string DELIVERY_WITH_INSTALL = "deliveryWithInstall"; +const std::string COMPILE_SDK_TYPE = "compileSdkType"; +const std::string DEVICE_TYPE = "deviceType"; +const std::string COMPATIBLE = "compatible"; +const std::string RELEASE_TYPE = "releaseType"; +const std::string TARGET = "target"; +const std::string API_VERSION = "apiVersion"; } bool PackInfo::ParseFromString(const std::string& jsonString) @@ -294,6 +306,29 @@ bool PackInfo::GetDistroObjectByModuleObj(const std::unique_ptr& moduleO return true; } +bool PackInfo::GetApiVersionObjectByModuleObj(const std::unique_ptr& moduleObj, + std::unique_ptr& apiVersionObj) +{ + if (!moduleObj) { + LOGE("Module node is null!"); + return false; + } + if (!moduleObj->Contains(API_VERSION.c_str())) { + cJSON *apiVersion = cJSON_CreateObject(); + apiVersionObj = std::make_unique(apiVersion); + if (!moduleObj->Add(API_VERSION.c_str(), apiVersionObj)) { + LOGE("Module node add %s node failed!", API_VERSION.c_str()); + return false; + } + return true; + } + if (moduleObj->GetObject(API_VERSION.c_str(), &apiVersionObj) != Result::SUCCESS) { + LOGE("Module node get %s node failed!", API_VERSION.c_str()); + return false; + } + return true; +} + bool PackInfo::GetExtensionAbilitiesObj(int32_t moduleIndex, std::unique_ptr& extensionAbilitiesObj) { std::unique_ptr modulesObj; @@ -657,5 +692,294 @@ bool PackInfo::GetPackageNamesByPackagesObj(const std::unique_ptr& packa } return true; } + +bool PackInfo::SetMinCompatibleVersionCode(const int32_t& minCompatibleVersionCode) +{ + std::unique_ptr versionObj; + if (!GetVersionObject(versionObj)) { + LOGE("GetVersionObject failed!"); + return false; + } + if (!versionObj->Contains(MIN_COMPATIBLE_VERSION_CODE.c_str())) { + if (!versionObj->Add(MIN_COMPATIBLE_VERSION_CODE.c_str(), minCompatibleVersionCode)) { + LOGE("App node add %s failed!", MIN_COMPATIBLE_VERSION_CODE.c_str()); + return false; + } + return true; + } + if (versionObj->SetInt(MIN_COMPATIBLE_VERSION_CODE.c_str(), minCompatibleVersionCode) != Result::SUCCESS) { + LOGE("Version node set %s failed!", CODE.c_str()); + return false; + } + return true; +} + +bool PackInfo::SetMinAPIVersion(const int32_t& minAPIVersion) +{ + std::unique_ptr modulesObj; + if (!GetModulesObject(modulesObj)) { + LOGE("GetModulesObject failed!"); + return false; + } + int32_t modulesSize = modulesObj->GetSize(); + for (int i = 0; i < modulesSize; i++) { + std::unique_ptr moduleObj = modulesObj->Get(i); + if (moduleObj == nullptr) { + LOGE("GetModuleObject failed!"); + return false; + } + std::unique_ptr apiVersionObj; + if (!GetApiVersionObjectByModuleObj(moduleObj, apiVersionObj)) { + LOGE("GetApiVersionObjectByModuleObj failed!"); + return false; + } + if (!apiVersionObj->Contains(COMPATIBLE.c_str())) { + if (!apiVersionObj->Add(COMPATIBLE.c_str(), minAPIVersion)) { + LOGE("App node add %s failed!", COMPATIBLE.c_str()); + return false; + } + return true; + } + if (apiVersionObj->SetInt(COMPATIBLE.c_str(), minAPIVersion) != Result::SUCCESS) { + LOGE("Module node set %s failed!", COMPATIBLE.c_str()); + return false; + } + } + return true; +} + +bool PackInfo::SetTargetAPIVersion(const int32_t& targetAPIVersion) +{ + std::unique_ptr modulesObj; + if (!GetModulesObject(modulesObj)) { + LOGE("GetModulesObject failed!"); + return false; + } + int32_t modulesSize = modulesObj->GetSize(); + for (int i = 0; i < modulesSize; i++) { + std::unique_ptr moduleObj = modulesObj->Get(i); + if (moduleObj == nullptr) { + LOGE("GetModuleObject failed!"); + return false; + } + std::unique_ptr apiVersionObj; + if (!GetApiVersionObjectByModuleObj(moduleObj, apiVersionObj)) { + LOGE("GetApiVersionObjectByModuleObj failed!"); + return false; + } + if (!apiVersionObj->Contains(TARGET.c_str())) { + if (!apiVersionObj->Add(TARGET.c_str(), targetAPIVersion)) { + LOGE("App node add %s failed!", TARGET.c_str()); + return false; + } + return true; + } + if (apiVersionObj->SetInt(TARGET.c_str(), targetAPIVersion) != Result::SUCCESS) { + LOGE("Module node set %s failed!", TARGET.c_str()); + return false; + } + } + return true; +} + +bool PackInfo::SetApiReleaseType(const std::string& apiReleaseType) +{ + std::unique_ptr modulesObj; + if (!GetModulesObject(modulesObj)) { + LOGE("GetModulesObject failed!"); + return false; + } + int32_t modulesSize = modulesObj->GetSize(); + for (int i = 0; i < modulesSize; i++) { + std::unique_ptr moduleObj = modulesObj->Get(i); + if (moduleObj == nullptr) { + LOGE("GetModuleObject failed!"); + return false; + } + std::unique_ptr apiVersionObj; + if (!GetApiVersionObjectByModuleObj(moduleObj, apiVersionObj)) { + LOGE("GetApiVersionObjectByModuleObj failed!"); + return false; + } + if (!apiVersionObj->Contains(RELEASE_TYPE.c_str())) { + if (!apiVersionObj->Add(RELEASE_TYPE.c_str(), apiReleaseType.c_str())) { + LOGE("App node add %s failed!", RELEASE_TYPE.c_str()); + return false; + } + return true; + } + if (apiVersionObj->SetString(RELEASE_TYPE.c_str(), apiReleaseType) != Result::SUCCESS) { + LOGE("Module node set %s failed!", RELEASE_TYPE.c_str()); + return false; + } + } + return true; +} + +bool PackInfo::SetBundleType(const std::string& bundleType) +{ + std::unique_ptr appObj; + if (!GetAppObject(appObj)) { + LOGE("GetAppObject failed!"); + return false; + } + if (!appObj->Contains(BUNDLE_TYPE.c_str())) { + if (!appObj->Add(BUNDLE_TYPE.c_str(), bundleType.c_str())) { + LOGE("App node add %s failed!", BUNDLE_TYPE.c_str()); + return false; + } + return true; + } + if (appObj->SetString(BUNDLE_TYPE.c_str(), bundleType) != Result::SUCCESS) { + LOGE("App node set %s failed!", BUNDLE_TYPE.c_str()); + return false; + } + return true; +} + +bool PackInfo::SetInstallationFree(const bool& installationFree) +{ + std::unique_ptr modulesObj; + if (!GetModulesObject(modulesObj)) { + LOGE("GetModulesObject failed!"); + return false; + } + int32_t modulesSize = modulesObj->GetSize(); + for (int i = 0; i < modulesSize; i++) { + std::unique_ptr moduleObj = modulesObj->Get(i); + if (moduleObj == nullptr) { + LOGE("GetModuleObject failed!"); + return false; + } + std::unique_ptr distroObj; + if (!GetDistroObject(i, distroObj)) { + LOGE("GetDistroObject failed!"); + return false; + } + if (!distroObj->Contains(INSTALLATION_FREE.c_str())) { + if (!distroObj->Add(INSTALLATION_FREE.c_str(), installationFree)) { + LOGE("App node add %s failed!", INSTALLATION_FREE.c_str()); + return false; + } + return true; + } + if (distroObj->SetBool(INSTALLATION_FREE.c_str(), installationFree) != Result::SUCCESS) { + LOGE("Module node set %s failed!", INSTALLATION_FREE.c_str()); + return false; + } + } + return true; +} + +bool PackInfo::SetDeliveryWithInstall(const bool& deliveryWithInstall) +{ + std::unique_ptr modulesObj; + if (!GetModulesObject(modulesObj)) { + LOGE("GetModulesObject failed!"); + return false; + } + int32_t modulesSize = modulesObj->GetSize(); + for (int i = 0; i < modulesSize; i++) { + std::unique_ptr moduleObj = modulesObj->Get(i); + if (moduleObj == nullptr) { + LOGE("GetModuleObject failed!"); + return false; + } + std::unique_ptr distroObj; + if (!GetDistroObject(i, distroObj)) { + LOGE("GetDistroObject failed!"); + return false; + } + if (!distroObj->Contains(DELIVERY_WITH_INSTALL.c_str())) { + if (!distroObj->Add(DELIVERY_WITH_INSTALL.c_str(), deliveryWithInstall)) { + LOGE("App node add %s failed!", DELIVERY_WITH_INSTALL.c_str()); + return false; + } + return true; + } + if (distroObj->SetBool(DELIVERY_WITH_INSTALL.c_str(), deliveryWithInstall) != Result::SUCCESS) { + LOGE("Module node set %s failed!", DELIVERY_WITH_INSTALL.c_str()); + return false; + } + } + std::unique_ptr packagesObj; + if (!GetPackagesObject(packagesObj)) { + LOGE("GetModuleObject failed!"); + return false; + } + int32_t packagesSize = packagesObj->GetSize(); + for (int i = 0; i < packagesSize; i++) { + std::unique_ptr packageObj = packagesObj->Get(i); + if (packageObj == nullptr) { + LOGE("GetModuleObject failed!"); + return false; + } + if (!packageObj->Contains(DELIVERY_WITH_INSTALL.c_str())) { + if (!packageObj->Add(DELIVERY_WITH_INSTALL.c_str(), deliveryWithInstall)) { + LOGE("App node add %s failed!", DELIVERY_WITH_INSTALL.c_str()); + return false; + } + return true; + } + if (packageObj->SetBool(DELIVERY_WITH_INSTALL.c_str(), deliveryWithInstall) != Result::SUCCESS) { + LOGE("Module node set %s failed!", DELIVERY_WITH_INSTALL.c_str()); + return false; + } + } + return true; +} + +bool PackInfo::SetDeviceTypes(const std::list& deviceTypes) +{ + std::unique_ptr modulesObj; + if (!GetModulesObject(modulesObj)) { + LOGE("GetModuleObject failed!"); + return false; + } + int32_t modulesSize = modulesObj->GetSize(); + for (int i = 0; i < modulesSize; i++) { + std::unique_ptr moduleObj = modulesObj->Get(i); + if (moduleObj == nullptr) { + LOGE("GetModuleObject failed!"); + return false; + } + if (!moduleObj->Contains(DEVICE_TYPE.c_str())) { + if (!moduleObj->Add(DEVICE_TYPE.c_str(), deviceTypes)) { + LOGE("App node add %s failed!", DEVICE_TYPE.c_str()); + return false; + } + return true; + } + if (moduleObj->SetArray(DEVICE_TYPE.c_str(), deviceTypes) != Result::SUCCESS) { + LOGE("Module node set %s failed!", DEVICE_TYPE.c_str()); + return false; + } + } + std::unique_ptr packagesObj; + if (!GetPackagesObject(packagesObj)) { + LOGE("GetModuleObject failed!"); + return false; + } + int32_t packagesSize = packagesObj->GetSize(); + for (int i = 0; i < packagesSize; i++) { + std::unique_ptr packageObj = packagesObj->Get(i); + if (packageObj == nullptr) { + LOGE("GetModuleObject failed!"); + return false; + } + if (!packageObj->Contains(DEVICE_TYPE.c_str())) { + if (!packageObj->Add(DEVICE_TYPE.c_str(), deviceTypes)) { + LOGE("App node add %s failed!", DEVICE_TYPE.c_str()); + return false; + } + return true; + } + if (packageObj->SetArray(DEVICE_TYPE.c_str(), deviceTypes) != Result::SUCCESS) { + LOGE("Module node set %s failed!", DEVICE_TYPE.c_str()); + return false; + } + } + return true; +} } // namespace AppPackingTool } // namespace OHOS diff --git a/packing_tool/frameworks/src/json/pt_json.cpp b/packing_tool/frameworks/src/json/pt_json.cpp index 9457de3e..a81b8b44 100644 --- a/packing_tool/frameworks/src/json/pt_json.cpp +++ b/packing_tool/frameworks/src/json/pt_json.cpp @@ -156,6 +156,30 @@ bool PtJson::Add(const char *key, const std::unique_ptr &value) const return true; } +bool PtJson::Add(const char *key, const std::list& values) const +{ + if (key == nullptr || Contains(key)) { + return false; + } + + cJSON *node = cJSON_CreateArray(); + if (node == nullptr) { + return false; + } + + for (const auto &value : values) { + cJSON_AddItemToArray(node, cJSON_CreateString(value.c_str())); + } + + cJSON_bool ret = cJSON_AddItemToObject(object_, key, node); + if (ret == 0) { + cJSON_Delete(node); + return false; + } + + return true; +} + bool PtJson::Push(bool value) const { return Push(cJSON_CreateBool(value)); @@ -526,6 +550,31 @@ Result PtJson::GetArray(const char *key, std::unique_ptr *value) const return Result::SUCCESS; } +Result PtJson::SetArray(const char *key, const std::list& value) +{ + cJSON *item = cJSON_GetObjectItem(object_, key); + if (item == nullptr) { + return Result::NOT_EXIST; + } + if (cJSON_IsArray(item) == 0) { + return Result::TYPE_ERROR; + } + cJSON *newArray = cJSON_CreateArray(); + if (newArray == nullptr) { + return Result::TYPE_ERROR; + } + for (const auto& str : value) { + cJSON *strItem = cJSON_CreateString(str.c_str()); + if (strItem == nullptr) { + cJSON_Delete(newArray); + return Result::TYPE_ERROR; + } + cJSON_AddItemToArray(newArray, strItem); + } + cJSON_ReplaceItemInObject(object_, key, newArray); + return Result::SUCCESS; +} + Result PtJson::GetAny(const char *key, std::unique_ptr *value) const { cJSON *item = cJSON_GetObjectItem(object_, key); diff --git a/packing_tool/frameworks/src/shell_command.cpp b/packing_tool/frameworks/src/shell_command.cpp index 3ffdb920..dd0835dc 100644 --- a/packing_tool/frameworks/src/shell_command.cpp +++ b/packing_tool/frameworks/src/shell_command.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 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 @@ -33,6 +33,7 @@ #include "package_normalize.h" #include "res_packager.h" #include "version_normalize.h" +#include "general_normalize.h" namespace OHOS { namespace AppPackingTool { @@ -190,6 +191,10 @@ std::unique_ptr ShellCommand::getPackager() std::unique_ptr packager = std::make_unique(parameterMap_, resultReceiver_); return packager; + } else if (mode == Constants::MODE_GENERAL_NORMALIZE) { + std::unique_ptr packager = + std::make_unique(parameterMap_, resultReceiver_); + return packager; } resultReceiver_.append("not support --mode: ").append(mode).append("\n"); return nullptr; diff --git a/packing_tool/frameworks/src/utils.cpp b/packing_tool/frameworks/src/utils.cpp index 87e231e1..64fcaa8f 100644 --- a/packing_tool/frameworks/src/utils.cpp +++ b/packing_tool/frameworks/src/utils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 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 @@ -30,6 +30,7 @@ #include #include "log.h" +#include "pt_json.h" namespace OHOS { namespace AppPackingTool { @@ -344,6 +345,28 @@ bool Utils::IsPositiveInteger(const std::string& str, int min, int max) return true; } +bool Utils::StringToBool(const std::string& str) +{ + std::string lowerStr = str; + std::transform(lowerStr.begin(), lowerStr.end(), lowerStr.begin(), ::tolower); + if (lowerStr == "true") { + return true; + } + return false; +} + +bool Utils::StringToArray(const std::string& str, std::list& array) +{ + array.clear(); + std::istringstream iss(str); + std::string item; + + while (std::getline(iss, item, ',')) { + array.push_back(item); + } + return true; +} + bool Utils::CheckFileName(const std::string& filePath, const std::string& fileName) { fs::path fsFilePath(filePath); @@ -458,5 +481,33 @@ bool Utils::GetRealPathOfNoneExistFile(const std::string& path, std::string& rea realPath = std::string(buffer) + fs::path::preferred_separator + fileName; return true; } + +bool Utils::RemoveAllFilesInDirectory(const std::string& directoryPath) +{ + fs::path fsPath(directoryPath); + if (!fs::exists(fsPath) || !fs::is_directory(fsPath)) { + return false; + } + for (auto& entry : fs::directory_iterator(fsPath)) { + if (fs::is_regular_file(entry)) { + fs::remove(entry); + } + } + return true; +} + +std::string Utils::ArrayToString(const std::list &array) +{ + std::unique_ptr jArray = PtJson::CreateArray(); + for (const auto& item : array) { + jArray->Push(item.c_str()); + } + return jArray->Stringify(); +} + +std::string Utils::BoolToString(bool value) +{ + return value ? "true" : "false"; +} } // namespace AppPackingTool } // namespace OHOS diff --git a/packing_tool/frameworks/test/unittest/shell_command_test/BUILD.gn b/packing_tool/frameworks/test/unittest/shell_command_test/BUILD.gn index 268cd829..e0101ba6 100644 --- a/packing_tool/frameworks/test/unittest/shell_command_test/BUILD.gn +++ b/packing_tool/frameworks/test/unittest/shell_command_test/BUILD.gn @@ -34,6 +34,7 @@ ohos_unittest("shell_command_test") { "../../../src/app_packager.cpp", "../../../src/appqf_packager.cpp", "../../../src/fast_app_packager.cpp", + "../../../src/general_normalize.cpp", "../../../src/hap_packager.cpp", "../../../src/hqf_packager.cpp", "../../../src/hqf_verify.cpp", -- Gitee