From 7503dd5710709fb3f9027411ff99919c7c882c70 Mon Sep 17 00:00:00 2001 From: dy Date: Fri, 8 Apr 2022 20:37:14 +0800 Subject: [PATCH] aging code 0408 Signed-off-by: dy Change-Id: Iefe73df9f91a34b120d75062d2cb1e741b010350 --- appexecfwk.gni | 12 + common/log/include/app_log_wrapper.h | 12 +- .../include/application_info.h | 1 + .../appexecfwk_base/include/hap_module_info.h | 1 + .../appexecfwk_base/src/application_info.cpp | 10 + .../appexecfwk_base/src/hap_module_info.cpp | 10 + .../include/bundlemgr/bundle_mgr_host.h | 15 + .../include/bundlemgr/bundle_mgr_interface.h | 25 ++ .../include/bundlemgr/bundle_mgr_proxy.h | 18 ++ .../src/bundlemgr/bundle_mgr_host.cpp | 35 +++ .../src/bundlemgr/bundle_mgr_proxy.cpp | 66 ++++ kits/appkit/napi/bundlemgr/bundle_mgr.cpp | 228 +++++++++++++- kits/appkit/napi/bundlemgr/bundle_mgr.h | 13 + kits/appkit/napi/bundlemgr/native_module.cpp | 1 + services/bundlemgr/BUILD.gn | 19 ++ services/bundlemgr/appexecfwk_bundlemgr.gni | 12 + .../include/aging/aging_bundle_info.h | 61 ++++ .../bundlemgr/include/aging/aging_constants.h | 52 ++++ .../bundlemgr/include/aging/aging_handler.h | 88 ++++++ .../include/aging/aging_handler_chain.h | 39 +++ .../bundlemgr/include/aging/aging_request.h | 77 +++++ services/bundlemgr/include/aging/aging_util.h | 37 +++ .../include/aging/bundle_aging_mgr.h | 68 ++++ services/bundlemgr/include/bundle_data_mgr.h | 41 +++ .../bundlemgr/include/bundle_mgr_host_impl.h | 17 + .../bundlemgr/include/bundle_mgr_service.h | 11 + .../bundlemgr/include/inner_bundle_info.h | 30 ++ .../src/aging/aging_handler_chain.cpp | 54 ++++ .../bundlemgr/src/aging/aging_request.cpp | 75 +++++ services/bundlemgr/src/aging/aging_util.cpp | 50 +++ .../bundlemgr/src/aging/bundle_aging_mgr.cpp | 218 +++++++++++++ .../aging/bundle_data_size_aging_handler.cpp | 32 ++ ...ver_10days_unused_bundle_aging_handler.cpp | 32 ++ ...ver_20days_unused_bundle_aging_handler.cpp | 32 ++ ...ver_30days_unused_bundle_aging_handler.cpp | 32 ++ .../recently_unused_bundle_aging_handler.cpp | 110 +++++++ .../bundlemgr/src/base_bundle_installer.cpp | 28 +- services/bundlemgr/src/bundle_data_mgr.cpp | 148 +++++++++ .../bundlemgr/src/bundle_mgr_host_impl.cpp | 20 ++ services/bundlemgr/src/bundle_mgr_service.cpp | 22 ++ services/bundlemgr/src/inner_bundle_info.cpp | 50 +++ services/bundlemgr/test/BUILD.gn | 4 + .../bms_bundle_accesstokenid_test/BUILD.gn | 14 + .../unittest/bms_bundle_clone_test/BUILD.gn | 14 + .../bms_bundle_installer_test/BUILD.gn | 29 +- .../bms_bundle_kit_service_test/BUILD.gn | 14 + .../bms_bundle_kit_service_test.cpp | 105 +++++++ .../bms_bundle_permission_grant_test/BUILD.gn | 14 + .../bms_bundle_uninstaller_test/BUILD.gn | 14 + .../unittest/bms_bundle_updater_test/BUILD.gn | 14 + .../test/unittest/bms_data_mgr_test/BUILD.gn | 15 + .../bms_service_bundle_scan_test/BUILD.gn | 15 + .../bms_service_startup_test/BUILD.gn | 15 + tools/bm/include/bundle_command.h | 38 ++- tools/bm/src/bundle_command.cpp | 294 +++++++++++++++++- tools/zip/BUILD.gn | 2 +- tools/zip/test/BUILD.gn | 2 +- 57 files changed, 2490 insertions(+), 15 deletions(-) create mode 100644 services/bundlemgr/include/aging/aging_bundle_info.h create mode 100644 services/bundlemgr/include/aging/aging_constants.h create mode 100644 services/bundlemgr/include/aging/aging_handler.h create mode 100644 services/bundlemgr/include/aging/aging_handler_chain.h create mode 100644 services/bundlemgr/include/aging/aging_request.h create mode 100644 services/bundlemgr/include/aging/aging_util.h create mode 100644 services/bundlemgr/include/aging/bundle_aging_mgr.h create mode 100644 services/bundlemgr/src/aging/aging_handler_chain.cpp create mode 100644 services/bundlemgr/src/aging/aging_request.cpp create mode 100644 services/bundlemgr/src/aging/aging_util.cpp create mode 100644 services/bundlemgr/src/aging/bundle_aging_mgr.cpp create mode 100644 services/bundlemgr/src/aging/bundle_data_size_aging_handler.cpp create mode 100644 services/bundlemgr/src/aging/over_10days_unused_bundle_aging_handler.cpp create mode 100644 services/bundlemgr/src/aging/over_20days_unused_bundle_aging_handler.cpp create mode 100644 services/bundlemgr/src/aging/over_30days_unused_bundle_aging_handler.cpp create mode 100644 services/bundlemgr/src/aging/recently_unused_bundle_aging_handler.cpp diff --git a/appexecfwk.gni b/appexecfwk.gni index bfdb0f43c..1cf306914 100644 --- a/appexecfwk.gni +++ b/appexecfwk.gni @@ -22,6 +22,7 @@ innerkits_path = "${appexecfwk_path}/interfaces/innerkits" tools_path = "${appexecfwk_path}/tools" declare_args() { bundle_framework_graphics = true + bundle_framework_free_install = true ability_runtime_enable = true account_enable = true @@ -32,11 +33,13 @@ declare_args() { if (defined(global_parts_info) && !defined(global_parts_info.aafwk_ability_runtime)) { ability_runtime_enable = false + bundle_framework_free_install = false } if (defined(global_parts_info) && !defined(global_parts_info.account_os_account_standard)) { account_enable = false + bundle_framework_free_install = false } if (defined(global_parts_info) && @@ -54,7 +57,16 @@ declare_args() { hicollie_enable = false } + if (defined(global_parts_info) && + (!defined(global_parts_info.powermgr_power_manager_native) || + !defined(global_parts_info.powermgr_battery_manager_native) || + !defined(global_parts_info.powermgr_display_manager_native) || + !defined(global_parts_info.aafwk_ability_runtime))) { + bundle_framework_free_install = false + } + print("bundle_framework_graphics = " + "$bundle_framework_graphics") + print("bundle_framework_free_install = " + "$bundle_framework_free_install") print("ability_runtime_enable = " + "$ability_runtime_enable") print("account_enable = " + "$account_enable") print("configpolicy_enable = " + "$configpolicy_enable") diff --git a/common/log/include/app_log_wrapper.h b/common/log/include/app_log_wrapper.h index 081bd2a86..01117d5f8 100644 --- a/common/log/include/app_log_wrapper.h +++ b/common/log/include/app_log_wrapper.h @@ -53,7 +53,7 @@ private: static AppLogLevel level_; }; -#define PRINT_LOG(LEVEL, Level, fmt, ...) \ +#define AFWK_PRINT_LOG(LEVEL, Level, fmt, ...) \ if (OHOS::AppExecFwk::AppLogWrapper::JudgeLevel(OHOS::AppExecFwk::AppLogLevel::LEVEL)) \ OHOS::HiviewDFX::HiLog::Level(OHOS::AppExecFwk::APP_LABEL, \ "[%{public}s(%{public}s):%{public}d] " fmt, \ @@ -62,11 +62,11 @@ private: __LINE__, \ ##__VA_ARGS__) -#define APP_LOGD(fmt, ...) PRINT_LOG(DEBUG, Debug, fmt, ##__VA_ARGS__) -#define APP_LOGI(fmt, ...) PRINT_LOG(INFO, Info, fmt, ##__VA_ARGS__) -#define APP_LOGW(fmt, ...) PRINT_LOG(WARN, Warn, fmt, ##__VA_ARGS__) -#define APP_LOGE(fmt, ...) PRINT_LOG(ERROR, Error, fmt, ##__VA_ARGS__) -#define APP_LOGF(fmt, ...) PRINT_LOG(FATAL, Fatal, fmt, ##__VA_ARGS__) +#define APP_LOGD(fmt, ...) AFWK_PRINT_LOG(DEBUG, Debug, fmt, ##__VA_ARGS__) +#define APP_LOGI(fmt, ...) AFWK_PRINT_LOG(INFO, Info, fmt, ##__VA_ARGS__) +#define APP_LOGW(fmt, ...) AFWK_PRINT_LOG(WARN, Warn, fmt, ##__VA_ARGS__) +#define APP_LOGE(fmt, ...) AFWK_PRINT_LOG(ERROR, Error, fmt, ##__VA_ARGS__) +#define APP_LOGF(fmt, ...) AFWK_PRINT_LOG(FATAL, Fatal, fmt, ##__VA_ARGS__) } // namespace AppExecFwk } // namespace OHOS #endif // FOUNDATION_APPEXECFWK_STANDARD_COMMON_LOG_INCLUDE_APP_LOG_WRAPPER_H diff --git a/interfaces/innerkits/appexecfwk_base/include/application_info.h b/interfaces/innerkits/appexecfwk_base/include/application_info.h index 265a3f0d6..bffb2ee54 100644 --- a/interfaces/innerkits/appexecfwk_base/include/application_info.h +++ b/interfaces/innerkits/appexecfwk_base/include/application_info.h @@ -120,6 +120,7 @@ struct ApplicationInfo : public Parcelable { bool isSystemApp = false; bool isLauncherApp = false; + bool isFreeInstallApp = false; std::string codePath; std::string dataDir; diff --git a/interfaces/innerkits/appexecfwk_base/include/hap_module_info.h b/interfaces/innerkits/appexecfwk_base/include/hap_module_info.h index da9e9253a..e89710f30 100644 --- a/interfaces/innerkits/appexecfwk_base/include/hap_module_info.h +++ b/interfaces/innerkits/appexecfwk_base/include/hap_module_info.h @@ -69,6 +69,7 @@ struct HapModuleInfo : public Parcelable { bool installationFree = false; bool isModuleJson = false; bool isStageBasedModel = false; + bool isRemovable = false; ModuleType moduleType = ModuleType::UNKNOWN; std::vector extensionInfos; std::vector metadata; diff --git a/interfaces/innerkits/appexecfwk_base/src/application_info.cpp b/interfaces/innerkits/appexecfwk_base/src/application_info.cpp index ac9d3de74..a5941063c 100644 --- a/interfaces/innerkits/appexecfwk_base/src/application_info.cpp +++ b/interfaces/innerkits/appexecfwk_base/src/application_info.cpp @@ -51,6 +51,7 @@ const std::string APPLICATION_SINGLETON = "singleton"; const std::string APPLICATION_USER_DATA_CLEARABLE = "userDataClearable"; const std::string APPLICATION_IS_SYSTEM_APP = "isSystemApp"; const std::string APPLICATION_IS_LAUNCHER_APP = "isLauncherApp"; +const std::string APPLICATION_IS_FREEINSTALL_APP = "isFreeInstallApp"; const std::string APPLICATION_CODE_PATH = "codePath"; const std::string APPLICATION_DATA_DIR = "dataDir"; const std::string APPLICATION_DATA_BASE_DIR = "dataBaseDir"; @@ -276,6 +277,7 @@ void to_json(nlohmann::json &jsonObject, const ApplicationInfo &applicationInfo) {APPLICATION_ACCESSIBLE, applicationInfo.accessible}, {APPLICATION_IS_SYSTEM_APP, applicationInfo.isSystemApp}, {APPLICATION_IS_LAUNCHER_APP, applicationInfo.isLauncherApp}, + {APPLICATION_IS_FREEINSTALL_APP, applicationInfo.isFreeInstallApp}, {APPLICATION_CODE_PATH, applicationInfo.codePath}, {APPLICATION_DATA_DIR, applicationInfo.dataDir}, {APPLICATION_DATA_BASE_DIR, applicationInfo.dataBaseDir}, @@ -474,6 +476,14 @@ void from_json(const nlohmann::json &jsonObject, ApplicationInfo &applicationInf false, parseResult, ArrayType::NOT_ARRAY); + GetValueIfFindKey(jsonObject, + jsonObjectEnd, + APPLICATION_IS_FREEINSTALL_APP, + applicationInfo.isFreeInstallApp, + JsonType::BOOLEAN, + false, + parseResult, + ArrayType::NOT_ARRAY); GetValueIfFindKey(jsonObject, jsonObjectEnd, APPLICATION_CODE_PATH, diff --git a/interfaces/innerkits/appexecfwk_base/src/hap_module_info.cpp b/interfaces/innerkits/appexecfwk_base/src/hap_module_info.cpp index 92597ea1e..009a4840d 100644 --- a/interfaces/innerkits/appexecfwk_base/src/hap_module_info.cpp +++ b/interfaces/innerkits/appexecfwk_base/src/hap_module_info.cpp @@ -51,6 +51,7 @@ const std::string HAP_MODULE_INFO_DELIVERY_WITH_INSTALL = "deliveryWithInstall"; const std::string HAP_MODULE_INFO_INSTALLATION_FREE = "installationFree"; const std::string HAP_MODULE_INFO_IS_MODULE_JSON = "isModuleJson"; const std::string HAP_MODULE_INFO_IS_STAGE_BASED_MODEL = "isStageBasedModel"; +const std::string HAP_MODULE_INFO_IS_REMOVABLE = "isRemovable"; const std::string HAP_MODULE_INFO_MODULE_TYPE = "moduleType"; const std::string HAP_MODULE_INFO_EXTENSION_INFOS = "extensionInfos"; const std::string HAP_MODULE_INFO_META_DATA = "metadata"; @@ -144,6 +145,7 @@ void to_json(nlohmann::json &jsonObject, const HapModuleInfo &hapModuleInfo) {HAP_MODULE_INFO_INSTALLATION_FREE, hapModuleInfo.installationFree}, {HAP_MODULE_INFO_IS_MODULE_JSON, hapModuleInfo.isModuleJson}, {HAP_MODULE_INFO_IS_STAGE_BASED_MODEL, hapModuleInfo.isStageBasedModel}, + {HAP_MODULE_INFO_IS_REMOVABLE, hapModuleInfo.isRemovable}, {HAP_MODULE_INFO_MODULE_TYPE, hapModuleInfo.moduleType}, {HAP_MODULE_INFO_EXTENSION_INFOS, hapModuleInfo.extensionInfos}, {HAP_MODULE_INFO_META_DATA, hapModuleInfo.metadata}, @@ -371,6 +373,14 @@ void from_json(const nlohmann::json &jsonObject, HapModuleInfo &hapModuleInfo) false, parseResult, ArrayType::NOT_ARRAY); + GetValueIfFindKey(jsonObject, + jsonObjectEnd, + HAP_MODULE_INFO_IS_REMOVABLE, + hapModuleInfo.isRemovable, + JsonType::BOOLEAN, + false, + parseResult, + ArrayType::NOT_ARRAY); GetValueIfFindKey(jsonObject, jsonObjectEnd, HAP_MODULE_INFO_MODULE_TYPE, diff --git a/interfaces/innerkits/appexecfwk_core/include/bundlemgr/bundle_mgr_host.h b/interfaces/innerkits/appexecfwk_core/include/bundlemgr/bundle_mgr_host.h index 5aea61518..e7001ea22 100644 --- a/interfaces/innerkits/appexecfwk_core/include/bundlemgr/bundle_mgr_host.h +++ b/interfaces/innerkits/appexecfwk_core/include/bundlemgr/bundle_mgr_host.h @@ -545,6 +545,21 @@ private: #endif ErrCode HandleGetAbilityInfo(Parcel &data, Parcel &reply); + /** + * @brief Handles the HandleIsModuleRemovable function called from a IBundleMgr proxy object. + * @param data Indicates the data to be read. + * @param reply Indicates the reply to be sent; + * @return Returns ERR_OK if called successfully; returns error code otherwise. + */ + ErrCode HandleIsModuleRemovable(Parcel &data, Parcel &reply); + /** + * @brief Handles the HandleSetModuleRemovable function called from a IBundleMgr proxy object. + * @param data Indicates the data to be read. + * @param reply Indicates the reply to be sent; + * @return Returns ERR_OK if called successfully; returns error code otherwise. + */ + ErrCode HandleSetModuleRemovable(Parcel &data, Parcel &reply); + ErrCode HandleImplicitQueryInfoByPriority(Parcel &data, Parcel &reply); ErrCode HandleGetAllDependentModuleNames(Parcel &data, Parcel &reply); diff --git a/interfaces/innerkits/appexecfwk_core/include/bundlemgr/bundle_mgr_interface.h b/interfaces/innerkits/appexecfwk_core/include/bundlemgr/bundle_mgr_interface.h index 222657c42..fdc104673 100644 --- a/interfaces/innerkits/appexecfwk_core/include/bundlemgr/bundle_mgr_interface.h +++ b/interfaces/innerkits/appexecfwk_core/include/bundlemgr/bundle_mgr_interface.h @@ -910,6 +910,29 @@ public: { return false; } + /** + * @brief Obtains the value of isRemovable based on a given bundle name and module name. + * @param bundleName Indicates the bundle name to be queried. + * @param moduleName Indicates the module name to be queried. + * @return Returns true if the isRemovable is successfully obtained; returns false otherwise. + */ + virtual bool IsModuleRemovable(const std::string &bundleName, const std::string &moduleName) + { + return false; + } + /** + * @brief Sets whether to enable isRemovable based on a given bundle name and module name. + * @param bundleName Indicates the bundle name to be queried. + * @param moduleName Indicates the module name to be queried. + * @param isEnable Specifies whether to enable the isRemovable of InnerModuleInfo. + * The value true means to enable it, and the value false means to disable it + * @return Returns true if the isRemovable is successfully obtained; returns false otherwise. + */ + virtual bool SetModuleRemovable( + const std::string &bundleName, const std::string &moduleName, bool isEnable) + { + return false; + } /** * @brief Obtains the dependent module names. @@ -1004,6 +1027,8 @@ public: VERIFY_CALLING_PERMISSION, GET_ACCESSIBLE_APP_CODE_PATH, QUERY_EXTENSION_ABILITY_INFO_BY_URI, + IS_MODULE_REMOVABLE, + SET_MODULE_REMOVABLE, GET_HAP_MODULE_INFO_WITH_USERID, IMPLICIT_QUERY_INFO_BY_PRIORITY, GET_ALL_DEPENDENT_MODULE_NAMES, diff --git a/interfaces/innerkits/appexecfwk_core/include/bundlemgr/bundle_mgr_proxy.h b/interfaces/innerkits/appexecfwk_core/include/bundlemgr/bundle_mgr_proxy.h index 2fd9cb3b4..e0237d81f 100644 --- a/interfaces/innerkits/appexecfwk_core/include/bundlemgr/bundle_mgr_proxy.h +++ b/interfaces/innerkits/appexecfwk_core/include/bundlemgr/bundle_mgr_proxy.h @@ -651,6 +651,24 @@ public: virtual bool GetAbilityInfo( const std::string &bundleName, const std::string &abilityName, AbilityInfo &abilityInfo) override; + /** + * @brief Obtains the value of isRemovable based on a given bundle name through the proxy object. + * @param bundleName Indicates the bundle name to be queried. + * @param moduleName Indicates the module name to be queried. + * @return Returns true if the isRemovable is successfully obtained; returns false otherwise. + */ + virtual bool IsModuleRemovable(const std::string &bundleName, const std::string &moduleName) override; + /** + * @brief Sets whether to enable isRemovable based on a given bundle name through the proxy object. + * @param bundleName Indicates the bundle name to be queried. + * @param moduleName Indicates the module name to be queried. + * @param isEnable Specifies whether to enable the isRemovable of InnerModuleInfo. + * The value true means to enable it, and the value false means to disable it + * @return Returns true if the isRemovable is successfully obtained; returns false otherwise. + */ + virtual bool SetModuleRemovable( + const std::string &bundleName, const std::string &moduleName, bool isEnable) override; + /** * @brief Obtains the dependent module names. * diff --git a/interfaces/innerkits/appexecfwk_core/src/bundlemgr/bundle_mgr_host.cpp b/interfaces/innerkits/appexecfwk_core/src/bundlemgr/bundle_mgr_host.cpp index 5ce7f7753..97f8e72be 100644 --- a/interfaces/innerkits/appexecfwk_core/src/bundlemgr/bundle_mgr_host.cpp +++ b/interfaces/innerkits/appexecfwk_core/src/bundlemgr/bundle_mgr_host.cpp @@ -301,6 +301,11 @@ int BundleMgrHost::OnRemoteRequest(uint32_t code, MessageParcel &data, MessagePa case static_cast(IBundleMgr::Message::GET_UID_BY_BUNDLE_NAME): errCode = HandleGetUidByBundleName(data, reply); break; + case static_cast(IBundleMgr::Message::IS_MODULE_REMOVABLE): + errCode = HandleIsModuleRemovable(data, reply); + break; + case static_cast(IBundleMgr::Message::SET_MODULE_REMOVABLE): + errCode = HandleSetModuleRemovable(data, reply); case static_cast(IBundleMgr::Message::GET_HAP_MODULE_INFO_WITH_USERID): errCode = HandleGetHapModuleInfoWithUserId(data, reply); break; @@ -1820,6 +1825,36 @@ ErrCode BundleMgrHost::HandleGetUidByBundleName(Parcel &data, Parcel &reply) return ERR_OK; } +ErrCode BundleMgrHost::HandleIsModuleRemovable(Parcel &data, Parcel &reply) +{ + BYTRACE_NAME(BYTRACE_TAG_APP, __PRETTY_FUNCTION__); + std::string bundleName = data.ReadString(); + std::string moduleName = data.ReadString(); + + APP_LOGD("bundleName %{public}s, moduleName %{public}s", bundleName.c_str(), moduleName.c_str()); + bool ret = IsModuleRemovable(bundleName, moduleName); + if (!reply.WriteBool(ret)) { + APP_LOGE("write failed"); + return ERR_APPEXECFWK_PARCEL_ERROR; + } + return ERR_OK; +} + +ErrCode BundleMgrHost::HandleSetModuleRemovable(Parcel &data, Parcel &reply) +{ + BYTRACE_NAME(BYTRACE_TAG_APP, __PRETTY_FUNCTION__); + std::string bundleName = data.ReadString(); + std::string moduleName = data.ReadString(); + bool isEnable = data.ReadBool(); + APP_LOGD("bundleName %{public}s, moduleName %{public}s", bundleName.c_str(), moduleName.c_str()); + bool ret = SetModuleRemovable(bundleName, moduleName, isEnable); + if (!reply.WriteBool(ret)) { + APP_LOGE("write failed"); + return ERR_APPEXECFWK_PARCEL_ERROR; + } + return ERR_OK; +} + ErrCode BundleMgrHost::HandleImplicitQueryInfoByPriority(Parcel &data, Parcel &reply) { BYTRACE_NAME(BYTRACE_TAG_APP, __PRETTY_FUNCTION__); diff --git a/interfaces/innerkits/appexecfwk_core/src/bundlemgr/bundle_mgr_proxy.cpp b/interfaces/innerkits/appexecfwk_core/src/bundlemgr/bundle_mgr_proxy.cpp index e061a8894..e545cb5d7 100644 --- a/interfaces/innerkits/appexecfwk_core/src/bundlemgr/bundle_mgr_proxy.cpp +++ b/interfaces/innerkits/appexecfwk_core/src/bundlemgr/bundle_mgr_proxy.cpp @@ -1455,6 +1455,72 @@ bool BundleMgrProxy::IsApplicationEnabled(const std::string &bundleName) return reply.ReadBool(); } +bool BundleMgrProxy::IsModuleRemovable(const std::string &bundleName, const std::string &moduleName) +{ + BYTRACE_NAME(BYTRACE_TAG_APP, __PRETTY_FUNCTION__); + APP_LOGI("begin to IsModuleRemovable of %{public}s", bundleName.c_str()); + if (bundleName.empty() || moduleName.empty()) { + APP_LOGE("fail to IsModuleRemovable due to params empty"); + return false; + } + + MessageParcel data; + if (!data.WriteInterfaceToken(GetDescriptor())) { + APP_LOGE("fail to IsModuleRemovable due to write InterfaceToken fail"); + return false; + } + if (!data.WriteString(bundleName)) { + APP_LOGE("fail to IsModuleRemovable due to write bundleName fail"); + return false; + } + + if (!data.WriteString(moduleName)) { + APP_LOGE("fail to IsModuleRemovable due to write moduleName fail"); + return false; + } + MessageParcel reply; + if (!SendTransactCmd(IBundleMgr::Message::IS_MODULE_REMOVABLE, data, reply)) { + APP_LOGE("fail to IsModuleRemovable from server"); + return false; + } + return reply.ReadBool(); +} + +bool BundleMgrProxy::SetModuleRemovable(const std::string &bundleName, const std::string &moduleName, bool isEnable) +{ + BYTRACE_NAME(BYTRACE_TAG_APP, __PRETTY_FUNCTION__); + APP_LOGI("begin to SetModuleRemovable of %{public}s", bundleName.c_str()); + if (bundleName.empty() || moduleName.empty()) { + APP_LOGE("fail to SetModuleRemovable due to params empty"); + return false; + } + + MessageParcel data; + if (!data.WriteInterfaceToken(GetDescriptor())) { + APP_LOGE("fail to SetModuleRemovable due to write InterfaceToken fail"); + return false; + } + if (!data.WriteString(bundleName)) { + APP_LOGE("fail to SetModuleRemovable due to write bundleName fail"); + return false; + } + + if (!data.WriteString(moduleName)) { + APP_LOGE("fail to SetModuleRemovable due to write moduleName fail"); + return false; + } + if (!data.WriteBool(isEnable)) { + APP_LOGE("fail to SetModuleRemovable due to write isEnable fail"); + return false; + } + MessageParcel reply; + if (!SendTransactCmd(IBundleMgr::Message::SET_MODULE_REMOVABLE, data, reply)) { + APP_LOGE("fail to SetModuleRemovable from server"); + return false; + } + return reply.ReadBool(); +} + bool BundleMgrProxy::SetApplicationEnabled(const std::string &bundleName, bool isEnable, int32_t userId) { BYTRACE_NAME(BYTRACE_TAG_APP, __PRETTY_FUNCTION__); diff --git a/kits/appkit/napi/bundlemgr/bundle_mgr.cpp b/kits/appkit/napi/bundlemgr/bundle_mgr.cpp index 4a2d06cce..59e8a3818 100644 --- a/kits/appkit/napi/bundlemgr/bundle_mgr.cpp +++ b/kits/appkit/napi/bundlemgr/bundle_mgr.cpp @@ -2425,7 +2425,11 @@ static void InnerInstall(napi_env env, const std::vector &bundleFil APP_LOGE("can not get iBundleInstaller"); return; } - installParam.installFlag = InstallFlag::REPLACE_EXISTING; + + if (installParam.installFlag == InstallFlag::NORMAL) { + installParam.installFlag = InstallFlag::REPLACE_EXISTING; + } + OHOS::sptr callback = new (std::nothrow) InstallerCallback(); if (!callback) { APP_LOGE("callback nullptr"); @@ -4727,6 +4731,228 @@ napi_value IsApplicationEnabled(napi_env env, napi_callback_info info) return ret; } +static bool InnerIsModuleRemovableExecute(napi_env env, const std::string &bundleName, const std::string &moduleName) +{ + auto iBundleMgr = GetBundleMgr(); + if (iBundleMgr == nullptr) { + APP_LOGE("can not get iBundleMgr"); + return false; + } + auto result = iBundleMgr->IsModuleRemovable(bundleName, moduleName); + if (result) { + APP_LOGI("InnerIsModuleRemovableExecute::IsModuleRemovable"); + } + return result; +} + +void IsModuleRemovableExecute(napi_env env, void *data) +{ + APP_LOGI("NAPI_IsModuleRemovable, worker pool thread execute."); + AsyncModuleRemovableCallbackInfo *asyncCallbackInfo = static_cast(data); + if (asyncCallbackInfo == nullptr) { + APP_LOGE("NAPI_IsModuleRemovable, asyncCallbackInfo == nullptr"); + return; + } + asyncCallbackInfo->result = + InnerIsModuleRemovableExecute(env, asyncCallbackInfo->bundleName, asyncCallbackInfo->moduleName); +} + +void IsModuleRemovableAsyncComplete(napi_env env, napi_status status, void *data) +{ + APP_LOGI("NAPI_IsModuleRemovable, main event thread complete."); + AsyncModuleRemovableCallbackInfo *asyncCallbackInfo = static_cast(data); + napi_value callback = nullptr; + napi_value undefined = nullptr; + napi_value result[ARGS_SIZE_TWO] = {nullptr}; + napi_value callResult = nullptr; + NAPI_CALL_RETURN_VOID(env, napi_get_undefined(env, &undefined)); + if (asyncCallbackInfo->err) { + napi_create_int32(env, asyncCallbackInfo->err, &result[PARAM0]); + } + + if (asyncCallbackInfo->err == NAPI_ERR_NO_ERROR) { + NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, asyncCallbackInfo->result, &result[PARAM1])); + } else { + result[PARAM1] = WrapUndefinedToJS(env); + } + + NAPI_CALL_RETURN_VOID(env, napi_get_reference_value(env, asyncCallbackInfo->callback, &callback)); + NAPI_CALL_RETURN_VOID(env, + napi_call_function(env, undefined, callback, sizeof(result) / sizeof(result[PARAM0]), result, &callResult)); + + if (asyncCallbackInfo->callback != nullptr) { + NAPI_CALL_RETURN_VOID(env, napi_delete_reference(env, asyncCallbackInfo->callback)); + } + NAPI_CALL_RETURN_VOID(env, napi_delete_async_work(env, asyncCallbackInfo->asyncWork)); + delete asyncCallbackInfo; + asyncCallbackInfo = nullptr; + APP_LOGI("NAPI_ModuleRemovable, main event thread complete end."); +} + +void IsModuleRemovablePromiseComplete(napi_env env, napi_status status, void *data) +{ + APP_LOGI("NAPI_IsModuleRemovable, main event thread complete."); + AsyncModuleRemovableCallbackInfo *asyncCallbackInfo = static_cast(data); + napi_value result = nullptr; + if (asyncCallbackInfo->err == NAPI_ERR_NO_ERROR) { + NAPI_CALL_RETURN_VOID(env, napi_get_boolean(env, asyncCallbackInfo->result, &result)); + napi_resolve_deferred(env, asyncCallbackInfo->deferred, result); + } else { + napi_create_int32(env, asyncCallbackInfo->err, &result); + napi_reject_deferred(env, asyncCallbackInfo->deferred, result); + } + + napi_delete_async_work(env, asyncCallbackInfo->asyncWork); + delete asyncCallbackInfo; + asyncCallbackInfo = nullptr; + APP_LOGI("NAPI_IsModuleRemovable, main event thread complete end."); +} + +napi_value IsModuleRemovableAsync( + napi_env env, napi_value *args, const size_t argCallback, AsyncModuleRemovableCallbackInfo *asyncCallbackInfo) +{ + APP_LOGI("%{public}s, asyncCallback.", __func__); + if (args == nullptr || asyncCallbackInfo == nullptr) { + APP_LOGE("%{public}s, param is nullptr.", __func__); + return nullptr; + } + + napi_value resourceName = nullptr; + napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName); + + napi_valuetype valuetype = napi_undefined; + NAPI_CALL(env, napi_typeof(env, args[argCallback], &valuetype)); + if (valuetype == napi_function) { + NAPI_CALL(env, napi_create_reference(env, args[argCallback], NAPI_RETURN_ONE, &asyncCallbackInfo->callback)); + } else { + return nullptr; + } + + NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName, IsModuleRemovableExecute, + IsModuleRemovableAsyncComplete, (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork)); + NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork)); + napi_value result = nullptr; + NAPI_CALL(env, napi_get_null(env, &result)); + APP_LOGI("%{public}s, asyncCallback end.", __func__); + return result; +} + +napi_value IsModuleRemovablePromise(napi_env env, AsyncModuleRemovableCallbackInfo *asyncCallbackInfo) +{ + APP_LOGI("%{public}s, promise.", __func__); + if (asyncCallbackInfo == nullptr) { + APP_LOGE("%{public}s, param is nullptr.", __func__); + return nullptr; + } + napi_value resourceName = nullptr; + NAPI_CALL(env, napi_create_string_latin1(env, __func__, NAPI_AUTO_LENGTH, &resourceName)); + napi_deferred deferred; + napi_value promise = nullptr; + NAPI_CALL(env, napi_create_promise(env, &deferred, &promise)); + asyncCallbackInfo->deferred = deferred; + + NAPI_CALL(env, napi_create_async_work(env, nullptr, resourceName, IsModuleRemovableExecute, + IsModuleRemovablePromiseComplete, (void *)asyncCallbackInfo, &asyncCallbackInfo->asyncWork)); + NAPI_CALL(env, napi_queue_async_work(env, asyncCallbackInfo->asyncWork)); + APP_LOGI("%{public}s, promise end.", __func__); + return promise; +} + +napi_value GetModuleRemovableWrap( + napi_env env, napi_callback_info info, AsyncModuleRemovableCallbackInfo *asyncCallbackInfo) +{ + APP_LOGI("%{public}s, asyncCallback.", __func__); + if (asyncCallbackInfo == nullptr) { + APP_LOGE("%{public}s, asyncCallbackInfo is nullptr.", __func__); + return nullptr; + } + + size_t argcAsync = ARGS_SIZE_THREE; + const size_t argcPromise = ARGS_SIZE_TWO; + const size_t argCountWithAsync = argcPromise + ARGS_ASYNC_COUNT; + napi_value args[ARGS_MAX_COUNT] = {nullptr}; + napi_value ret = nullptr; + + NAPI_CALL(env, napi_get_cb_info(env, info, &argcAsync, args, nullptr, nullptr)); + if (argcAsync > argCountWithAsync || argcAsync > ARGS_MAX_COUNT) { + APP_LOGE("%{public}s, Wrong argument count.", __func__); + return nullptr; + } + + napi_valuetype valueType = napi_undefined; + napi_typeof(env, args[PARAM0], &valueType); + if (valueType == napi_string) { + ParseString(env, asyncCallbackInfo->bundleName, args[PARAM0]); + } else { + asyncCallbackInfo->err = PARAM_TYPE_ERROR; + asyncCallbackInfo->errMssage = "type misMatch"; + } + + napi_valuetype secondValueType = napi_undefined; + napi_typeof(env, args[PARAM1], &secondValueType); + if (secondValueType == napi_string) { + ParseString(env, asyncCallbackInfo->moduleName, args[PARAM1]); + } else { + asyncCallbackInfo->err = PARAM_TYPE_ERROR; + asyncCallbackInfo->errMssage = "type misMatch"; + } + + APP_LOGI("bundleName: %{public}s, moduleName: %{public}s", + asyncCallbackInfo->bundleName.c_str(), asyncCallbackInfo->moduleName.c_str()); + if (asyncCallbackInfo->bundleName.empty() || asyncCallbackInfo->moduleName.empty()) { + asyncCallbackInfo->err = INVALID_PARAM; + asyncCallbackInfo->errMssage = "invalid param"; + } + + if (argcAsync > argcPromise) { + ret = IsModuleRemovableAsync(env, args, argcAsync - 1, asyncCallbackInfo); + } else { + ret = IsModuleRemovablePromise(env, asyncCallbackInfo); + } + APP_LOGI("%{public}s, asyncCallback end.", __func__); + return ret; +} + +AsyncModuleRemovableCallbackInfo *CreateModuleRemovableCallbackInfo(napi_env env) +{ + APP_LOGI("%{public}s called.", __func__); + AsyncModuleRemovableCallbackInfo *asyncCallbackInfo = new AsyncModuleRemovableCallbackInfo { + .env = env, + .asyncWork = nullptr, + .deferred = nullptr, + }; + + if (asyncCallbackInfo == nullptr) { + APP_LOGE("%{public}s, asyncCallbackInfo is nullptr.", __func__); + return nullptr; + } + + APP_LOGI("%{public}s end.", __func__); + return asyncCallbackInfo; +} + +napi_value IsModuleRemovable(napi_env env, napi_callback_info info) +{ + APP_LOGI("NAPI_IsModuleRemovable start"); + AsyncModuleRemovableCallbackInfo *asyncCallbackInfo = CreateModuleRemovableCallbackInfo(env); + if (asyncCallbackInfo == nullptr) { + return WrapVoidToJS(env); + } + + napi_value ret = GetModuleRemovableWrap(env, info, asyncCallbackInfo); + + if (ret == nullptr) { + APP_LOGE("%{public}s ret is nullptr", __func__); + if (asyncCallbackInfo != nullptr) { + delete asyncCallbackInfo; + asyncCallbackInfo = nullptr; + } + ret = WrapVoidToJS(env); + } + APP_LOGI("%{public}s end.", __func__); + return ret; +} + AsyncAbilityLabelCallbackInfo *CreateAbilityLabelCallbackInfo(napi_env env) { APP_LOGI("%{public}s called.", __func__); diff --git a/kits/appkit/napi/bundlemgr/bundle_mgr.h b/kits/appkit/napi/bundlemgr/bundle_mgr.h index 2a51d12a4..a07361487 100644 --- a/kits/appkit/napi/bundlemgr/bundle_mgr.h +++ b/kits/appkit/napi/bundlemgr/bundle_mgr.h @@ -130,6 +130,18 @@ struct AsyncAbilityLabelCallbackInfo : public AsyncWorkData { std::string message; }; +struct AsyncModuleRemovableCallbackInfo { + napi_env env; + napi_async_work asyncWork; + napi_deferred deferred; + napi_ref callback = 0; + std::string bundleName; + std::string moduleName; + bool result = false; + int32_t err = 0; + std::string errMssage; +}; + struct InstallResult { std::string resultMsg; int32_t resultCode = 0; @@ -298,6 +310,7 @@ napi_value GetAbilityIcon(napi_env env, napi_callback_info info); napi_value GetBundleGids(napi_env env, napi_callback_info info); napi_value IsAbilityEnabled(napi_env env, napi_callback_info info); napi_value IsApplicationEnabled(napi_env env, napi_callback_info info); +napi_value IsModuleRemovable(napi_env env, napi_callback_info info); bool UnwrapAbilityInfo(napi_env env, napi_value param, OHOS::AppExecFwk::AbilityInfo& abilityInfo); void CreateAbilityTypeObject(napi_env env, napi_value value); void CreateAbilitySubTypeObject(napi_env env, napi_value value); diff --git a/kits/appkit/napi/bundlemgr/native_module.cpp b/kits/appkit/napi/bundlemgr/native_module.cpp index fc8f43552..b4983934f 100644 --- a/kits/appkit/napi/bundlemgr/native_module.cpp +++ b/kits/appkit/napi/bundlemgr/native_module.cpp @@ -119,6 +119,7 @@ static napi_value Init(napi_env env, napi_value exports) DECLARE_NAPI_FUNCTION("setAbilityEnabled", SetAbilityEnabled), DECLARE_NAPI_FUNCTION("isAbilityEnabled", IsAbilityEnabled), DECLARE_NAPI_FUNCTION("isApplicationEnabled", IsApplicationEnabled), + DECLARE_NAPI_FUNCTION("isModuleRemovable", IsModuleRemovable), DECLARE_NAPI_FUNCTION("getAppPrivilegeLevel", GetAppPrivilegeLevel), DECLARE_NAPI_FUNCTION("queryExtensionAbilityInfosByWant", QueryExtensionInfoByWant), DECLARE_NAPI_FUNCTION("getNameForUid", GetNameForUid), diff --git a/services/bundlemgr/BUILD.gn b/services/bundlemgr/BUILD.gn index 4cfec2d54..b1f29e323 100644 --- a/services/bundlemgr/BUILD.gn +++ b/services/bundlemgr/BUILD.gn @@ -22,6 +22,10 @@ config("bundlemgr_common_config") { "//utils/system/safwk/native/include", ] + if (bundle_framework_free_install) { + include_dirs += [ "//base/sensors/sensor/interfaces/native/include" ] + } + defines = [ "APP_LOG_TAG = \"BundleMgrService\"", "LOG_DOMAIN = 0xD001120", @@ -194,6 +198,21 @@ ohos_shared_library("libbms") { defines += [ "ACCOUNT_ENABLE" ] } + if (bundle_framework_free_install) { + sources += aging + sources += [ "src/installd/installd_operator.cpp" ] + deps += [ "${aafwk_path}/frameworks/kits/appkit:appkit_native" ] + external_deps += [ + "ability_runtime:ability_manager", + "ability_runtime:app_manager", + "battery_manager_native:batterysrv_client", + "device_usage_statistics:usagestatsinner", + "display_manager_native:displaymgr", + "power_manager_native:powermgr_client", + ] + defines += [ "BUNDLE_FRAMEWORK_FREE_INSTALL" ] + } + if (configpolicy_enable) { external_deps += [ "config_policy:configpolicy_util" ] defines += [ "CONFIG_POLOCY_ENABLE" ] diff --git a/services/bundlemgr/appexecfwk_bundlemgr.gni b/services/bundlemgr/appexecfwk_bundlemgr.gni index c2042896c..c62913eb0 100644 --- a/services/bundlemgr/appexecfwk_bundlemgr.gni +++ b/services/bundlemgr/appexecfwk_bundlemgr.gni @@ -43,6 +43,18 @@ bundle_install_sources = [ "${services_path}/bundlemgr/src/xcollie_helper.cpp", ] +aging = [ + "${services_path}/bundlemgr/src/aging/aging_handler_chain.cpp", + "${services_path}/bundlemgr/src/aging/aging_request.cpp", + "${services_path}/bundlemgr/src/aging/aging_util.cpp", + "${services_path}/bundlemgr/src/aging/bundle_aging_mgr.cpp", + "${services_path}/bundlemgr/src/aging/bundle_data_size_aging_handler.cpp", + "${services_path}/bundlemgr/src/aging/over_10days_unused_bundle_aging_handler.cpp", + "${services_path}/bundlemgr/src/aging/over_20days_unused_bundle_aging_handler.cpp", + "${services_path}/bundlemgr/src/aging/over_30days_unused_bundle_aging_handler.cpp", + "${services_path}/bundlemgr/src/aging/recently_unused_bundle_aging_handler.cpp", +] + bundle_install_deps = [ "${services_path}/bundlemgr:bundle_parser", "${services_path}/bundlemgr:parser_common", diff --git a/services/bundlemgr/include/aging/aging_bundle_info.h b/services/bundlemgr/include/aging/aging_bundle_info.h new file mode 100644 index 000000000..4b9e075f0 --- /dev/null +++ b/services/bundlemgr/include/aging/aging_bundle_info.h @@ -0,0 +1,61 @@ +/* + * 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. + */ + +#ifndef FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_AGING_BUNDLE_INFO_H +#define FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_AGING_BUNDLE_INFO_H + +#include +#include + +namespace OHOS { +namespace AppExecFwk { +class AgingBundleInfo { +public: + AgingBundleInfo() = default; + AgingBundleInfo(const std::string &name, int64_t time, int64_t bundleDataBytes, int uid) + : bundleName(name), recentlyUsedTime(time), dataBytes(bundleDataBytes), bundleUid(uid) + { + }; + virtual ~AgingBundleInfo() = default; + + const std::string &GetBundleName() const + { + return bundleName; + }; + + int64_t GetRecentlyUsedTime() const + { + return recentlyUsedTime; + }; + + int64_t GetDataBytes() const + { + return dataBytes; + }; + + int GetBundleUid() const + { + return bundleUid; + }; + +private: + std::string bundleName; + int64_t recentlyUsedTime = 0; + int64_t dataBytes = 0; + int bundleUid = -1; +}; +} // namespace AppExecFwk +} // namespace OHOS +#endif // FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_AGING_BUNDLE_INFO_H \ No newline at end of file diff --git a/services/bundlemgr/include/aging/aging_constants.h b/services/bundlemgr/include/aging/aging_constants.h new file mode 100644 index 000000000..c469844a0 --- /dev/null +++ b/services/bundlemgr/include/aging/aging_constants.h @@ -0,0 +1,52 @@ +/* + * 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. + */ + +#ifndef FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_AGING_CONSTANTS_H +#define FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_AGING_CONSTANTS_H + +#include + +namespace OHOS { +namespace AppExecFwk { +namespace AgingConstants { +const std::string SYSTEM_PARAM_DATA_SIZE_THRESHOLD = "persist.sys.bms.aging.policy.data.size.threshold"; +const std::string SYSTEM_PARAM_RECENILY_USED_THRESHOLD = "persist.sys.bms.aging.policy.recently.used.threshold"; +const std::string SYSTEM_PARAM_AGING_TIMER_INTERVAL = "persist.sys.bms.aging.policy.timer.interval"; +const std::string SYSTEM_PARAM_AGING_BATTER_THRESHOLD = "persist.sys.bms.aging.policy.battery.threshold"; +const int64_t ONE_MS = 1000; +const float AGING_SIZE_RATIO = 0.8F; +const int64_t ONE_HOUR_MS = (int64_t)60 * 60 * ONE_MS; +const int64_t DEFAULT_AGING_TIMER_INTERVAL = (int64_t)8 * ONE_HOUR_MS; +const int64_t ONE_DAYS_MS = (int64_t)24 * ONE_HOUR_MS; +const int64_t ONE_KB = (int64_t)1024; +const int64_t ONE_MB = (int64_t)1024 * ONE_KB; +const int64_t DEFAULT_AGING_DATA_SIZE_THRESHOLD = (int64_t)500 * ONE_MB; +const int64_t DEFAULT_AGING_BATTERY_THRESHOLD = (int64_t)10; +const int64_t THRESHOLD_VAL_LEN = 20; +const int32_t TIME_30_DAYS = 30; +const int32_t TIME_20_DAYS = 20; +const int32_t TIME_10_DAYS = 10; +const int32_t COUNT_MODULE_RECODES_GET = 0x7FFFFFFF; + +const std::string AGING_THREAD = "aging_thread"; + +const std::string UNUSED_FOR_30_DAYS_BUNDLE_AGING_HANDLER = "UnusedFor30DaysBundleAgingHandler"; +const std::string UNUSED_FOR_20_DAYS_BUNDLE_AGING_HANDLER = "UnusedFor20DaysBundleAgingHandler"; +const std::string UNUSED_FOR_10_DAYS_BUNDLE_AGING_HANDLER = "UnusedFor10DaysBundleAgingHandler"; +const std::string BUNDLE_DATA_SIZE_AGING_HANDLER = "BundleDataSizeAgingHandler"; +} // namespace AgingConstants +} // namespace AppExecFwk +} // namespace OHOS +#endif // FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_AGING_CONSTANTS_H diff --git a/services/bundlemgr/include/aging/aging_handler.h b/services/bundlemgr/include/aging/aging_handler.h new file mode 100644 index 000000000..0a7cc738d --- /dev/null +++ b/services/bundlemgr/include/aging/aging_handler.h @@ -0,0 +1,88 @@ +/* + * 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. + */ + +#ifndef FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_AGING_HANDLER_H +#define FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_AGING_HANDLER_H + +#include +#include +#include + +#include "aging_request.h" +#include "bundle_util.h" +#include "status_receiver_host.h" + +namespace OHOS { +namespace AppExecFwk { +class AgingHandler { +public: + AgingHandler() = default; + virtual ~AgingHandler() = default; + virtual bool Process(AgingRequest &request) const = 0; + virtual const std::string &GetName() const = 0; +}; + +class RecentlyUnuseBundleAgingHandler : public AgingHandler { +public: + RecentlyUnuseBundleAgingHandler() = default; + virtual ~RecentlyUnuseBundleAgingHandler() = default; + virtual bool Process(AgingRequest &request) const override; + virtual bool CheckBundle(const AgingBundleInfo &bundle) const = 0; + virtual bool NeedContinue(const AgingRequest &requese) const; + virtual bool isRunning(const std::string bundleName, const int bundleuid) const; + +private: + bool UnInstallBundle(const std::string &bundlename) const; + bool IsBundleRunning(const std::string &bundlename) const; +}; + +class Over30DaysUnusedBundleAgingHandler : public RecentlyUnuseBundleAgingHandler { +public: + bool CheckBundle(const AgingBundleInfo &bundle) const override; + const std::string &GetName() const override; +}; + +class Over20DaysUnusedBundleAgingHandler : public RecentlyUnuseBundleAgingHandler { +public: + bool CheckBundle(const AgingBundleInfo &bundle) const override; + const std::string &GetName() const override; +}; + +class Over10DaysUnusedBundleAgingHandler : public RecentlyUnuseBundleAgingHandler { +public: + bool CheckBundle(const AgingBundleInfo &bundle) const override; + const std::string &GetName() const override; +}; + +class BundleDataSizeAgingHandler : public RecentlyUnuseBundleAgingHandler { +public: + bool CheckBundle(const AgingBundleInfo &bundle) const override; + const std::string &GetName() const override; +}; + +class AgingUninstallReceiveImpl : public StatusReceiverHost { +public: + AgingUninstallReceiveImpl() = default; + virtual ~AgingUninstallReceiveImpl() override = default; + virtual void OnStatusNotify(const int progress) override + { + } + virtual void OnFinished(const int32_t resultCode, const std::string &resultMsg) override + { + } +}; +} // namespace AppExecFwk +} // namespace OHOS +#endif // FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_AGING_HANDLER_H diff --git a/services/bundlemgr/include/aging/aging_handler_chain.h b/services/bundlemgr/include/aging/aging_handler_chain.h new file mode 100644 index 000000000..292b68ee5 --- /dev/null +++ b/services/bundlemgr/include/aging/aging_handler_chain.h @@ -0,0 +1,39 @@ +/* + * 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. + */ + +#ifndef FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_AGING_HANDLER_CHAIN_H +#define FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_AGING_HANDLER_CHAIN_H + +#include +#include + +#include "aging_handler.h" +#include "aging_request.h" + +namespace OHOS { +namespace AppExecFwk { +class AgingHandlerChain { +public: + AgingHandlerChain(); + ~AgingHandlerChain(); + void AddHandler(const std::shared_ptr &handler); + bool Process(AgingRequest &request) const; + +private: + std::vector> handlers; +}; +} // namespace AppExecFwk +} // namespace OHOS +#endif // FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_AGING_HANDLER_CHAIN_H \ No newline at end of file diff --git a/services/bundlemgr/include/aging/aging_request.h b/services/bundlemgr/include/aging/aging_request.h new file mode 100644 index 000000000..d75c87bf8 --- /dev/null +++ b/services/bundlemgr/include/aging/aging_request.h @@ -0,0 +1,77 @@ +/* + * 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. + */ + +#ifndef FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_AGING_REQUEST_H +#define FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_AGING_REQUEST_H + +#include + +#include "aging_bundle_info.h" +#include "aging_util.h" + +namespace OHOS { +namespace AppExecFwk { +class AgingRequest { +public: + AgingRequest(); + bool IsReachStartAgingThreshold() const; + bool IsReachEndAgingThreshold() const; + const std::vector &GetAgingBundles() const + { + return agingBundles; + }; + void AddAgingBundle(AgingBundleInfo &bundleInfo); + size_t SortAgingBundles() + { + AgingUtil::SortAgingBundles(agingBundles); + return agingBundles.size(); + }; + void UpdateTotalDataBytesAfterUninstalled(const int64_t dataBytes) + { + tatalDataBytes -= dataBytes; + }; + int64_t GetTotalDataBytes() const + { + return tatalDataBytes; + }; + void SetTotalDataBytes(const int64_t allBundleDataBytes) + { + tatalDataBytes = allBundleDataBytes; + }; + void reset(); + +public: + static int64_t GetTotalDataBytesThreshold() + { + return totalDataBytesThreshold; + }; + static int64_t GetOneDayTimeMs() + { + return oneDayTimeMs; + }; + +private: + void InitAgingPolicySystemParameters(); + std::vector agingBundles; + int64_t tatalDataBytes = 0; + +private: + static int64_t totalDataBytesThreshold; + static int64_t oneDayTimeMs; +}; +} // namespace AppExecFwk +} // namespace OHOS + +#endif // FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_AGING_REQUEST_H diff --git a/services/bundlemgr/include/aging/aging_util.h b/services/bundlemgr/include/aging/aging_util.h new file mode 100644 index 000000000..22a633d0e --- /dev/null +++ b/services/bundlemgr/include/aging/aging_util.h @@ -0,0 +1,37 @@ +/* + * 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. + */ +#ifndef FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_AGING_UTIL_H +#define FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_AGING_UTIL_H + +#include + +#include "aging/aging_bundle_info.h" +#include "bundle_util.h" + +namespace OHOS { +namespace AppExecFwk { +class AgingUtil { +public: + static inline int64_t GetNowSysTimeMs() + { + return BundleUtil::GetCurrentTime(); + } + static void SortAgingBundles(std::vector &bundles); + static bool SortTwoAgingBundleinfos(AgingBundleInfo &bundle1, AgingBundleInfo &bundle2); + static int64_t GetUnusedTimeMsBaseOnCurrentTime(int64_t currentTimeMs, int32_t days); +}; +} // namespace AppExecFwk +} // namespace OHOS +#endif // FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_AGING_UTIL_H diff --git a/services/bundlemgr/include/aging/bundle_aging_mgr.h b/services/bundlemgr/include/aging/bundle_aging_mgr.h new file mode 100644 index 000000000..bea0294eb --- /dev/null +++ b/services/bundlemgr/include/aging/bundle_aging_mgr.h @@ -0,0 +1,68 @@ +/* + * 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. + */ +#ifndef FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_BUNDLE_AGING_MGR_H +#define FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_BUNDLE_AGING_MGR_H + +#include +#include +#include + +#include "aging/aging_constants.h" +#include "aging/aging_handler_chain.h" +#include "aging/aging_request.h" +#include "bundle_data_mgr.h" +#include "event_handler.h" +#include "singleton.h" + +namespace OHOS { +namespace AppExecFwk { +class BundleAgingMgr : public EventHandler { +public: + enum AgingTriggertype { + PREIOD = 0, + FREE_INSTALL = 1, + UPDATE_REMOVABLE_FLAG = 2, + }; + +public: + BundleAgingMgr(); + ~BundleAgingMgr(); + +public: + void Start(AgingTriggertype type); + void InitAgingtTimer(); + void InitAgingRunner(); + +private: + void InitAgingHandlerChain(); + void Process(const std::shared_ptr &dataMgr); + void ProcessEvent(const InnerEvent::Pointer &event) override; + bool CheckPrerequisite(AgingTriggertype type) const; + bool ReInitAgingRequest(const std::shared_ptr &dataMgr); + +private: + std::mutex mutex_; + bool running = false; + AgingHandlerChain chain; + AgingRequest request; + int64_t agingTimerInterval = 0; + int64_t agingBatteryThresold = 0; + +private: + static const uint32_t EVENT_AGING_NOW = 1; +}; +} // namespace AppExecFwk +} // namespace OHOS +#endif // FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_BUNDLE_AGING_MGR_H \ No newline at end of file diff --git a/services/bundlemgr/include/bundle_data_mgr.h b/services/bundlemgr/include/bundle_data_mgr.h index bb39d9725..e9c010d5e 100644 --- a/services/bundlemgr/include/bundle_data_mgr.h +++ b/services/bundlemgr/include/bundle_data_mgr.h @@ -16,6 +16,7 @@ #ifndef FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_BUNDLE_DATA_MGR_H #define FOUNDATION_APPEXECFWK_SERVICES_BUNDLEMGR_INCLUDE_BUNDLE_DATA_MGR_H +#include #include #include #include @@ -605,6 +606,13 @@ public: * @return Returns all userId. */ std::set GetAllUser() const; +#ifdef BUNDLE_FRAMEWORK_FREE_INSTALL + /** + * @brief Get active user. + * @return Returns active userId. + */ + int32_t GetActiveUserId() const; +#endif /** * @brief Obtains the DistributedBundleInfo based on a given bundle name and networkId. * @param networkId Indicates the networkId of remote device. @@ -681,12 +689,45 @@ public: bool RemoveInnerBundleUserInfo(const std::string &bundleName, int32_t userId); +#ifdef BUNDLE_FRAMEWORK_FREE_INSTALL + bool GetRemovableBundleNameVec(std::map& bundlenameAndUids); +#endif bool ImplicitQueryInfoByPriority(const Want &want, int32_t flags, int32_t userId, AbilityInfo &abilityInfo, ExtensionAbilityInfo &extensionInfo); #ifdef SUPPORT_GRAPHICS std::shared_ptr GetAbilityPixelMapIcon(const std::string &bundleName, const std::string &abilityName) const; #endif + + /** + * @brief Set Module isRemovable by bundleName and moduleName. + * @param bundleName Indicates the bundleName. + * @param moduleName Indicates the moduleName. + * @param isEnable Set module isRemovable is enable. + * @return Returns true if the module isRemovable is set success; returns false otherwise. + */ + bool SetModuleRemovable(const std::string &bundleName, const std::string &moduleName, bool isEnable); + /** + * @brief Get Module isRemovable by bundleName and moduleName. + * @param bundleName Indicates the application bundle name to be queried. + * @param moduleName Indicates the moduleName. + * @return Returns true if the module isRemovable is successfully obtained; returns false otherwise. + */ + bool IsModuleRemovable(const std::string &bundleName, const std::string &moduleName) const; + +#ifdef BUNDLE_FRAMEWORK_FREE_INSTALL + /** + * @brief Get bundle space size (Bytes) by bundleName. + * @param bundleName Indicates the application bundle name to be queried. + * @return Returns the space size of a bundle by bundleName. + */ + int64_t GetBundleSpaceSize(const std::string &bundleName) const; + /** + * @brief Get all free install bundle space size (Bytes). + * @return Returns the space size of all free install bundles. + */ + int64_t GetAllFreeInstallBundleSpaceSize() const; +#endif bool GetAllDependentModuleNames(const std::string &bundleName, const std::string &moduleName, std::vector &dependentModuleNames); diff --git a/services/bundlemgr/include/bundle_mgr_host_impl.h b/services/bundlemgr/include/bundle_mgr_host_impl.h index 097809157..64e536e95 100644 --- a/services/bundlemgr/include/bundle_mgr_host_impl.h +++ b/services/bundlemgr/include/bundle_mgr_host_impl.h @@ -641,6 +641,23 @@ public: virtual std::shared_ptr GetAbilityPixelMapIcon(const std::string &bundleName, const std::string &abilityName) override; #endif + /** + * @brief Obtains the value of isRemovable based on a given bundle name and module name. + * @param bundleName Indicates the bundle name to be queried. + * @param moduleName Indicates the module name to be queried. + * @return Returns true if the isRemovable is successfully obtained; returns false otherwise. + */ + virtual bool IsModuleRemovable(const std::string &bundleName, const std::string &moduleName) override; + /** + * @brief Sets whether to enable isRemovable based on a given bundle name and module name. + * @param bundleName Indicates the bundle name to be queried. + * @param moduleName Indicates the module name to be queried. + * @param isEnable Specifies whether to enable the isRemovable of InnerModuleInfo. + * The value true means to enable it, and the value false means to disable it + * @return Returns true if the isRemovable is successfully obtained; returns false otherwise. + */ + virtual bool SetModuleRemovable( + const std::string &bundleName, const std::string &moduleName, bool isEnable) override; /** * @brief Obtains the dependent module names. * diff --git a/services/bundlemgr/include/bundle_mgr_service.h b/services/bundlemgr/include/bundle_mgr_service.h index cee8a3c6d..12575a686 100644 --- a/services/bundlemgr/include/bundle_mgr_service.h +++ b/services/bundlemgr/include/bundle_mgr_service.h @@ -24,6 +24,9 @@ #ifdef DEVICE_MANAGER_ENABLE #include "bms_device_manager.h" #endif +#ifdef BUNDLE_FRAMEWORK_FREE_INSTALL +#include "aging/bundle_aging_mgr.h" +#endif #include "bundle_clone_mgr.h" #include "bundle_constants.h" #include "bundle_data_mgr.h" @@ -64,6 +67,9 @@ public: const std::shared_ptr GetCloneMgr() const; const std::shared_ptr GetDataMgr() const; +#ifdef BUNDLE_FRAMEWORK_FREE_INSTALL + const std::shared_ptr GetAgingMgr() const; +#endif /** * @brief Get a IBundleInstaller object for IPC * @return Returns the pointer of IBundleInstaller object. @@ -89,11 +95,13 @@ public: * @return Returns whether the interface is called successfully. */ bool Hidump(const std::vector &args, std::string& result) const; + protected: #ifdef DEVICE_MANAGER_ENABLE void OnAddSystemAbility(int32_t systemAbilityId, const std::string& deviceId) override; void OnRemoveSystemAbility(int32_t systemAbilityId, const std::string& deviceId) override; #endif + private: /** * @brief Initialize the bundle manager service context. @@ -123,6 +131,9 @@ private: std::shared_ptr deviceManager_; #endif std::shared_ptr hidumpHelper_; +#ifdef BUNDLE_FRAMEWORK_FREE_INSTALL + std::shared_ptr agingMgr_; +#endif sptr host_; sptr installer_; sptr userMgrHost_; diff --git a/services/bundlemgr/include/inner_bundle_info.h b/services/bundlemgr/include/inner_bundle_info.h index a10319529..9b6743bad 100644 --- a/services/bundlemgr/include/inner_bundle_info.h +++ b/services/bundlemgr/include/inner_bundle_info.h @@ -68,6 +68,7 @@ struct InnerModuleInfo { std::string srcPath; bool isEntry = false; bool installationFree = false; + bool isRemovable = false; MetaData metaData; ModuleColorMode colorMode = ModuleColorMode::AUTO; Distro distro; @@ -948,6 +949,16 @@ public: return baseApplicationInfo_.isLauncherApp; } + void SetIsFreeInstallApp(bool isFreeInstall) + { + baseApplicationInfo_.isFreeInstallApp = isFreeInstall; + } + + bool GetIsFreeInstallApp() const + { + return baseApplicationInfo_.isFreeInstallApp; + } + void SetMainAbility(const std::string &mainAbility) { mainAbility_ = mainAbility; @@ -1343,6 +1354,25 @@ public: void GetUriPrefixList(std::vector &uriPrefixList, const std::string &excludeModule = "") const; void GetUriPrefixList(std::vector &uriPrefixList, int32_t userId, const std::string &excludeModule = "") const; + /** + * @brief module is removed. + * @param moduleName Indicates the moduleName. + * @return Return get module removed result. + */ + bool isModuleRemovable(const std::string &moduleName) const; + /** + * @brief module is removed. + * @param moduleName Indicates the moduleName. + * @param isEnable Indicates the module isRemovable is enable. + * @return Return set module removed result. + */ + bool SetModuleRemovable(const std::string &moduleName, bool isEnable); + /** + * @brief bundle is removed. + * @return Return get bundle removed result + */ + bool IsBundleRemovable() const; + private: void GetBundleWithAbilities( int32_t flags, BundleInfo &bundleInfo, int32_t userId = Constants::UNSPECIFIED_USERID) const; diff --git a/services/bundlemgr/src/aging/aging_handler_chain.cpp b/services/bundlemgr/src/aging/aging_handler_chain.cpp new file mode 100644 index 000000000..53bf64d53 --- /dev/null +++ b/services/bundlemgr/src/aging/aging_handler_chain.cpp @@ -0,0 +1,54 @@ +/* + * 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. + */ + +#include "aging/aging_handler_chain.h" +#include "app_log_wrapper.h" + +namespace OHOS { +namespace AppExecFwk { +AgingHandlerChain::AgingHandlerChain() +{ +} + +AgingHandlerChain::~AgingHandlerChain() +{ + handlers.clear(); + APP_LOGD("AgingHandlerChain is destroyed"); +} + +void AgingHandlerChain::AddHandler(const ::std::shared_ptr &handler) +{ + if (handler == nullptr) { + APP_LOGE("agingHandler: invalid handler."); + return; + } + handlers.emplace_back(handler); + APP_LOGD("agingHandler: %{public}s is added into handlers", handler->GetName().c_str()); +} + +bool AgingHandlerChain::Process(AgingRequest &request) const +{ + for (auto handler : handlers) { + bool passed = handler->Process(request); + APP_LOGD("agingHandler: %{public}s process passed: %{public}d", handler->GetName().c_str(), passed); + if (!passed) { + break; + } + } + APP_LOGD("agingHandler: aging handler chain process done."); + return request.IsReachEndAgingThreshold(); +} +} // namespace AppExecFwk +} // namespace OHOS \ No newline at end of file diff --git a/services/bundlemgr/src/aging/aging_request.cpp b/services/bundlemgr/src/aging/aging_request.cpp new file mode 100644 index 000000000..dea320073 --- /dev/null +++ b/services/bundlemgr/src/aging/aging_request.cpp @@ -0,0 +1,75 @@ +/* + * 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. + */ + +#include "aging/aging_request.h" + +#include + +#include "aging/aging_constants.h" +#include "app_log_wrapper.h" +#include "parameter.h" + +namespace OHOS { +namespace AppExecFwk { +int64_t AgingRequest::totalDataBytesThreshold = AgingConstants::DEFAULT_AGING_DATA_SIZE_THRESHOLD; +int64_t AgingRequest::oneDayTimeMs = AgingConstants::ONE_DAYS_MS; +AgingRequest::AgingRequest() +{ + InitAgingPolicySystemParameters(); +} + +void AgingRequest::InitAgingPolicySystemParameters() +{ + char szDatasizeThreshold[AgingConstants::THRESHOLD_VAL_LEN] = {0}; + int32_t ret = GetParameter(AgingConstants::SYSTEM_PARAM_DATA_SIZE_THRESHOLD.c_str(), "", szDatasizeThreshold, + AgingConstants::THRESHOLD_VAL_LEN); + if (strcmp(szDatasizeThreshold, "") != 0) { + totalDataBytesThreshold = atoi(szDatasizeThreshold); + } + + char szOneDayTimeMs[AgingConstants::THRESHOLD_VAL_LEN] = {0}; + ret = GetParameter(AgingConstants::SYSTEM_PARAM_RECENILY_USED_THRESHOLD.c_str(), "", szOneDayTimeMs, + AgingConstants::THRESHOLD_VAL_LEN); + if (strcmp(szOneDayTimeMs, "") != 0) + oneDayTimeMs = atoi(szOneDayTimeMs); +} + +bool AgingRequest::IsReachStartAgingThreshold() const +{ + APP_LOGD("tatalDataBytes: %{public}" PRId64 ", totalDataBytesThreshold: %{public}" PRId64, tatalDataBytes, + totalDataBytesThreshold); + return tatalDataBytes > totalDataBytesThreshold; +} + +bool AgingRequest::IsReachEndAgingThreshold() const +{ + APP_LOGD("tatalDataBytes: %{public}" PRId64 ", totalDataBytesThreshold: %{public}" PRId64, tatalDataBytes, + totalDataBytesThreshold); + return tatalDataBytes < (int64_t)(totalDataBytesThreshold * AgingConstants::AGING_SIZE_RATIO); +} + +void AgingRequest::AddAgingBundle(AgingBundleInfo &bundleInfo) +{ + agingBundles.emplace_back(bundleInfo); +} + +void AgingRequest::reset() +{ + agingBundles.clear(); + tatalDataBytes = 0; + InitAgingPolicySystemParameters(); +} +} // namespace AppExecFwk +} // namespace OHOS \ No newline at end of file diff --git a/services/bundlemgr/src/aging/aging_util.cpp b/services/bundlemgr/src/aging/aging_util.cpp new file mode 100644 index 000000000..83c0fd7a8 --- /dev/null +++ b/services/bundlemgr/src/aging/aging_util.cpp @@ -0,0 +1,50 @@ +/* + * 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. + */ + +#include "aging/aging_util.h" + +#include "app_log_wrapper.h" +#include "aging/aging_bundle_info.h" +#include "aging/aging_constants.h" +#include "aging/aging_request.h" + +namespace OHOS { +namespace AppExecFwk { +void AgingUtil::SortAgingBundles(std::vector &bundles) +{ + sort(bundles.begin(), bundles.end(), SortTwoAgingBundleinfos); +} +bool AgingUtil::SortTwoAgingBundleinfos(AgingBundleInfo &bundle1, AgingBundleInfo &bundle2) +{ + int64_t currentTimeMs = GetNowSysTimeMs(); + int64_t unusedTime = GetUnusedTimeMsBaseOnCurrentTime(currentTimeMs, AgingConstants::TIME_10_DAYS); + if (bundle1.GetRecentlyUsedTime() > unusedTime && bundle2.GetRecentlyUsedTime() > unusedTime) { + return bundle1.GetDataBytes() > bundle2.GetDataBytes(); + } else if (bundle1.GetRecentlyUsedTime() > unusedTime && bundle2.GetRecentlyUsedTime() < unusedTime) { + return false; + } else if (bundle1.GetRecentlyUsedTime() < unusedTime && bundle2.GetRecentlyUsedTime() > unusedTime) { + return true; + } else if (bundle1.GetRecentlyUsedTime() < unusedTime && bundle2.GetRecentlyUsedTime() < unusedTime) { + return bundle1.GetRecentlyUsedTime() < bundle2.GetRecentlyUsedTime(); + } + return false; +} + +int64_t AgingUtil::GetUnusedTimeMsBaseOnCurrentTime(int64_t currentTimeMs, int32_t days) +{ + return currentTimeMs - days * AgingRequest::GetOneDayTimeMs(); +} +} // namespace AppExecFwk +} // namespace OHOS \ No newline at end of file diff --git a/services/bundlemgr/src/aging/bundle_aging_mgr.cpp b/services/bundlemgr/src/aging/bundle_aging_mgr.cpp new file mode 100644 index 000000000..198b6efd3 --- /dev/null +++ b/services/bundlemgr/src/aging/bundle_aging_mgr.cpp @@ -0,0 +1,218 @@ +/* + * 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. + */ +#include "aging/bundle_aging_mgr.h" + +#include "battery_srv_client.h" +#include "bundle_active_client.h" +#include "bundle_active_period_stats.h" +#include "bundle_mgr_service.h" +#include "bundle_util.h" +#include "display_power_mgr_client.h" +#include "parameter.h" + +namespace OHOS { +namespace AppExecFwk { +BundleAgingMgr::BundleAgingMgr() +{ + InitAgingHandlerChain(); + APP_LOGI("BundleAgingMgr is created."); +} + +BundleAgingMgr::~BundleAgingMgr() +{ + APP_LOGI("BundleAgingMgr is destroyed"); +} + +void BundleAgingMgr::InitAgingRunner() +{ + auto agingRunner = EventRunner::Create(AgingConstants::AGING_THREAD); + if (!agingRunner) { + APP_LOGE("create aging runner failed"); + return; + } + SetEventRunner(agingRunner); +} + +void BundleAgingMgr::InitAgingtTimer() +{ + char szTimerThresold[AgingConstants::THRESHOLD_VAL_LEN + 1] = {0}; + int32_t ret = GetParameter(AgingConstants::SYSTEM_PARAM_AGING_TIMER_INTERVAL.c_str(), "", szTimerThresold, + AgingConstants::THRESHOLD_VAL_LEN); + APP_LOGD("ret is %{public}d, szTimerThresold is %{public}d", ret, atoi(szTimerThresold)); + if (strcmp(szTimerThresold, "") == 0) { + agingTimerInterval = AgingConstants::DEFAULT_AGING_TIMER_INTERVAL; + } else { + agingTimerInterval = atoi(szTimerThresold); + } + + char szBatteryThresold[AgingConstants::THRESHOLD_VAL_LEN + 1] = {0}; + ret = GetParameter(AgingConstants::SYSTEM_PARAM_AGING_BATTER_THRESHOLD.c_str(), "", szBatteryThresold, + AgingConstants::THRESHOLD_VAL_LEN); + if (strcmp(szBatteryThresold, "") == 0) { + agingBatteryThresold = AgingConstants::DEFAULT_AGING_BATTERY_THRESHOLD; + } else { + agingBatteryThresold = atoi(szBatteryThresold); + } + + APP_LOGD("BundleAgingMgr init aging timer, interval : %{public}" PRId64 ", battery threshold: %{public}" PRId64, + agingTimerInterval, agingBatteryThresold); + + bool isEventStarted = SendEvent(InnerEvent::Get(EVENT_AGING_NOW), agingTimerInterval); + if (!isEventStarted) { + APP_LOGE("faild to send event is not started"); + { + std::lock_guard lock(mutex_); + running = false; + } + } + APP_LOGD("BundleAgingMgr init aging timer success"); +} + +bool BundleAgingMgr::ReInitAgingRequest(const std::shared_ptr &dataMgr) +{ + if (!dataMgr) { + APP_LOGE("ReInitAgingRequest: dataMgr is null"); + return false; + } + request.reset(); + std::map bundleNamesAndUid; + dataMgr->GetRemovableBundleNameVec(bundleNamesAndUid); + if (bundleNamesAndUid.empty()) { + APP_LOGE("ReInitAginRequst: no removable bundles"); + return false; + } + APP_LOGD("ReInitAginRequst: removable bundles size %{public}zu", bundleNamesAndUid.size()); + + std::vector activeModuleRecord; + DeviceUsageStats::BundleActiveClient* bundleActiveClient = new DeviceUsageStats::BundleActiveClient(); + int ret = bundleActiveClient->QueryFormStatistics(AgingConstants::COUNT_MODULE_RECODES_GET, activeModuleRecord); + APP_LOGD("activeModuleRecord size %{public}zu, ret:%{public}d", activeModuleRecord.size(), ret); + delete(bundleActiveClient); + + for (auto iter : bundleNamesAndUid) { + int64_t dataBytes = dataMgr->GetBundleSpaceSize(iter.first); + // the value of lastLaunchTimesMs get from lastLaunchTimesMs interface + // which is not exist, init lastLaunchTimesMs to 0 firstly + int64_t lastLaunchTimesMs = AgingUtil::GetNowSysTimeMs(); + if (ret == 0) { + for (const auto &moduleRecord : activeModuleRecord) { + if (moduleRecord.bundleName_ == iter.first && lastLaunchTimesMs > moduleRecord.lastModuleUsedTime_) { + lastLaunchTimesMs = moduleRecord.lastModuleUsedTime_; + } + } + APP_LOGD("%{public}s: %{public}" PRId64, iter.first.c_str(), lastLaunchTimesMs); + } + AgingBundleInfo agingBundleInfo(iter.first, lastLaunchTimesMs, dataBytes, iter.second); + request.AddAgingBundle(agingBundleInfo); + } + request.SetTotalDataBytes(dataMgr->GetAllFreeInstallBundleSpaceSize()); + return request.SortAgingBundles() > 0; +} + +void BundleAgingMgr::Process(const std::shared_ptr &dataMgr) +{ + APP_LOGD("BundleAging begin to process."); + if (ReInitAgingRequest(dataMgr)) { + if (request.IsReachStartAgingThreshold()) { + chain.Process(request); + } + } + { + std::lock_guard lock(mutex_); + running = false; + } + APP_LOGD("BundleAgingMgr Process done"); +} + +void BundleAgingMgr::Start(AgingTriggertype type) +{ + APP_LOGD("aging start, AgingTriggertype: %{public}d", type); + if (!CheckPrerequisite(type)) { + APP_LOGE("BundleAgingMgr aging Prerequisite is not satisfied"); + return; + } + + auto dataMgr = OHOS::DelayedSingleton::GetInstance()->GetDataMgr(); + if (!dataMgr) { + APP_LOGE("dataMgr is null"); + return; + } + { + std::lock_guard lock(mutex_); + if (running) { + APP_LOGD("BundleAgingMgr is running, no need to start is again"); + return; + } + running = true; + } + + auto task = [&, dataMgr]() { Process(dataMgr); }; + bool isEventStarted = SendEvent(InnerEvent::Get(task)); + if (!isEventStarted) { + APP_LOGE("BundleAgingMgr event is not started."); + { + std::lock_guard lock(mutex_); + running = false; + } + } else { + APP_LOGD("BundleAgingMgr schedule process done"); + } +} + +bool BundleAgingMgr::CheckPrerequisite(AgingTriggertype type) const +{ + if (type != AgingTriggertype::PREIOD) { + return true; + } + DisplayPowerMgr::DisplayState state = DisplayPowerMgr::DisplayPowerMgrClient::GetInstance().GetDisplayState(); + if (state == DisplayPowerMgr::DisplayState::DISPLAY_ON) { + APP_LOGD("current Displaystate is DisplayState::DISPLAY_ON"); + return false; + } + int32_t currentbatteryCap = OHOS::PowerMgr::BatterySrvClient::GetInstance().GetCapacity(); + APP_LOGD("current GetCapacity is %{public}d agingBatteryThresold: %{public}" PRId64, + currentbatteryCap, agingBatteryThresold); + return currentbatteryCap > agingBatteryThresold; +} + +void BundleAgingMgr::ProcessEvent(const InnerEvent::Pointer &event) +{ + uint32_t eventId = event->GetInnerEventId(); + APP_LOGD("BundleAgingMgr process event : %{public}u", eventId); + switch (eventId) { + case EVENT_AGING_NOW: + APP_LOGD("BundleAgingMgr timer expire, run aging now."); + Start(AgingTriggertype::PREIOD); + SendEvent(eventId, 0, agingTimerInterval); + APP_LOGD("BundleAginMgr reschedule time."); + break; + + default: + APP_LOGD("BundleAgingMgr invalid Event %{public}d.", eventId); + break; + } +} + +void BundleAgingMgr::InitAgingHandlerChain() +{ + chain = AgingHandlerChain(); + chain.AddHandler(std::make_shared()); + chain.AddHandler(std::make_shared()); + chain.AddHandler(std::make_shared()); + chain.AddHandler(std::make_shared()); + APP_LOGD("InitAgingHandleChain is finished."); +} +} // namespace AppExecFwk +} // namespace OHOS diff --git a/services/bundlemgr/src/aging/bundle_data_size_aging_handler.cpp b/services/bundlemgr/src/aging/bundle_data_size_aging_handler.cpp new file mode 100644 index 000000000..e443c5307 --- /dev/null +++ b/services/bundlemgr/src/aging/bundle_data_size_aging_handler.cpp @@ -0,0 +1,32 @@ +/* + * 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. + */ + +#include "aging/aging_constants.h" +#include "aging/aging_handler.h" + +namespace OHOS { +namespace AppExecFwk { +bool BundleDataSizeAgingHandler::CheckBundle(const AgingBundleInfo &bundle) const +{ + // the size of all app is bigger than 0 + return true; +} + +const std::string &BundleDataSizeAgingHandler::GetName() const +{ + return AgingConstants::BUNDLE_DATA_SIZE_AGING_HANDLER; +} +} // namespace AppExecFwk +} // namespace OHOS \ No newline at end of file diff --git a/services/bundlemgr/src/aging/over_10days_unused_bundle_aging_handler.cpp b/services/bundlemgr/src/aging/over_10days_unused_bundle_aging_handler.cpp new file mode 100644 index 000000000..a1a5a549c --- /dev/null +++ b/services/bundlemgr/src/aging/over_10days_unused_bundle_aging_handler.cpp @@ -0,0 +1,32 @@ +/* + * 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. + */ + +#include "aging/aging_constants.h" +#include "aging/aging_handler.h" + +namespace OHOS { +namespace AppExecFwk { +bool Over10DaysUnusedBundleAgingHandler::CheckBundle(const AgingBundleInfo &bundle) const +{ + return (AgingUtil::GetNowSysTimeMs() - bundle.GetRecentlyUsedTime()) > + (AgingConstants::TIME_10_DAYS * AgingConstants::ONE_DAYS_MS); +} + +const std::string &Over10DaysUnusedBundleAgingHandler::GetName() const +{ + return AgingConstants::UNUSED_FOR_10_DAYS_BUNDLE_AGING_HANDLER; +} +} // namespace AppExecFwk +} // namespace OHOS \ No newline at end of file diff --git a/services/bundlemgr/src/aging/over_20days_unused_bundle_aging_handler.cpp b/services/bundlemgr/src/aging/over_20days_unused_bundle_aging_handler.cpp new file mode 100644 index 000000000..fe62ed86f --- /dev/null +++ b/services/bundlemgr/src/aging/over_20days_unused_bundle_aging_handler.cpp @@ -0,0 +1,32 @@ +/* + * 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. + */ + +#include "aging/aging_constants.h" +#include "aging/aging_handler.h" + +namespace OHOS { +namespace AppExecFwk { +bool Over20DaysUnusedBundleAgingHandler::CheckBundle(const AgingBundleInfo &bundle) const +{ + return (AgingUtil::GetNowSysTimeMs() - bundle.GetRecentlyUsedTime()) > + (AgingConstants::TIME_20_DAYS * AgingConstants::ONE_DAYS_MS); +} + +const std::string &Over20DaysUnusedBundleAgingHandler::GetName() const +{ + return AgingConstants::UNUSED_FOR_20_DAYS_BUNDLE_AGING_HANDLER; +} +} // namespace AppExecFwk +} // namespace OHOS \ No newline at end of file diff --git a/services/bundlemgr/src/aging/over_30days_unused_bundle_aging_handler.cpp b/services/bundlemgr/src/aging/over_30days_unused_bundle_aging_handler.cpp new file mode 100644 index 000000000..39b22629a --- /dev/null +++ b/services/bundlemgr/src/aging/over_30days_unused_bundle_aging_handler.cpp @@ -0,0 +1,32 @@ +/* + * 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. + */ + +#include "aging/aging_constants.h" +#include "aging/aging_handler.h" + +namespace OHOS { +namespace AppExecFwk { +bool Over30DaysUnusedBundleAgingHandler::CheckBundle(const AgingBundleInfo &bundle) const +{ + return (AgingUtil::GetNowSysTimeMs() - bundle.GetRecentlyUsedTime()) > + (AgingConstants::TIME_30_DAYS * AgingConstants::ONE_DAYS_MS); +} + +const std::string &Over30DaysUnusedBundleAgingHandler::GetName() const +{ + return AgingConstants::UNUSED_FOR_30_DAYS_BUNDLE_AGING_HANDLER; +} +} // namespace AppExecFwk +} // namespace OHOS \ No newline at end of file diff --git a/services/bundlemgr/src/aging/recently_unused_bundle_aging_handler.cpp b/services/bundlemgr/src/aging/recently_unused_bundle_aging_handler.cpp new file mode 100644 index 000000000..feb95a969 --- /dev/null +++ b/services/bundlemgr/src/aging/recently_unused_bundle_aging_handler.cpp @@ -0,0 +1,110 @@ +/* + * 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. + */ + +#include + +#include "ability_manager.h" +#include "aging/aging_handler.h" +#include "app_log_wrapper.h" +#include "bundle_data_mgr.h" +#include "bundle_mgr_service.h" +#include "install_param.h" +#include "running_process_info.h" + +namespace OHOS { +namespace AppExecFwk { +bool RecentlyUnuseBundleAgingHandler::Process(AgingRequest &request) const +{ + bool needContinue = true; + APP_LOGD("aging handler start: %{public}s, currentTotalDataBytes: %{pubic}" PRId64, GetName().c_str(), + request.GetTotalDataBytes()); + std::vector &agingBundles = const_cast &>(request.GetAgingBundles()); + APP_LOGD("aging handler start: agingBundles size :%{public}zu / %{public}" PRId64, agingBundles.size(), + request.GetTotalDataBytes()); + auto iter = agingBundles.begin(); + while (iter != agingBundles.end()) { + if (!CheckBundle(*iter)) { + break; + } + APP_LOGD("found matching bundle: %{public}s.", iter->GetBundleName().c_str()); + bool isBundlerunning = isRunning(iter->GetBundleName(), iter->GetBundleUid()); + if (!isBundlerunning) { + bool isBundleUnistalled = UnInstallBundle(iter->GetBundleName()); + if (isBundleUnistalled) { + request.UpdateTotalDataBytesAfterUninstalled(iter->GetDataBytes()); + } + } + iter = agingBundles.erase(iter); + if (GetName() == AgingConstants::BUNDLE_DATA_SIZE_AGING_HANDLER) { + if (!NeedContinue(request)) { + APP_LOGD("there is no need to continue now."); + needContinue = false; + return needContinue; + } + } + } + if (!NeedContinue(request)) { + APP_LOGD("there is no need to continue now."); + needContinue = false; + } + APP_LOGD("aging handle done: %{public}s, currentTotalDataBytes: %{public}" PRId64, GetName().c_str(), + request.GetTotalDataBytes()); + return needContinue; +} + +bool RecentlyUnuseBundleAgingHandler::NeedContinue(const AgingRequest &requese) const +{ + return !requese.IsReachEndAgingThreshold(); +} + +bool RecentlyUnuseBundleAgingHandler::UnInstallBundle(const std::string &bundlename) const +{ + auto bms = DelayedSingleton::GetInstance(); + auto bundleInstaller = bms->GetBundleInstaller(); + auto bundleDataMgr = bms->GetDataMgr(); + if (!bundleInstaller) { + APP_LOGE("bundleInstaller is null."); + return false; + } + + sptr userReceiverImpl(new (std::nothrow) AgingUninstallReceiveImpl()); + InstallParam installParam; + installParam.userId = bundleDataMgr->GetActiveUserId(); + bundleInstaller->Uninstall(bundlename, installParam, userReceiverImpl); + return true; +} + +bool RecentlyUnuseBundleAgingHandler::isRunning(const std::string bundleName, const int bundleuid) const +{ + if (bundleuid < 0) { + APP_LOGE("bundleuid is error."); + return false; + } + std::vector runningList = AbilityManager::GetInstance().GetAllRunningProcesses(); + if (runningList.size() == 0) { + APP_LOGD("app runningList size = 0."); + return false; + } + for (RunningProcessInfo info : runningList) { + if (info.uid_ == bundleuid) { + APP_LOGD("bundleName: %{public}s is running.", bundleName.c_str()); + return true; + } + } + APP_LOGD("nothing app running."); + return false; +} +} // namespace AppExecFwk +} // namespace OHOS diff --git a/services/bundlemgr/src/base_bundle_installer.cpp b/services/bundlemgr/src/base_bundle_installer.cpp index 6d4e5a9fd..6870e17ec 100644 --- a/services/bundlemgr/src/base_bundle_installer.cpp +++ b/services/bundlemgr/src/base_bundle_installer.cpp @@ -17,7 +17,11 @@ #include "nlohmann/json.hpp" +#ifdef BUNDLE_FRAMEWORK_FREE_INSTALL +#include "aging/bundle_aging_mgr.h" +#endif #include "ability_manager_helper.h" +#include "ability_manager_interface.h" #include "app_log_wrapper.h" #include "bundle_clone_mgr.h" #include "bundle_constants.h" @@ -215,6 +219,18 @@ ErrCode BaseBundleInstaller::InnerProcessBundleInstall(std::unordered_map &moduleInfo = item.second.FetchInnerModuleInfos(); + for (auto iter = moduleInfo.begin(); iter != moduleInfo.end(); iter++) { + APP_LOGD("set bundleName:(%{public}s) hap modulePackage:(%{public}s) isRemovable true.", + bundleName_.c_str(), iter->second.modulePackage.c_str()); + iter->second.isRemovable = true; + } + } + } + ErrCode result = ERR_OK; if (isAppExist_) { // to guarantee that the hap version can be compatible. @@ -265,6 +281,8 @@ ErrCode BaseBundleInstaller::InnerProcessBundleInstall(std::unordered_map } UpdateInstallerState(InstallerState::INSTALL_SUCCESS); // ---- 100% - APP_LOGD("finish ProcessBundleInstall bundlePath install"); + APP_LOGD("finish ProcessBundleInstall bundlePath install touch off aging"); +#ifdef BUNDLE_FRAMEWORK_FREE_INSTALL + if (installParam.installFlag == InstallFlag::FREE_INSTALL) { + DelayedSingleton::GetInstance()->GetAgingMgr()->Start( + BundleAgingMgr::AgingTriggertype::FREE_INSTALL); + } +#endif return result; } @@ -1480,7 +1504,7 @@ ErrCode BaseBundleInstaller::CheckAppLabelInfo(const std::unordered_mapsecond).IsSingleton(); Constants::AppType appType = (infos.begin()->second).GetAppType(); - for (const auto &info :infos) { + for (const auto &info : infos) { // check bundleName if (bundleName != info.second.GetBundleName()) { return ERR_APPEXECFWK_INSTALL_BUNDLENAME_NOT_SAME; diff --git a/services/bundlemgr/src/bundle_data_mgr.cpp b/services/bundlemgr/src/bundle_data_mgr.cpp index 4e0bd49a3..94f87add0 100644 --- a/services/bundlemgr/src/bundle_data_mgr.cpp +++ b/services/bundlemgr/src/bundle_data_mgr.cpp @@ -18,6 +18,11 @@ #include #include +#ifdef BUNDLE_FRAMEWORK_FREE_INSTALL +#include "installd/installd_operator.h" +#include "os_account_info.h" +#include "os_account_manager.h" +#endif #include "app_log_wrapper.h" #include "bundle_constants.h" #include "bundle_data_storage_database.h" @@ -1035,6 +1040,62 @@ bool BundleDataMgr::GetInnerBundleInfoByUid(const int uid, InnerBundleInfo &inne APP_LOGD("the uid(%{public}d) is not exists.", uid); return false; } +#ifdef BUNDLE_FRAMEWORK_FREE_INSTALL +int64_t BundleDataMgr::GetBundleSpaceSize(const std::string &bundleName) const +{ + int32_t userId; + int64_t curSize = 0; + int64_t spaceSize = 0; + BundleInfo bundleInfo; + + if ((userId = GetActiveUserId()) != Constants::INVALID_USERID + && GetBundleInfo(bundleName, GET_ALL_APPLICATION_INFO, bundleInfo, userId) == true) { + if (!bundleInfo.applicationInfo.codePath.empty()) { + curSize = InstalldOperator::GetDiskUsage(bundleInfo.applicationInfo.codePath); + spaceSize += curSize; + APP_LOGI("Code %{public}s:%{public}" PRId64, bundleInfo.applicationInfo.codePath.c_str(), curSize); + } + if (!bundleInfo.applicationInfo.dataDir.empty()) { + curSize = InstalldOperator::GetDiskUsage(bundleInfo.applicationInfo.dataDir); + spaceSize += curSize; + APP_LOGI("Data %{public}s:%{public}" PRId64, bundleInfo.applicationInfo.dataDir.c_str(), curSize); + } + } + + APP_LOGI("%{public}s spaceSize:%{public}" PRId64, bundleName.c_str(), spaceSize); + return spaceSize; +} + +int64_t BundleDataMgr::GetAllFreeInstallBundleSpaceSize() const +{ + int32_t userId; + int64_t allSize = 0; + int64_t curSize = 0; + std::vector bundleInfos; + + if ((userId = GetActiveUserId()) != Constants::INVALID_USERID + && GetBundleInfos(GET_ALL_APPLICATION_INFO, bundleInfos, userId) == true) { + for (const auto &item : bundleInfos) { + APP_LOGI("%{public}s freeInstall:%{public}d", item.name.c_str(), item.applicationInfo.isFreeInstallApp); + if (item.applicationInfo.isFreeInstallApp) { + if (!item.applicationInfo.codePath.empty()) { + curSize = InstalldOperator::GetDiskUsage(item.applicationInfo.codePath); + allSize += curSize; + APP_LOGI("Code %{public}s:%{public}" PRId64, item.applicationInfo.codePath.c_str(), curSize); + } + if (!item.applicationInfo.dataDir.empty()) { + curSize = InstalldOperator::GetDiskUsage(item.applicationInfo.dataDir); + allSize += curSize; + APP_LOGI("Data %{public}s:%{public}" PRId64, item.applicationInfo.dataDir.c_str(), curSize); + } + } + } + } + + APP_LOGI("All sfreeInstall:%{public}" PRId64, allSize); + return allSize; +} +#endif bool BundleDataMgr::GetBundlesForUid(const int uid, std::vector &bundleNames) const { @@ -1438,6 +1499,58 @@ bool BundleDataMgr::SetApplicationEnabled(const std::string &bundleName, bool is } } +bool BundleDataMgr::SetModuleRemovable(const std::string &bundleName, const std::string &moduleName, bool isEnable) +{ + APP_LOGD("bundleName:%{public}s, moduleName:%{public}s", bundleName.c_str(), moduleName.c_str()); + if (bundleName.empty() || moduleName.empty()) { + APP_LOGE("bundleName or moduleName is empty"); + return false; + } + std::lock_guard lock(bundleInfoMutex_); + auto infoItem = bundleInfos_.find(bundleName); + if (infoItem == bundleInfos_.end()) { + APP_LOGE("can not find bundle %{public}s", bundleName.c_str()); + return false; + } + InnerBundleInfo newInfo = infoItem->second; + bool ret = newInfo.SetModuleRemovable(moduleName, isEnable); + if (ret && dataStorage_->SaveStorageBundleInfo(newInfo)) { + ret = infoItem->second.SetModuleRemovable(moduleName, isEnable); +#ifdef BUNDLE_FRAMEWORK_FREE_INSTALL + if (isEnable) { + // call clean task + APP_LOGD("bundle:%{public}s isEnable:%{public}d ret:%{public}d call clean task", + bundleName.c_str(), isEnable, ret); + DelayedSingleton::GetInstance()->GetAgingMgr()->Start( + BundleAgingMgr::AgingTriggertype::UPDATE_REMOVABLE_FLAG); + } +#endif + return ret; + } else { + APP_LOGE("bundle:%{public}s SetModuleRemoved failed", bundleName.c_str()); + return false; + } +} + +bool BundleDataMgr::IsModuleRemovable(const std::string &bundleName, const std::string &moduleName) const +{ + APP_LOGD("bundleName is bundleName:%{public}s, moduleName:%{public}s", bundleName.c_str(), moduleName.c_str()); + if (bundleName.empty() || moduleName.empty()) { + APP_LOGE("bundleName or moduleName is empty"); + return false; + } + std::lock_guard lock(bundleInfoMutex_); + auto infoItem = bundleInfos_.find(bundleName); + if (infoItem == bundleInfos_.end()) { + APP_LOGE("can not find bundle %{public}s", bundleName.c_str()); + return false; + } + InnerBundleInfo newInfo = infoItem->second; + + return newInfo.isModuleRemovable(moduleName); +} + + bool BundleDataMgr::IsAbilityEnabled(const AbilityInfo &abilityInfo) const { int32_t flags = GET_ABILITY_INFO_DEFAULT; @@ -2324,6 +2437,20 @@ int32_t BundleDataMgr::GetUserIdByCallingUid() const return BundleUtil::GetUserIdByCallingUid(); } +#ifdef BUNDLE_FRAMEWORK_FREE_INSTALL +int32_t BundleDataMgr::GetActiveUserId() const +{ + std::vector activeIds; + int32_t ret = AccountSA::OsAccountManager::QueryActiveOsAccountIds(activeIds); + if (ret != 0 || activeIds.empty()) { + APP_LOGE("QueryActiveOsAccountIds ret = %{public}d. activeIds empty:%{public}d", + ret, activeIds.empty()); + return Constants::INVALID_USERID; + } + return activeIds[0]; +} +#endif + std::set BundleDataMgr::GetAllUser() const { std::lock_guard lock(multiUserIdSetMutex_); @@ -2681,6 +2808,27 @@ std::shared_ptr BundleDataMgr::GetResourceMan return resourceManager; } +#ifdef BUNDLE_FRAMEWORK_FREE_INSTALL +bool BundleDataMgr::GetRemovableBundleNameVec(std::map& bundlenameAndUids) +{ + if (bundleInfos_.empty()) { + APP_LOGE("bundleInfos_ is data is empty."); + } + for (auto &it : bundleInfos_) { + APP_LOGD("bundleName: %{public}s", it.first.c_str()); + int32_t userId = GetActiveUserId(); + APP_LOGD("bundle userId is %{public}d, userId= %{public}d", it.second.GetUserId(), userId); + if (!it.second.HasInnerBundleUserInfo(userId)) { + continue; + } + if (it.second.IsBundleRemovable()) { + bundlenameAndUids.emplace(it.first, it.second.GetUid(it.second.GetUserId())); + } + } + return true; +} +#endif + bool BundleDataMgr::QueryAllDeviceIds(std::vector &deviceIds) { return distributedDataStorage_->QueryAllDeviceIds(deviceIds); diff --git a/services/bundlemgr/src/bundle_mgr_host_impl.cpp b/services/bundlemgr/src/bundle_mgr_host_impl.cpp index 7df5d1bb4..5e432af8f 100644 --- a/services/bundlemgr/src/bundle_mgr_host_impl.cpp +++ b/services/bundlemgr/src/bundle_mgr_host_impl.cpp @@ -845,6 +845,26 @@ bool BundleMgrHostImpl::IsApplicationEnabled(const std::string &bundleName) return dataMgr->IsApplicationEnabled(bundleName); } +bool BundleMgrHostImpl::IsModuleRemovable(const std::string &bundleName, const std::string &moduleName) +{ + auto dataMgr = GetDataMgrFromService(); + if (dataMgr == nullptr) { + APP_LOGE("DataMgr is nullptr"); + return false; + } + return dataMgr->IsModuleRemovable(bundleName, moduleName); +} + +bool BundleMgrHostImpl::SetModuleRemovable(const std::string &bundleName, const std::string &moduleName, bool isEnable) +{ + auto dataMgr = GetDataMgrFromService(); + if (dataMgr == nullptr) { + APP_LOGE("DataMgr is nullptr"); + return false; + } + return dataMgr->SetModuleRemovable(bundleName, moduleName, isEnable); +} + bool BundleMgrHostImpl::SetApplicationEnabled(const std::string &bundleName, bool isEnable, int32_t userId) { APP_LOGD("start SetApplicationEnabled"); diff --git a/services/bundlemgr/src/bundle_mgr_service.cpp b/services/bundlemgr/src/bundle_mgr_service.cpp index 72aaf6c6a..9de84b678 100644 --- a/services/bundlemgr/src/bundle_mgr_service.cpp +++ b/services/bundlemgr/src/bundle_mgr_service.cpp @@ -206,6 +206,21 @@ bool BundleMgrService::Init() hidumpHelper_ = std::make_shared(dataMgr_); } +#ifdef BUNDLE_FRAMEWORK_FREE_INSTALL + if (!agingMgr_) { + APP_LOGI("Create aging manager"); + agingMgr_ = DelayedSingleton::GetInstance(); + if (!agingMgr_) { + APP_LOGE("Create aging manager faild."); + } + if (agingMgr_) { + APP_LOGI("Create aging manager success."); + agingMgr_->InitAgingRunner(); + agingMgr_->InitAgingtTimer(); + } + } +#endif + CheckAllUser(); ready_ = true; APP_LOGI("init end success"); @@ -222,6 +237,13 @@ const std::shared_ptr BundleMgrService::GetDataMgr() const return dataMgr_; } +#ifdef BUNDLE_FRAMEWORK_FREE_INSTALL +const std::shared_ptr BundleMgrService::GetAgingMgr() const +{ + return agingMgr_; +} +#endif + const std::shared_ptr BundleMgrService::GetCloneMgr() const { return cloneMgr_; diff --git a/services/bundlemgr/src/inner_bundle_info.cpp b/services/bundlemgr/src/inner_bundle_info.cpp index a359b9bea..dd4826015 100644 --- a/services/bundlemgr/src/inner_bundle_info.cpp +++ b/services/bundlemgr/src/inner_bundle_info.cpp @@ -52,6 +52,7 @@ const std::string MODULE_DESCRIPTION_ID = "descriptionId"; const std::string MODULE_LABEL = "label"; const std::string MODULE_LABEL_ID = "labelId"; const std::string MODULE_DESCRIPTION_INSTALLATION_FREE = "installationFree"; +const std::string MODULE_IS_REMOVABLE = "isRemovable"; const std::string MODULE_IS_ENTRY = "isEntry"; const std::string MODULE_METADATA = "metaData"; const std::string MODULE_COLOR_MODE = "colorMode"; @@ -345,6 +346,7 @@ void to_json(nlohmann::json &jsonObject, const InnerModuleInfo &info) {MODULE_LABEL, info.label}, {MODULE_LABEL_ID, info.labelId}, {MODULE_DESCRIPTION_INSTALLATION_FREE, info.installationFree}, + {MODULE_IS_REMOVABLE, info.isRemovable}, {MODULE_REQ_CAPABILITIES, info.reqCapabilities}, {MODULE_ABILITY_KEYS, info.abilityKeys}, {MODULE_SKILL_KEYS, info.skillKeys}, @@ -559,6 +561,14 @@ void from_json(const nlohmann::json &jsonObject, InnerModuleInfo &info) false, ProfileReader::parseResult, ArrayType::NOT_ARRAY); + GetValueIfFindKey(jsonObject, + jsonObjectEnd, + MODULE_IS_REMOVABLE, + info.isRemovable, + JsonType::BOOLEAN, + false, + ProfileReader::parseResult, + ArrayType::NOT_ARRAY); GetValueIfFindKey>(jsonObject, jsonObjectEnd, MODULE_REQ_CAPABILITIES, @@ -1229,6 +1239,7 @@ std::optional InnerBundleInfo::FindHapModuleInfo(const std::strin hapInfo.supportedModes = baseApplicationInfo_.supportedModes; hapInfo.reqCapabilities = it->second.reqCapabilities; hapInfo.colorMode = it->second.colorMode; + hapInfo.isRemovable = it->second.isRemovable; hapInfo.bundleName = baseApplicationInfo_.bundleName; hapInfo.mainElementName = it->second.mainAbility; @@ -1885,6 +1896,8 @@ void InnerBundleInfo::GetCommonEvents(const std::string &eventKey, std::vector InnerBundleInfo::GetInnerModuleInfoByModuleName(const std::string &moduleName) const { for (const auto &innerModuleInfo : innerModuleInfos_) { + APP_LOGD("info.moduleName = %{public}s, moduleName= %{public}s", + innerModuleInfo.second.moduleName.c_str(), moduleName.c_str()); if (innerModuleInfo.second.moduleName == moduleName) { return innerModuleInfo.second; } @@ -2113,6 +2126,43 @@ void InnerBundleInfo::SetApplicationEnabled(bool enabled, int32_t userId) infoItem->second.bundleUserInfo.enabled = enabled; } +bool InnerBundleInfo::IsBundleRemovable() const +{ + if (IsPreInstallApp()) { + APP_LOGE("PreInstallApp should not be cleaned"); + return false; + } + for (const auto &innerModuleInfo : innerModuleInfos_) { + if (!innerModuleInfo.second.isRemovable) { + return false; + } + } + return true; +} + +bool InnerBundleInfo::isModuleRemovable(const std::string &moduleName) const +{ + auto modInfoItem = GetInnerModuleInfoByModuleName(moduleName); + if (!modInfoItem) { + APP_LOGE("get InnerModuleInfo by moduleName(%{public}s) failed", moduleName.c_str()); + return false; + } + APP_LOGD("isRemovable = %{public}d, moduleName= %{public}s", modInfoItem->isRemovable, moduleName.c_str()); + return modInfoItem->isRemovable; +} + +bool InnerBundleInfo::SetModuleRemovable(const std::string &moduleName, bool isEnable) +{ + for (auto &innerModuleInfo : innerModuleInfos_) { + if (innerModuleInfo.second.moduleName == moduleName) { + innerModuleInfo.second.isRemovable = isEnable; + APP_LOGD("moduleName = %{public}s, isEnable = %{public}d", moduleName.c_str(), isEnable); + return true; + } + } + return false; +} + int32_t InnerBundleInfo::GetResponseUserId(int32_t requestUserId) const { if (innerBundleUserInfos_.empty()) { diff --git a/services/bundlemgr/test/BUILD.gn b/services/bundlemgr/test/BUILD.gn index feddc173c..29d5dc5ed 100644 --- a/services/bundlemgr/test/BUILD.gn +++ b/services/bundlemgr/test/BUILD.gn @@ -31,6 +31,10 @@ config("bundlemgr_test_config") { "//base/security/appverify/interfaces/innerkits/appverify/include", ] + if (bundle_framework_free_install) { + include_dirs += [ "//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_base/include/aging" ] + } + configs = [ "${services_path}/bundlemgr:bundlemgr_common_config", "${common_path}:appexecfwk_common_config", diff --git a/services/bundlemgr/test/unittest/bms_bundle_accesstokenid_test/BUILD.gn b/services/bundlemgr/test/unittest/bms_bundle_accesstokenid_test/BUILD.gn index 1dcf1a538..4630f4661 100644 --- a/services/bundlemgr/test/unittest/bms_bundle_accesstokenid_test/BUILD.gn +++ b/services/bundlemgr/test/unittest/bms_bundle_accesstokenid_test/BUILD.gn @@ -102,6 +102,19 @@ ohos_unittest("BmsBundleAccessTokenIdTest") { external_deps += [ "os_account_standard:os_account_innerkits" ] defines += [ "ACCOUNT_ENABLE" ] } + if (bundle_framework_free_install) { + sources += aging + include_dirs += + [ "${aafwk_path}/frameworks/kits/appkit/native/app/include" ] + deps += [ "${aafwk_path}/frameworks/kits/appkit:appkit_native" ] + external_deps += [ + "battery_manager_native:batterysrv_client", + "device_usage_statistics:usagestatsinner", + "display_manager_native:displaymgr", + "power_manager_native:powermgr_client", + ] + defines += [ "BUNDLE_FRAMEWORK_FREE_INSTALL" ] + } if (device_manager_enable) { sources += [ "${services_path}/bundlemgr/src/bms_device_manager.cpp" ] external_deps += [ "device_manager_base:devicemanagersdk" ] @@ -111,6 +124,7 @@ ohos_unittest("BmsBundleAccessTokenIdTest") { external_deps += [ "hicollie_native:libhicollie" ] defines += [ "HICOLLIE_ENABLE" ] } + resource_config_file = "//foundation/appexecfwk/standard/test/resource/bundlemgrservice/ohos_test.xml" } diff --git a/services/bundlemgr/test/unittest/bms_bundle_clone_test/BUILD.gn b/services/bundlemgr/test/unittest/bms_bundle_clone_test/BUILD.gn index ad88f2627..9d79bd5af 100644 --- a/services/bundlemgr/test/unittest/bms_bundle_clone_test/BUILD.gn +++ b/services/bundlemgr/test/unittest/bms_bundle_clone_test/BUILD.gn @@ -113,6 +113,20 @@ ohos_unittest("BmsBundleCloneTest") { external_deps += [ "hicollie_native:libhicollie" ] defines += [ "HICOLLIE_ENABLE" ] } + + if (bundle_framework_free_install) { + sources += aging + include_dirs += + [ "${aafwk_path}/frameworks/kits/appkit/native/app/include" ] + deps += [ "${aafwk_path}/frameworks/kits/appkit:appkit_native" ] + external_deps += [ + "battery_manager_native:batterysrv_client", + "device_usage_statistics:usagestatsinner", + "display_manager_native:displaymgr", + "power_manager_native:powermgr_client", + ] + defines += [ "BUNDLE_FRAMEWORK_FREE_INSTALL" ] + } } group("unittest") { diff --git a/services/bundlemgr/test/unittest/bms_bundle_installer_test/BUILD.gn b/services/bundlemgr/test/unittest/bms_bundle_installer_test/BUILD.gn index 204a6c7d0..1fefbdf5c 100644 --- a/services/bundlemgr/test/unittest/bms_bundle_installer_test/BUILD.gn +++ b/services/bundlemgr/test/unittest/bms_bundle_installer_test/BUILD.gn @@ -104,7 +104,19 @@ ohos_unittest("BmsBundleInstallerTest") { external_deps += [ "os_account_standard:os_account_innerkits" ] defines += [ "ACCOUNT_ENABLE" ] } - + if (bundle_framework_free_install) { + sources += aging + include_dirs += + [ "${aafwk_path}/frameworks/kits/appkit/native/app/include" ] + deps += [ "${aafwk_path}/frameworks/kits/appkit:appkit_native" ] + external_deps += [ + "battery_manager_native:batterysrv_client", + "device_usage_statistics:usagestatsinner", + "display_manager_native:displaymgr", + "power_manager_native:powermgr_client", + ] + defines += [ "BUNDLE_FRAMEWORK_FREE_INSTALL" ] + } if (device_manager_enable) { sources += [ "${services_path}/bundlemgr/src/bms_device_manager.cpp" ] external_deps += [ "device_manager_base:devicemanagersdk" ] @@ -206,6 +218,21 @@ ohos_unittest("BmsMultipleBundleInstallerTest") { external_deps += [ "os_account_standard:os_account_innerkits" ] defines += [ "ACCOUNT_ENABLE" ] } + + if (bundle_framework_free_install) { + sources += aging + include_dirs += + [ "${aafwk_path}/frameworks/kits/appkit/native/app/include" ] + deps += [ "${aafwk_path}/frameworks/kits/appkit:appkit_native" ] + external_deps += [ + "battery_manager_native:batterysrv_client", + "device_usage_statistics:usagestatsinner", + "display_manager_native:displaymgr", + "power_manager_native:powermgr_client", + ] + defines += [ "BUNDLE_FRAMEWORK_FREE_INSTALL" ] + } + if (hicollie_enable) { external_deps += [ "hicollie_native:libhicollie" ] defines += [ "HICOLLIE_ENABLE" ] diff --git a/services/bundlemgr/test/unittest/bms_bundle_kit_service_test/BUILD.gn b/services/bundlemgr/test/unittest/bms_bundle_kit_service_test/BUILD.gn index 84313e459..38e3d771f 100644 --- a/services/bundlemgr/test/unittest/bms_bundle_kit_service_test/BUILD.gn +++ b/services/bundlemgr/test/unittest/bms_bundle_kit_service_test/BUILD.gn @@ -66,6 +66,7 @@ ohos_unittest("BmsBundleKitServiceTest") { if (target_cpu == "arm") { cflags += [ "-DBINDER_IPC_32BIT" ] } + deps = [] if (bundle_framework_graphics) { @@ -106,6 +107,19 @@ ohos_unittest("BmsBundleKitServiceTest") { external_deps += [ "os_account_standard:os_account_innerkits" ] defines += [ "ACCOUNT_ENABLE" ] } + if (bundle_framework_free_install) { + sources += aging + include_dirs += + [ "${aafwk_path}/frameworks/kits/appkit/native/app/include" ] + deps += [ "${aafwk_path}/frameworks/kits/appkit:appkit_native" ] + external_deps += [ + "battery_manager_native:batterysrv_client", + "device_usage_statistics:usagestatsinner", + "display_manager_native:displaymgr", + "power_manager_native:powermgr_client", + ] + defines += [ "BUNDLE_FRAMEWORK_FREE_INSTALL" ] + } if (device_manager_enable) { sources += [ "${services_path}/bundlemgr/src/bms_device_manager.cpp" ] external_deps += [ "device_manager_base:devicemanagersdk" ] diff --git a/services/bundlemgr/test/unittest/bms_bundle_kit_service_test/bms_bundle_kit_service_test.cpp b/services/bundlemgr/test/unittest/bms_bundle_kit_service_test/bms_bundle_kit_service_test.cpp index 82ef10718..a21f024e5 100644 --- a/services/bundlemgr/test/unittest/bms_bundle_kit_service_test/bms_bundle_kit_service_test.cpp +++ b/services/bundlemgr/test/unittest/bms_bundle_kit_service_test/bms_bundle_kit_service_test.cpp @@ -959,6 +959,111 @@ void BmsBundleKitServiceTest::CheckShortcutInfoDemo(std::vector &s } } +/** + * @tc.number: CheckModuleRemovable_0100 + * @tc.name: test can check module removable is enable by no setting + * @tc.desc: 1.system run normally + * 2.check the module removable successfully + */ +HWTEST_F(BmsBundleKitServiceTest, CheckModuleRemovable_0100, Function | SmallTest | Level1) +{ + MockInstallBundle(BUNDLE_NAME_TEST, MODULE_NAME_TEST, ABILITY_NAME_TEST); + + bool testRet = GetBundleDataMgr()->IsModuleRemovable(BUNDLE_NAME_TEST, MODULE_NAME_TEST); + EXPECT_FALSE(testRet); + + MockUninstallBundle(BUNDLE_NAME_TEST); +} + +/** + * @tc.number: CheckModuleRemovable_0200 + * @tc.name: test can check module removable is enable by setting + * @tc.desc: 1.system run normally + * 2.check the module removable successfully + */ +HWTEST_F(BmsBundleKitServiceTest, CheckModuleRemovable_0200, Function | SmallTest | Level1) +{ + MockInstallBundle(BUNDLE_NAME_TEST, MODULE_NAME_TEST, ABILITY_NAME_TEST); + + bool testRet = GetBundleDataMgr()->SetModuleRemovable(BUNDLE_NAME_TEST, MODULE_NAME_TEST, true); + EXPECT_TRUE(testRet); + bool testRet1 = GetBundleDataMgr()->IsModuleRemovable(BUNDLE_NAME_TEST, MODULE_NAME_TEST); + EXPECT_TRUE(testRet1); + + MockUninstallBundle(BUNDLE_NAME_TEST); +} + +/** + * @tc.number: CheckModuleRemovable_0300 + * @tc.name: test can check module removable is disable by setting + * @tc.desc: 1.system run normally + * 2.check the module removable successfully + */ +HWTEST_F(BmsBundleKitServiceTest, CheckModuleRemovable_0300, Function | SmallTest | Level1) +{ + MockInstallBundle(BUNDLE_NAME_TEST, MODULE_NAME_TEST, ABILITY_NAME_TEST); + + bool testRet = GetBundleDataMgr()->SetModuleRemovable(BUNDLE_NAME_TEST, MODULE_NAME_TEST, false); + EXPECT_TRUE(testRet); + bool testRet1 = GetBundleDataMgr()->IsModuleRemovable(BUNDLE_NAME_TEST, MODULE_NAME_TEST); + EXPECT_FALSE(testRet1); + + bool testRet2 = GetBundleDataMgr()->SetModuleRemovable(BUNDLE_NAME_TEST, MODULE_NAME_TEST, true); + EXPECT_TRUE(testRet2); + bool testRet3 = GetBundleDataMgr()->IsModuleRemovable(BUNDLE_NAME_TEST, MODULE_NAME_TEST); + EXPECT_TRUE(testRet3); + + MockUninstallBundle(BUNDLE_NAME_TEST); +} + +/** + * @tc.number: CheckModuleRemovable_0400 + * @tc.name: test can check module removable is disable by no install + * @tc.desc: 1.system run normally + * 2.check the module removable failed + */ +HWTEST_F(BmsBundleKitServiceTest, CheckModuleRemovable_0400, Function | SmallTest | Level1) +{ + bool testRet = GetBundleDataMgr()->IsModuleRemovable(BUNDLE_NAME_TEST, MODULE_NAME_TEST); + EXPECT_FALSE(testRet); +} + +/** + * @tc.number: CheckModuleRemovable_0500 + * @tc.name: test can check module removable is able by empty bundle name + * @tc.desc: 1.system run normally + * 2.check the module removable successfully + */ +HWTEST_F(BmsBundleKitServiceTest, CheckModuleRemovable_0500, Function | SmallTest | Level1) +{ + MockInstallBundle(BUNDLE_NAME_TEST, MODULE_NAME_TEST, ABILITY_NAME_TEST); + + bool testRet = GetBundleDataMgr()->SetModuleRemovable("", "", true); + EXPECT_FALSE(testRet); + bool testRet1 = GetBundleDataMgr()->IsModuleRemovable(BUNDLE_NAME_TEST, MODULE_NAME_TEST); + EXPECT_FALSE(testRet1); + + MockUninstallBundle(BUNDLE_NAME_TEST); +} + +/** + * @tc.number: CheckModuleRemovable_0600 + * @tc.name: test can check module removable is disable by empty bundle name + * @tc.desc: 1.system run normally + * 2.check the module removable failed + */ +HWTEST_F(BmsBundleKitServiceTest, CheckModuleRemovable_0600, Function | SmallTest | Level1) +{ + MockInstallBundle(BUNDLE_NAME_TEST, MODULE_NAME_TEST, ABILITY_NAME_TEST); + + bool testRet = GetBundleDataMgr()->SetModuleRemovable(BUNDLE_NAME_TEST, MODULE_NAME_TEST, true); + EXPECT_TRUE(testRet); + bool testRet1 = GetBundleDataMgr()->IsModuleRemovable("", ""); + EXPECT_FALSE(testRet1); + + MockUninstallBundle(BUNDLE_NAME_TEST); +} + /** * @tc.number: GetBundleInfo_0100 * @tc.name: test can get the bundleName's bundle info diff --git a/services/bundlemgr/test/unittest/bms_bundle_permission_grant_test/BUILD.gn b/services/bundlemgr/test/unittest/bms_bundle_permission_grant_test/BUILD.gn index 6c850957a..ed2dc59bb 100644 --- a/services/bundlemgr/test/unittest/bms_bundle_permission_grant_test/BUILD.gn +++ b/services/bundlemgr/test/unittest/bms_bundle_permission_grant_test/BUILD.gn @@ -109,6 +109,19 @@ ohos_unittest("BmsBundlePermissionGrantTest") { external_deps += [ "os_account_standard:os_account_innerkits" ] defines += [ "ACCOUNT_ENABLE" ] } + if (bundle_framework_free_install) { + sources += aging + include_dirs += + [ "${aafwk_path}/frameworks/kits/appkit/native/app/include" ] + deps += [ "${aafwk_path}/frameworks/kits/appkit:appkit_native" ] + external_deps += [ + "battery_manager_native:batterysrv_client", + "device_usage_statistics:usagestatsinner", + "display_manager_native:displaymgr", + "power_manager_native:powermgr_client", + ] + defines += [ "BUNDLE_FRAMEWORK_FREE_INSTALL" ] + } if (device_manager_enable) { sources += [ "${services_path}/bundlemgr/src/bms_device_manager.cpp" ] external_deps += [ "device_manager_base:devicemanagersdk" ] @@ -118,6 +131,7 @@ ohos_unittest("BmsBundlePermissionGrantTest") { external_deps += [ "hicollie_native:libhicollie" ] defines += [ "HICOLLIE_ENABLE" ] } + resource_config_file = "//foundation/appexecfwk/standard/test/resource/bundlemgrservice/ohos_test.xml" } diff --git a/services/bundlemgr/test/unittest/bms_bundle_uninstaller_test/BUILD.gn b/services/bundlemgr/test/unittest/bms_bundle_uninstaller_test/BUILD.gn index cc10effa2..9f11b8a39 100644 --- a/services/bundlemgr/test/unittest/bms_bundle_uninstaller_test/BUILD.gn +++ b/services/bundlemgr/test/unittest/bms_bundle_uninstaller_test/BUILD.gn @@ -107,6 +107,19 @@ ohos_unittest("BmsBundleUninstallerTest") { external_deps += [ "os_account_standard:os_account_innerkits" ] defines += [ "ACCOUNT_ENABLE" ] } + if (bundle_framework_free_install) { + sources += aging + include_dirs += + [ "${aafwk_path}/frameworks/kits/appkit/native/app/include" ] + deps += [ "${aafwk_path}/frameworks/kits/appkit:appkit_native" ] + external_deps += [ + "battery_manager_native:batterysrv_client", + "device_usage_statistics:usagestatsinner", + "display_manager_native:displaymgr", + "power_manager_native:powermgr_client", + ] + defines += [ "BUNDLE_FRAMEWORK_FREE_INSTALL" ] + } if (device_manager_enable) { sources += [ "${services_path}/bundlemgr/src/bms_device_manager.cpp" ] external_deps += [ "device_manager_base:devicemanagersdk" ] @@ -116,6 +129,7 @@ ohos_unittest("BmsBundleUninstallerTest") { external_deps += [ "hicollie_native:libhicollie" ] defines += [ "HICOLLIE_ENABLE" ] } + resource_config_file = "//foundation/appexecfwk/standard/test/resource/bundlemgrservice/ohos_test.xml" } diff --git a/services/bundlemgr/test/unittest/bms_bundle_updater_test/BUILD.gn b/services/bundlemgr/test/unittest/bms_bundle_updater_test/BUILD.gn index b4b4becd1..d524cc19d 100644 --- a/services/bundlemgr/test/unittest/bms_bundle_updater_test/BUILD.gn +++ b/services/bundlemgr/test/unittest/bms_bundle_updater_test/BUILD.gn @@ -111,6 +111,19 @@ ohos_unittest("BmsBundleUpdaterTest") { external_deps += [ "os_account_standard:os_account_innerkits" ] defines += [ "ACCOUNT_ENABLE" ] } + if (bundle_framework_free_install) { + sources += aging + include_dirs += + [ "${aafwk_path}/frameworks/kits/appkit/native/app/include" ] + deps += [ "${aafwk_path}/frameworks/kits/appkit:appkit_native" ] + external_deps += [ + "battery_manager_native:batterysrv_client", + "device_usage_statistics:usagestatsinner", + "display_manager_native:displaymgr", + "power_manager_native:powermgr_client", + ] + defines += [ "BUNDLE_FRAMEWORK_FREE_INSTALL" ] + } if (device_manager_enable) { sources += [ "${services_path}/bundlemgr/src/bms_device_manager.cpp" ] external_deps += [ "device_manager_base:devicemanagersdk" ] @@ -120,6 +133,7 @@ ohos_unittest("BmsBundleUpdaterTest") { external_deps += [ "hicollie_native:libhicollie" ] defines += [ "HICOLLIE_ENABLE" ] } + resource_config_file = "//foundation/appexecfwk/standard/test/resource/bundlemgrservice/ohos_test.xml" } diff --git a/services/bundlemgr/test/unittest/bms_data_mgr_test/BUILD.gn b/services/bundlemgr/test/unittest/bms_data_mgr_test/BUILD.gn index cb035a979..2e01af46a 100644 --- a/services/bundlemgr/test/unittest/bms_data_mgr_test/BUILD.gn +++ b/services/bundlemgr/test/unittest/bms_data_mgr_test/BUILD.gn @@ -101,6 +101,21 @@ ohos_unittest("BmsDataMgrTest") { external_deps += [ "os_account_standard:os_account_innerkits" ] defines += [ "ACCOUNT_ENABLE" ] } + if (bundle_framework_free_install) { + sources += aging + sources += + [ "${services_path}/bundlemgr/src/installd/installd_operator.cpp" ] + include_dirs += + [ "${aafwk_path}/frameworks/kits/appkit/native/app/include" ] + deps += [ "${aafwk_path}/frameworks/kits/appkit:appkit_native" ] + external_deps += [ + "battery_manager_native:batterysrv_client", + "device_usage_statistics:usagestatsinner", + "display_manager_native:displaymgr", + "power_manager_native:powermgr_client", + ] + defines += [ "BUNDLE_FRAMEWORK_FREE_INSTALL" ] + } if (device_manager_enable) { sources += [ "${services_path}/bundlemgr/src/bms_device_manager.cpp" ] external_deps += [ "device_manager_base:devicemanagersdk" ] diff --git a/services/bundlemgr/test/unittest/bms_service_bundle_scan_test/BUILD.gn b/services/bundlemgr/test/unittest/bms_service_bundle_scan_test/BUILD.gn index 8b42ff181..14e65d10e 100644 --- a/services/bundlemgr/test/unittest/bms_service_bundle_scan_test/BUILD.gn +++ b/services/bundlemgr/test/unittest/bms_service_bundle_scan_test/BUILD.gn @@ -90,6 +90,21 @@ ohos_unittest("BmsServiceBundleScanTest") { external_deps += [ "os_account_standard:os_account_innerkits" ] defines += [ "ACCOUNT_ENABLE" ] } + if (bundle_framework_free_install) { + sources += aging + sources += + [ "${services_path}/bundlemgr/src/installd/installd_operator.cpp" ] + include_dirs += + [ "${aafwk_path}/frameworks/kits/appkit/native/app/include" ] + deps += [ "${aafwk_path}/frameworks/kits/appkit:appkit_native" ] + external_deps += [ + "battery_manager_native:batterysrv_client", + "device_usage_statistics:usagestatsinner", + "display_manager_native:displaymgr", + "power_manager_native:powermgr_client", + ] + defines += [ "BUNDLE_FRAMEWORK_FREE_INSTALL" ] + } if (device_manager_enable) { sources += [ "${services_path}/bundlemgr/src/bms_device_manager.cpp" ] external_deps += [ "device_manager_base:devicemanagersdk" ] diff --git a/services/bundlemgr/test/unittest/bms_service_startup_test/BUILD.gn b/services/bundlemgr/test/unittest/bms_service_startup_test/BUILD.gn index c53dff44e..7f7de0fb5 100644 --- a/services/bundlemgr/test/unittest/bms_service_startup_test/BUILD.gn +++ b/services/bundlemgr/test/unittest/bms_service_startup_test/BUILD.gn @@ -90,6 +90,21 @@ ohos_unittest("BmsServiceStartupTest") { external_deps += [ "os_account_standard:os_account_innerkits" ] defines += [ "ACCOUNT_ENABLE" ] } + if (bundle_framework_free_install) { + sources += aging + sources += + [ "${services_path}/bundlemgr/src/installd/installd_operator.cpp" ] + include_dirs += + [ "${aafwk_path}/frameworks/kits/appkit/native/app/include" ] + deps += [ "${aafwk_path}/frameworks/kits/appkit:appkit_native" ] + external_deps += [ + "battery_manager_native:batterysrv_client", + "device_usage_statistics:usagestatsinner", + "display_manager_native:displaymgr", + "power_manager_native:powermgr_client", + ] + defines += [ "BUNDLE_FRAMEWORK_FREE_INSTALL" ] + } if (device_manager_enable) { sources += [ "${services_path}/bundlemgr/src/bms_device_manager.cpp" ] external_deps += [ "device_manager_base:devicemanagersdk" ] diff --git a/tools/bm/include/bundle_command.h b/tools/bm/include/bundle_command.h index 98cbb52c2..c48874264 100644 --- a/tools/bm/include/bundle_command.h +++ b/tools/bm/include/bundle_command.h @@ -34,7 +34,9 @@ const std::string HELP_MSG = "usage: bm \n" " clean clean the bundle data\n" " enable enable the bundle\n" " disable disable the bundle\n" - " get obtain device udid\n"; + " get obtain device udid\n" + " getrm obtain the value of isRemovable by given bundle name and module name\n" + " setrm set module isRemovable by given bundle name and module name\n"; const std::string HELP_MSG_INSTALL = "usage: bm install \n" @@ -97,6 +99,23 @@ const std::string HELP_MSG_GET = "options list:\n" " -u, --udid obtain udid of the current device\n"; +const std::string HELP_MSG_SET = + "usage: bm setrm \n" + "eg:bm setrm -m -n -i 1\n" + "options list:\n" + " -h, --help list available commands\n" + " -n, --bundle-name set isRemovable by moduleNmae and bundleName\n" + " -i, --is-removable set isRemovable 0 or 1\n" + " -m, --module-name set isRemovable by moduleNmae and bundleName\n"; + +const std::string HELP_MSG_GET_REMOVABLE = + "usage: bm getrm \n" + "eg:bm getrm -m -n \n" + "options list:\n" + " -h, --help list available commands\n" + " -n, --bundle-name get isRemovable by moduleNmae and bundleName\n" + " -m, --module-name get isRemovable by moduleNmae and bundleName\n"; + const std::string STRING_INCORRECT_OPTION = "error: incorrect option"; const std::string HELP_MSG_NO_BUNDLE_PATH_OPTION = "error: you must specify a bundle path with '-p' or '--bundle-path'."; @@ -127,8 +146,18 @@ const std::string STRING_DISABLE_BUNDLE_NG = "error: failed to disable bundle."; const std::string STRING_GET_UDID_OK = "udid of current device is :"; const std::string STRING_GET_UDID_NG = "error: failed to get udid"; +const std::string STRING_GET_REMOVABLE_OK = "get removable is ok"; +const std::string STRING_GET_REMOVABLE_NG = "error: failed to get removable"; + +const std::string STRING_SET_REMOVABLE_OK = "set removable is ok"; +const std::string STRING_SET_REMOVABLE_NG = "error: failed to set removable"; + +const std::string HELP_MSG_NO_REMOVABLE_OPTION = + "error: you must specify a bundle name with '-n' or '--bundle-name' \n" + "and a module name with '-m' or '--module-name' \n"; + const std::string HELP_MSG_DUMP_FAILED = "error: failed to get information and the parameters may be wrong."; -} // namespace +} // namespace class BundleManagerShellCommand : public ShellCommand { public: @@ -152,6 +181,8 @@ private: ErrCode RunAsEnableCommand(); ErrCode RunAsDisableCommand(); ErrCode RunAsGetCommand(); + ErrCode RunAsSetRmCommand(); + ErrCode RunAsGetRmCommand(); std::string DumpBundleList(int32_t userId) const; std::string DumpBundleInfo(const std::string &bundleName, int32_t userId) const; @@ -170,7 +201,10 @@ private: bool CleanBundleDataFilesOperation(const std::string &bundleName, int32_t userId) const; bool SetApplicationEnabledOperation(const AbilityInfo &abilityInfo, bool isEnable, int32_t userId) const; + bool SetIsRemovableOperation(const std::string &bundleName, const std::string &moduleName, bool enable) const; + bool GetIsRemovableOperation( + const std::string &bundleName, const std::string &moduleName, std::string &result) const; int32_t GetCurrentUserId(int32_t userId) const; sptr bundleMgrProxy_; diff --git a/tools/bm/src/bundle_command.cpp b/tools/bm/src/bundle_command.cpp index d61d90bab..e4cfcd56c 100644 --- a/tools/bm/src/bundle_command.cpp +++ b/tools/bm/src/bundle_command.cpp @@ -42,7 +42,7 @@ const int32_t INDEX_OFFSET = 2; const int32_t MAX_WAITING_TIME = 3000; const int32_t DEVICE_UDID_LENGTH = 65; const int32_t MAX_ARGUEMENTS_NUMBER = 3; -const std::string SHORT_OPTIONS = "hp:rfn:m:a:cdu:"; +const std::string SHORT_OPTIONS = "hp:rfn:m:a:cdu:i:"; const struct option LONG_OPTIONS[] = { {"help", no_argument, nullptr, 'h'}, {"bundle-path", required_argument, nullptr, 'p'}, @@ -53,6 +53,7 @@ const struct option LONG_OPTIONS[] = { {"bundle-info", no_argument, nullptr, 'i'}, {"cache", no_argument, nullptr, 'c'}, {"data", no_argument, nullptr, 'd'}, + {"is-removable", required_argument, nullptr, 'i'}, {"user-id", required_argument, nullptr, 'u'}, {nullptr, 0, nullptr, 0}, }; @@ -126,6 +127,8 @@ ErrCode BundleManagerShellCommand::CreateCommandMap() {"enable", std::bind(&BundleManagerShellCommand::RunAsEnableCommand, this)}, {"disable", std::bind(&BundleManagerShellCommand::RunAsDisableCommand, this)}, {"get", std::bind(&BundleManagerShellCommand::RunAsGetCommand, this)}, + {"getrm", std::bind(&BundleManagerShellCommand::RunAsGetRmCommand, this)}, + {"setrm", std::bind(&BundleManagerShellCommand::RunAsSetRmCommand, this)}, }; return OHOS::ERR_OK; @@ -1465,6 +1468,295 @@ ErrCode BundleManagerShellCommand::RunAsGetCommand() return result; } +ErrCode BundleManagerShellCommand::RunAsSetRmCommand() +{ + int result = OHOS::ERR_OK; + int option = -1; + int counter = 0; + int isRemovable = 0; + bool enable = false; + bool setRemovable = false; + std::string bundleName = ""; + std::string moduleName = ""; + APP_LOGD("RunAsSetCommand is start"); + while (true) { + counter++; + option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr); + APP_LOGD("option: %{public}c, optopt: %{public}d, optind: %{public}d, argv_[optind - 1]:%{public}s", option, + optopt, optind, argv_[optind - 1]); + if (optind < 0 || optind > argc_) { + return OHOS::ERR_INVALID_VALUE; + } + + if (option == -1) { + if (counter == 1) { + // When scanning the first argument + if (strcmp(argv_[optind], cmd_.c_str()) == 0) { + // 'bm setrmrm' with no option: bm setrm + // 'bm setrm' with a wrong argument: bm setrm xxx + APP_LOGD("'bm setrm' with no option."); + resultReceiver_.append(HELP_MSG_NO_OPTION + "\n"); + result = OHOS::ERR_INVALID_VALUE; + } + } + break; + } + + if (option == '?') { + switch (optopt) { + case 'i': { + // 'bm setrm -i' with no argument: bm setrm -i + // 'bm setrm --is-removable' with no argument: bm setrm --is-removable + APP_LOGD("'bm setrm -i' with no argument."); + resultReceiver_.append("error: -i option "); + resultReceiver_.append("requires a value.\n"); + result = OHOS::ERR_INVALID_VALUE; + break; + } + case 'm': { + // 'bm setrm -m' with no argument: bm setrm -m + // 'bm setrm --module-name' with no argument: bm setrm --module-name + APP_LOGD("'bm setrm -m' with no argument."); + resultReceiver_.append("error: -m option "); + resultReceiver_.append("requires a value.\n"); + result = OHOS::ERR_INVALID_VALUE; + break; + } + case 'n': { + // 'bm setrm -n' with no argument: bm setrm -n + // 'bm setrm --bundle-name' with no argument: bm setrm --bundle-name + APP_LOGD("'bm setrm -n' with no argument."); + resultReceiver_.append("error: -n option "); + resultReceiver_.append("requires a value.\n"); + result = OHOS::ERR_INVALID_VALUE; + break; + } + default: { + // 'bm setrm' with an unknown option: bm setrm -x + // 'bm setrm' with an unknown option: bm setrm -xxx + std::string unknownOption = ""; + std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption); + APP_LOGD("'bm setrm' with an unknown option."); + resultReceiver_.append(unknownOptionMsg); + result = OHOS::ERR_INVALID_VALUE; + break; + } + } + break; + } + + switch (option) { + case 'h': { + // 'bm setrm -h' + // 'bm setrm --help' + APP_LOGD("'bm setrm %{public}s'", argv_[optind - 1]); + result = OHOS::ERR_INVALID_VALUE; + break; + } + case 'n': { + // 'bm setrm -n ' + // 'bm setrm --bundle-name ' + bundleName = optarg; + APP_LOGD("'bm setrm -n %{public}s'", argv_[optind - 1]); + break; + } + case 'i': { + // 'bm setrm -i <1/0>' + // 'bm setrm --is-removable <1/0>' + isRemovable = std::stoi(optarg); + APP_LOGD("'bm setrm -i isRemovable:%{public}d, %{public}s'", isRemovable, argv_[optind - 1]); + if (isRemovable == 1) { + enable = true; + } else if (isRemovable == 0) { + enable = false; + } + setRemovable = true; + break; + } + case 'm': { + // 'bm setrm -m ' + // 'bm setrm --module-name ' + moduleName = optarg; + APP_LOGD("'bm setrm -m module-name:%{public}s, %{public}s'", moduleName.c_str(), argv_[optind - 1]); + break; + } + default: { + result = OHOS::ERR_INVALID_VALUE; + break; + } + } + } + + if (result == OHOS::ERR_OK) { + if (resultReceiver_ == "" && (bundleName.size() == 0 || moduleName.size() == 0)) { + // 'bm setrm ...' with no option + APP_LOGD("'bm setrm' with no option."); + resultReceiver_.append(HELP_MSG_NO_REMOVABLE_OPTION + "\n"); + result = OHOS::ERR_INVALID_VALUE; + } + } + + if (result != OHOS::ERR_OK) { + resultReceiver_.append(HELP_MSG_SET); + } else { + bool setResult = false; + if (setRemovable) { + setResult = SetIsRemovableOperation(bundleName, moduleName, enable); + APP_LOGD("'bm setrm' isRemovable is %{public}d", isRemovable); + } + + if (setResult == true) { + resultReceiver_ = STRING_SET_REMOVABLE_OK + "\n"; + } else { + resultReceiver_ = STRING_SET_REMOVABLE_NG + "\n"; + } + } + return result; +} + +ErrCode BundleManagerShellCommand::RunAsGetRmCommand() +{ + int result = OHOS::ERR_OK; + int option = -1; + int counter = 0; + std::string bundleName = ""; + std::string moduleName = ""; + std::string getResults = ""; + APP_LOGD("RunAsGetRmCommand is start"); + while (true) { + counter++; + option = getopt_long(argc_, argv_, SHORT_OPTIONS.c_str(), LONG_OPTIONS, nullptr); + APP_LOGD("option: %{public}d, optopt: %{public}d, optind: %{public}d", option, optopt, optind); + if (optind < 0 || optind > argc_) { + return OHOS::ERR_INVALID_VALUE; + } + + if (option == -1) { + if (counter == 1) { + // When scanning the first argument + if (strcmp(argv_[optind], cmd_.c_str()) == 0) { + // 'bm getrm' with no option: bm getrm + // 'bm getrm' with a wrong argument: bm getrm xxx + APP_LOGD("'bm getrm' with no option."); + resultReceiver_.append(HELP_MSG_NO_OPTION + "\n"); + result = OHOS::ERR_INVALID_VALUE; + } + } + break; + } + + if (option == '?') { + switch (optopt) { + case 'n': { + // 'bm getrm -n' with no argument: bm getrm -n + // 'bm getrm --bundle-name' with no argument: bm getrm --bundle-name + APP_LOGD("'bm getrm -n' with no argument."); + resultReceiver_.append("error: option "); + resultReceiver_.append("requires a value.\n"); + result = OHOS::ERR_INVALID_VALUE; + break; + } + case 'm': { + // 'bm getrm -m' with no argument: bm getrm -m + // 'bm getrm --module-name' with no argument: bm getrm --module-name + APP_LOGD("'bm getrm -m' with no argument."); + resultReceiver_.append("error: option "); + resultReceiver_.append("requires a value.\n"); + result = OHOS::ERR_INVALID_VALUE; + break; + } + default: { + // 'bm getrm' with an unknown option: bm getrm -x + // 'bm getrm' with an unknown option: bm getrm -xxx + std::string unknownOption = ""; + std::string unknownOptionMsg = GetUnknownOptionMsg(unknownOption); + APP_LOGD("'bm getrm' with an unknown option."); + resultReceiver_.append(unknownOptionMsg); + result = OHOS::ERR_INVALID_VALUE; + break; + } + } + break; + } + + switch (option) { + case 'h': { + // 'bm getrm -h' + // 'bm getrm --help' + APP_LOGD("'bm getrm %{public}s'", argv_[optind - 1]); + result = OHOS::ERR_INVALID_VALUE; + break; + } + case 'n': { + // 'bm getrm -n ' + // 'bm getrm --bundle-name ' + bundleName = optarg; + break; + } + case 'm': { + // 'bm getrm -m ' + // 'bm getrm --module-name ' + moduleName = optarg; + APP_LOGD("'bm getrm -m module-name:%{public}s, %{public}s'", moduleName.c_str(), argv_[optind - 1]); + break; + } + default: { + result = OHOS::ERR_INVALID_VALUE; + break; + } + } + } + + if (result == OHOS::ERR_OK) { + if (resultReceiver_ == "" && (bundleName.size() == 0 || moduleName.size() == 0)) { + // 'bm getrm ...' with no option + APP_LOGD("'bm getrm' with no option."); + resultReceiver_.append(HELP_MSG_NO_REMOVABLE_OPTION + "\n"); + result = OHOS::ERR_INVALID_VALUE; + } + } + + if (result != OHOS::ERR_OK) { + resultReceiver_.append(HELP_MSG_GET_REMOVABLE); + return result; + } else { + std::string results = ""; + GetIsRemovableOperation(bundleName, moduleName, results); + if (results.empty()) { + resultReceiver_.append(STRING_GET_REMOVABLE_NG); + return result; + } + resultReceiver_.append(results); + return result; + } +} + +bool BundleManagerShellCommand::SetIsRemovableOperation( + const std::string &bundleName, const std::string &moduleName, bool enable) const +{ + APP_LOGD("bundleName: %{public}s, moduleName:%{public}s, enable:%{public}d", bundleName.c_str(), moduleName.c_str(), + enable); + auto ret = bundleMgrProxy_->SetModuleRemovable(bundleName, moduleName, enable); + APP_LOGD("SetModuleRemovable end bundleName: %{public}d", ret); + if (!ret) { + APP_LOGE("SetIsRemovableOperation failed"); + return false; + } + return ret; +} + +bool BundleManagerShellCommand::GetIsRemovableOperation( + const std::string &bundleName, const std::string &moduleName, std::string &result) const +{ + APP_LOGD("bundleName: %{public}s, moduleName:%{public}s", bundleName.c_str(), moduleName.c_str()); + auto ret = bundleMgrProxy_->IsModuleRemovable(bundleName, moduleName); + APP_LOGD("IsModuleRemovable end bundleName: %{public}s, ret:%{public}d", bundleName.c_str(), ret); + result.append("isRemovable: "); + result.append(std::to_string(ret)); + result.append("\n"); + return ret; +} + std::string BundleManagerShellCommand::GetUdid() const { char innerUdid[DEVICE_UDID_LENGTH] = { 0 }; diff --git a/tools/zip/BUILD.gn b/tools/zip/BUILD.gn index ad5f8e807..b9d7a3375 100644 --- a/tools/zip/BUILD.gn +++ b/tools/zip/BUILD.gn @@ -56,7 +56,7 @@ ohos_shared_library("zlib") { ] external_deps = [ - "ability_runtime:task_dispatcher", + "ability_base:task_dispatcher", "bundle_framework:appexecfwk_base", "hilog_native:libhilog_base", "hiviewdfx_hilog_native:libhilog", diff --git a/tools/zip/test/BUILD.gn b/tools/zip/test/BUILD.gn index 74e196e77..0451d4907 100644 --- a/tools/zip/test/BUILD.gn +++ b/tools/zip/test/BUILD.gn @@ -51,7 +51,7 @@ ohos_unittest("zip_test") { ] external_deps = [ - "ability_runtime:task_dispatcher", + "ability_base:task_dispatcher", "bundle_framework:appexecfwk_base", "hiviewdfx_hilog_native:libhilog", "ipc:ipc_core",