From a094b5938bc982c8a288c27ba2c6c0d1be7290cb Mon Sep 17 00:00:00 2001 From: liujuan1018 Date: Sun, 27 Mar 2022 01:26:25 +0800 Subject: [PATCH 1/2] IssueNo:add agingClean base code Description: add agingClean base code Sig:SIG_ApplicationFramework Feature or Bugfix: Feature Binary Source: No Signed-off-by: liujuan Change-Id: Ibbd4d372747eab253da0f0ecb27f04caab1016da --- .../include/application_info.h | 1 + .../appexecfwk_base/include/hap_module_info.h | 1 + .../include/bundlemgr/bundle_mgr_host.h | 7 + .../include/bundlemgr/bundle_mgr_interface.h | 8 + .../include/bundlemgr/bundle_mgr_proxy.h | 7 + .../src/bundlemgr/bundle_mgr_host.cpp | 18 ++ .../src/bundlemgr/bundle_mgr_proxy.cpp | 31 +++ kits/appkit/napi/bundlemgr/bundle_mgr.cpp | 215 ++++++++++++++++++ kits/appkit/napi/bundlemgr/bundle_mgr.h | 13 ++ kits/appkit/napi/bundlemgr/native_module.cpp | 1 + services/bundlemgr/BUILD.gn | 8 + services/bundlemgr/appexecfwk_bundlemgr.gni | 9 + .../include/aging/aging_bundle_info.h | 55 +++++ .../bundlemgr/include/aging/aging_constants.h | 51 +++++ .../bundlemgr/include/aging/aging_handler.h | 74 ++++++ .../include/aging/aging_handler_chain.h | 39 ++++ .../bundlemgr/include/aging/aging_request.h | 78 +++++++ services/bundlemgr/include/aging/aging_util.h | 37 +++ .../include/aging/bundle_aging_mgr.h | 69 ++++++ services/bundlemgr/include/bundle_data_mgr.h | 38 ++++ .../bundlemgr/include/bundle_mgr_host_impl.h | 7 + .../bundlemgr/include/bundle_mgr_service.h | 4 + .../bundlemgr/include/inner_bundle_info.h | 30 +++ .../src/aging/aging_handler_chain.cpp | 54 +++++ .../bundlemgr/src/aging/aging_request.cpp | 80 +++++++ services/bundlemgr/src/aging/aging_util.cpp | 52 +++++ .../bundlemgr/src/aging/bundle_aging_mgr.cpp | 195 ++++++++++++++++ .../aging/bundle_data_size_aging_handler.cpp | 36 +++ .../over_10days_unsed_bundle_agin_handler.cpp | 34 +++ .../over_20days_unsed_bundle_agin_handler.cpp | 34 +++ .../over_30days_unsed_bundle_agin_handler.cpp | 34 +++ .../recently_unused_bundle_aging_handler.cpp | 115 ++++++++++ .../bundlemgr/src/base_bundle_installer.cpp | 14 ++ services/bundlemgr/src/bundle_data_mgr.cpp | 175 +++++++++++++- .../bundlemgr/src/bundle_mgr_host_impl.cpp | 10 + services/bundlemgr/src/bundle_mgr_service.cpp | 18 ++ services/bundlemgr/src/inner_bundle_info.cpp | 38 ++++ .../bms_bundle_kit_service_test/BUILD.gn | 8 + .../bms_bundle_kit_service_test.cpp | 105 +++++++++ 39 files changed, 1802 insertions(+), 1 deletion(-) 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_unsed_bundle_agin_handler.cpp create mode 100644 services/bundlemgr/src/aging/over_20days_unsed_bundle_agin_handler.cpp create mode 100644 services/bundlemgr/src/aging/over_30days_unsed_bundle_agin_handler.cpp create mode 100644 services/bundlemgr/src/aging/recently_unused_bundle_aging_handler.cpp diff --git a/interfaces/innerkits/appexecfwk_base/include/application_info.h b/interfaces/innerkits/appexecfwk_base/include/application_info.h index 07e3aea3..7d3170f1 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 205594d5..50296a58 100644 --- a/interfaces/innerkits/appexecfwk_base/include/hap_module_info.h +++ b/interfaces/innerkits/appexecfwk_base/include/hap_module_info.h @@ -68,6 +68,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_core/include/bundlemgr/bundle_mgr_host.h b/interfaces/innerkits/appexecfwk_core/include/bundlemgr/bundle_mgr_host.h index 7f174ba4..6c21b2d0 100644 --- a/interfaces/innerkits/appexecfwk_core/include/bundlemgr/bundle_mgr_host.h +++ b/interfaces/innerkits/appexecfwk_core/include/bundlemgr/bundle_mgr_host.h @@ -551,6 +551,13 @@ private: ErrCode HandleGetAbilityPixelMapIcon(Parcel &data, Parcel &reply); #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); private: /** * @brief Write a parcelabe vector objects to the proxy node. 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 5b42a344..5848cb3c 100644 --- a/interfaces/innerkits/appexecfwk_core/include/bundlemgr/bundle_mgr_interface.h +++ b/interfaces/innerkits/appexecfwk_core/include/bundlemgr/bundle_mgr_interface.h @@ -716,6 +716,13 @@ 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 abilityInfo is successfully obtained; returns false otherwise. + */ + virtual bool IsModuleRemovable(const std::string &bundleName, const std::string &moduleName) = 0; enum class Message { GET_APPLICATION_INFO = 0, @@ -798,6 +805,7 @@ public: VERIFY_CALLING_PERMISSION, GET_ACCESSIBLE_APP_CODE_PATH, QUERY_EXTENSION_ABILITY_INFO_BY_URI, + IS_MODULE_REMOVABLE, }; }; } // namespace AppExecFwk 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 905bee76..73f31ab9 100644 --- a/interfaces/innerkits/appexecfwk_core/include/bundlemgr/bundle_mgr_proxy.h +++ b/interfaces/innerkits/appexecfwk_core/include/bundlemgr/bundle_mgr_proxy.h @@ -638,6 +638,13 @@ 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; private: /** * @brief Send a command message from the proxy object. 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 b7072241..944b625c 100644 --- a/interfaces/innerkits/appexecfwk_core/src/bundlemgr/bundle_mgr_host.cpp +++ b/interfaces/innerkits/appexecfwk_core/src/bundlemgr/bundle_mgr_host.cpp @@ -307,6 +307,9 @@ 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; default: return IPCObjectStub::OnRemoteRequest(code, data, reply, option); } @@ -1832,6 +1835,21 @@ 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; +} + template bool BundleMgrHost::WriteParcelableVector(std::vector &parcelableVector, Parcel &reply) { 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 6c141cce..f98c1339 100644 --- a/interfaces/innerkits/appexecfwk_core/src/bundlemgr/bundle_mgr_proxy.cpp +++ b/interfaces/innerkits/appexecfwk_core/src/bundlemgr/bundle_mgr_proxy.cpp @@ -1425,6 +1425,37 @@ 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::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 7864088e..f9230fee 100644 --- a/kits/appkit/napi/bundlemgr/bundle_mgr.cpp +++ b/kits/appkit/napi/bundlemgr/bundle_mgr.cpp @@ -5155,6 +5155,221 @@ 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 = INVALID_PARAM; + 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 = INVALID_PARAM; + asyncCallbackInfo->errMssage = "type misMatch"; + } + + 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 c0b8a96c..f3010bd0 100644 --- a/kits/appkit/napi/bundlemgr/bundle_mgr.h +++ b/kits/appkit/napi/bundlemgr/bundle_mgr.h @@ -153,6 +153,18 @@ struct AsyncAbilityLabelCallbackInfo { 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; @@ -375,6 +387,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 485dbfc3..27c69c8a 100644 --- a/kits/appkit/napi/bundlemgr/native_module.cpp +++ b/kits/appkit/napi/bundlemgr/native_module.cpp @@ -120,6 +120,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 883150a1..ea41ac0b 100644 --- a/services/bundlemgr/BUILD.gn +++ b/services/bundlemgr/BUILD.gn @@ -18,6 +18,8 @@ import( config("bundlemgr_common_config") { include_dirs = [ + "//base/powermgr/display_manager/utils/native/include", + "//base/sensors/sensor/interfaces/native/include", "include", "//utils/system/safwk/native/include", ] @@ -140,6 +142,7 @@ ohos_shared_library("libbms") { "src/bundle_user_mgr_host_impl.cpp", "src/distributed_data_storage.cpp", "src/hidump_helper.cpp", + "src/installd/installd_operator.cpp", "src/kvstore_death_recipient_callback.cpp", "src/module_usage_data_storage.cpp", "src/permission_changed_death_recipient.cpp", @@ -157,6 +160,7 @@ ohos_shared_library("libbms") { cflags += [ "-DBINDER_IPC_32BIT" ] } deps = [ + "//base/powermgr/display_manager/service:displaymgrservice", ":bundle_parser", ":parser_common", "${common_path}:libappexecfwk_common", @@ -167,19 +171,23 @@ ohos_shared_library("libbms") { "ability_runtime:app_manager", "access_token:libaccesstoken_sdk", "appverify:libhapverify", + "battery_manager_native:batterysrv_client", "bundle_framework:appexecfwk_base", "bundle_framework:appexecfwk_core", "bytrace_standard:bytrace_core", "ces_standard:cesfwk_core", "ces_standard:cesfwk_innerkits", + "display_manager_native:displaymgr", "distributeddatamgr:distributeddata_inner", "eventhandler:libeventhandler", "hiviewdfx_hilog_native:libhilog", "init:libbegetutil", "ipc:ipc_core", "resmgr_standard:global_resmgr", + "power_manager_native:powermgr_client", "safwk:system_ability_fwk", "samgr_standard:samgr_proxy", + "sensor:sensor_interface_native", "startup_l2:syspara", ] diff --git a/services/bundlemgr/appexecfwk_bundlemgr.gni b/services/bundlemgr/appexecfwk_bundlemgr.gni index 0bdbe895..03c2dec9 100644 --- a/services/bundlemgr/appexecfwk_bundlemgr.gni +++ b/services/bundlemgr/appexecfwk_bundlemgr.gni @@ -40,6 +40,15 @@ bundle_install_sources = [ "${services_path}/bundlemgr/src/pre_install_bundle_info.cpp", "${services_path}/bundlemgr/src/system_bundle_installer.cpp", "${services_path}/bundlemgr/src/xcollie_helper.cpp", + "${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_unsed_bundle_agin_handler.cpp", + "${services_path}/bundlemgr/src/aging/over_20days_unsed_bundle_agin_handler.cpp", + "${services_path}/bundlemgr/src/aging/over_30days_unsed_bundle_agin_handler.cpp", + "${services_path}/bundlemgr/src/aging/recently_unused_bundle_aging_handler.cpp", ] bundle_install_deps = [ 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 00000000..1b73c35d --- /dev/null +++ b/services/bundlemgr/include/aging/aging_bundle_info.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2021-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) + : bundleName(name), recentlyUsedTime(time), dataBytes(bundleDataBytes) + { + }; + virtual ~AgingBundleInfo() = default; + + const std::string &GetBundleName() const + { + return bundleName; + }; + + int64_t GetRecentlyUsedTime() const + { + return recentlyUsedTime; + }; + + int64_t GetDataBytes() const + { + return dataBytes; + }; + +private: + std::string bundleName; + int64_t recentlyUsedTime = 0; + int64_t dataBytes = 0; +}; +} // 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 00000000..c7831db2 --- /dev/null +++ b/services/bundlemgr/include/aging/aging_constants.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2021-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 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 \ No newline at end of file diff --git a/services/bundlemgr/include/aging/aging_handler.h b/services/bundlemgr/include/aging/aging_handler.h new file mode 100644 index 00000000..4eaf53fa --- /dev/null +++ b/services/bundlemgr/include/aging/aging_handler.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2021-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 "aging_request.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; + bool CanStart(const AgingRequest &request) const; + virtual bool Process(AgingRequest &request) const override; + virtual bool CheckBundle(const AgingBundleInfo &bundle) const = 0; + virtual bool NeedContinue(const AgingRequest &requese) const; + +private: + bool UnInstallBundle(const std::string &bundlename) const; + bool IsBundleRunning(const std::string &bundlename) const; +}; + +class Over30DaysUnsedBundleAginHandler : public RecentlyUnuseBundleAgingHandler { +public: + bool CheckBundle(const AgingBundleInfo &bundle) const override; + const std::string &GetName() const override; +}; + +class Over20DaysUnsedBundleAginHandler : public RecentlyUnuseBundleAgingHandler { +public: + bool CheckBundle(const AgingBundleInfo &bundle) const override; + const std::string &GetName() const override; +}; + +class Over10DaysUnsedBundleAginHandler : public RecentlyUnuseBundleAgingHandler { +public: + bool CheckBundle(const AgingBundleInfo &bundle) const override; + const std::string &GetName() const override; +}; + +class BundleDataSizeAginHandler : public RecentlyUnuseBundleAgingHandler { +public: + bool CanStart(const AgingRequest &request) const; + bool CheckBundle(const AgingBundleInfo &bundle) const override; + const std::string &GetName() const 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 00000000..9288da90 --- /dev/null +++ b/services/bundlemgr/include/aging/aging_handler_chain.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2021-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 00000000..d72b8f21 --- /dev/null +++ b/services/bundlemgr/include/aging/aging_request.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2021-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(); + ~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(int64_t dataBytes) + { + tatalDataBytes -= dataBytes; + }; + int64_t GetTotalDataBytes() + { + return tatalDataBytes; + }; + void SetTotalDataBytes(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 00000000..6141e277 --- /dev/null +++ b/services/bundlemgr/include/aging/aging_util.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2021-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 00000000..5af9f9ff --- /dev/null +++ b/services/bundlemgr/include/aging/bundle_aging_mgr.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2021-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 2f76d9a2..03beba32 100644 --- a/services/bundlemgr/include/bundle_data_mgr.h +++ b/services/bundlemgr/include/bundle_data_mgr.h @@ -631,6 +631,11 @@ public: * @return Returns all userId. */ std::set GetAllUser() const; + /** + * @brief Get active user. + * @return Returns active userId. + */ + int32_t GetActiveUserId() const; /** * @brief Obtains the DistributedBundleInfo based on a given bundle name and networkId. * @param networkId Indicates the networkId of remote device. @@ -699,10 +704,43 @@ public: const std::string &excludeModule = "") const; bool AddInnerBundleUserInfo(const std::string &bundleName, const InnerBundleUserInfo& newUserInfo); bool RemoveInnerBundleUserInfo(const std::string &bundleName, int32_t userId); + bool GetRemovableBundleNameVec(std::vector& bundlenames); #ifdef SUPPORT_GRAPHICS std::shared_ptr GetAbilityPixelMapIcon(const std::string &bundleName, const std::string &abilityName) const; #endif + /** + * @brief Set Module isRemovable by bundleName & 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 & 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; + /** + * @brief Get bundle isRemovable by innerBundleInfo. + * @param innerBundleInfo Indicates the map of deviced id and InnerBundleInfo. + * @return Returns true if the bunlde isRemovable is successfully obtained; returns false otherwise. + */ + bool IsBundleRemovable(std::map &innerBundleInfo) const; + /** + * @brief Get bundle space size 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. + * @return Returns the space size of all free install bundles. + */ + int64_t GetAllFreeInstallBundleSpaceSize() const; private: /** * @brief Init transferStates. diff --git a/services/bundlemgr/include/bundle_mgr_host_impl.h b/services/bundlemgr/include/bundle_mgr_host_impl.h index 5a0652a7..a70b3a86 100644 --- a/services/bundlemgr/include/bundle_mgr_host_impl.h +++ b/services/bundlemgr/include/bundle_mgr_host_impl.h @@ -629,6 +629,13 @@ 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 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; private: const std::shared_ptr GetCloneMgrFromService(); const std::shared_ptr GetDataMgrFromService(); diff --git a/services/bundlemgr/include/bundle_mgr_service.h b/services/bundlemgr/include/bundle_mgr_service.h index 0a125021..97f6fc19 100644 --- a/services/bundlemgr/include/bundle_mgr_service.h +++ b/services/bundlemgr/include/bundle_mgr_service.h @@ -21,6 +21,7 @@ #include "singleton.h" #include "system_ability.h" +#include "aging/bundle_aging_mgr.h" #ifdef DEVICE_MANAGER_ENABLE #include "bms_device_manager.h" #endif @@ -63,6 +64,8 @@ public: const std::shared_ptr GetCloneMgr() const; const std::shared_ptr GetDataMgr() const; + + const std::shared_ptr GetAgingMgr() const; /** * @brief Get a IBundleInstaller object for IPC * @return Returns the pointer of IBundleInstaller object. @@ -122,6 +125,7 @@ private: std::shared_ptr deviceManager_; #endif std::shared_ptr hidumpHelper_; + std::shared_ptr agingMgr_; 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 772234ce..fa2b7bf9 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; @@ -952,6 +953,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; @@ -1344,6 +1355,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 00000000..42c901d7 --- /dev/null +++ b/services/bundlemgr/src/aging/aging_handler_chain.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2021-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_LOGD("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 00000000..5c8c364c --- /dev/null +++ b/services/bundlemgr/src/aging/aging_request.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2021-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 * AgingConstants::ONE_KB; +int64_t AgingRequest::oneDayTimeMs = AgingConstants::ONE_DAYS_MS; +AgingRequest::AgingRequest() +{ + InitAgingPolicySystemParameters(); +} +AgingRequest::~AgingRequest() +{ + // TO DO +} + +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(szDatasizeThreshold, "") != 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 00000000..b96fec9f --- /dev/null +++ b/services/bundlemgr/src/aging/aging_util.cpp @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2021-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_bundle_info.h" +#include "aging/aging_constants.h" +#include "aging/aging_request.h" +#include "aging/aging_util.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.GetRecentlyUsedTime() > bundle2.GetRecentlyUsedTime(); + } else if (bundle1.GetRecentlyUsedTime() > unusedTime && + bundle2.GetRecentlyUsedTime() < unusedTime) { + return true; + } else if (bundle1.GetRecentlyUsedTime() < unusedTime && + bundle2.GetRecentlyUsedTime() > unusedTime) { + return false; + } else if (bundle1.GetRecentlyUsedTime() < unusedTime && + bundle2.GetRecentlyUsedTime() < unusedTime) { + return bundle1.GetDataBytes() > bundle1.GetDataBytes(); + } + 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 00000000..08ba2351 --- /dev/null +++ b/services/bundlemgr/src/aging/bundle_aging_mgr.cpp @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2021-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_mgr_service.h" +#include "display_power_mgr_client.h" +#include "display_power_mgr_service.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_TIMER_INTERVAL; + } 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_LOGD("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::vector bundleNames; + dataMgr->GetRemovableBundleNameVec(bundleNames); + if (bundleNames.empty()) { + APP_LOGE("ReInitAginRequst: no removable bundles"); + return false; + } + APP_LOGD("ReInitAginRequst: removable bundles size %{public}d", bundleNames.size()); + for (auto iter : bundleNames) { + int64_t dataBytes = dataMgr->GetBundleSpaceSize(iter); + // int64_t lastLaunchTimesMs = dataMgr->lastLaunchTimesMs(); + int64_t lastLaunchTimesMs = 0; + AgingBundleInfo agingBundleInfo(iter, lastLaunchTimesMs, dataBytes); + 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)) { + chain.Process(request); + } + { + std::lock_guard lock(mutex_); + running = false; + } + APP_LOGD("BundleAgingMgr Process done"); +} + +void BundleAgingMgr::Start(AgingTriggertype type) +{ + if (!CheckPrerequisite(type)) { + APP_LOGD("BundleAgingMgr aging Prerequisite is not satisfied"); + } + + auto dataMgr = OHOS::DelayedSingleton::GetInstance()->GetDataMgr(); + if (!dataMgr) { + APP_LOGD("dataMgr is null"); + return; + } + { + std::lock_guard lock(mutex_); + if (running) { + APP_LOGD("BundleAgingMgr is running, no need to start is aggin"); + return; + } + running = true; + } + + auto task = [&, dataMgr]() { Process(dataMgr); }; + bool isEventStarted = SendEvent(InnerEvent::Get(task)); + if (!isEventStarted) { + APP_LOGD("BundleAgingMgr ecet 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(); + 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 \ No newline at end of file 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 00000000..eceb59b0 --- /dev/null +++ b/services/bundlemgr/src/aging/bundle_data_size_aging_handler.cpp @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2021-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 BundleDataSizeAginHandler::CanStart(const AgingRequest &request) const +{ + return request.IsReachStartAgingThreshold(); +} +bool BundleDataSizeAginHandler::CheckBundle(const AgingBundleInfo &bundle) const +{ + // the size of all app is bigger than 0 + return true; +} + +const std::string &BundleDataSizeAginHandler::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_unsed_bundle_agin_handler.cpp b/services/bundlemgr/src/aging/over_10days_unsed_bundle_agin_handler.cpp new file mode 100644 index 00000000..609c995e --- /dev/null +++ b/services/bundlemgr/src/aging/over_10days_unsed_bundle_agin_handler.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021-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 Over10DaysUnsedBundleAginHandler::CheckBundle(const AgingBundleInfo &bundle) const +{ + // There isn't interface of not used by the app,just return false first + // return AgingUtil::GetNowSysTimeMs() - bundle.GetRecentlyUsedTime() > + // ((int64_t)AgingConstants::TIME_10_DAYS * AgingRequest::GetOneDayTimeMs()); + return false; +} + +const std::string &Over10DaysUnsedBundleAginHandler::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_unsed_bundle_agin_handler.cpp b/services/bundlemgr/src/aging/over_20days_unsed_bundle_agin_handler.cpp new file mode 100644 index 00000000..6f40f84c --- /dev/null +++ b/services/bundlemgr/src/aging/over_20days_unsed_bundle_agin_handler.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021-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 Over20DaysUnsedBundleAginHandler::CheckBundle(const AgingBundleInfo &bundle) const +{ + // There isn't interface of not used by the app,just return false first + // return AgingUtil::GetNowSysTimeMs() - bundle.GetRecentlyUsedTime() > + // ((int64_t)AgingConstants::TIME_20_DAYS * AgingRequest::GetOneDayTimeMs()); + return false; +} + +const std::string &Over20DaysUnsedBundleAginHandler::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_unsed_bundle_agin_handler.cpp b/services/bundlemgr/src/aging/over_30days_unsed_bundle_agin_handler.cpp new file mode 100644 index 00000000..68282a85 --- /dev/null +++ b/services/bundlemgr/src/aging/over_30days_unsed_bundle_agin_handler.cpp @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2021-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 Over30DaysUnsedBundleAginHandler::CheckBundle(const AgingBundleInfo &bundle) const +{ + // There isn't interface of not used by the app,just return false first + // return AgingUtil::GetNowSysTimeMs() - bundle.GetRecentlyUsedTime() > + // ((int64_t)AgingConstants::TIME_30_DAYS * AgingRequest::GetOneDayTimeMs()); + return false; +} + +const std::string &Over30DaysUnsedBundleAginHandler::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 00000000..2954cb20 --- /dev/null +++ b/services/bundlemgr/src/aging/recently_unused_bundle_aging_handler.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2021-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 "aging/aging_handler.h" +#include "app_log_wrapper.h" +#include "bundle_data_mgr.h" +#include "bundle_mgr_service.h" +#include "install_param.h" +#include "status_receiver_host.h" + +namespace OHOS { +namespace AppExecFwk { +class AgingUninstallReceiveIrmpl : public StatusReceiverHost { +public: + AgingUninstallReceiveIrmpl() = default; + virtual ~AgingUninstallReceiveIrmpl() override = default; + + void SetBundlePromise(const std::shared_ptr& bundlePromise) + { + //bundlePromise_ = bundlePromise; + } + + void SetTotalHapNum(int32_t totalHapNum) + { + //totalHapNum_ = totalHapNum; + } + + virtual void OnStatusNotify(const int progress) override {} + virtual void OnFinished(const int32_t resultCode, const std::string &resultMsg) override + { + // g_installedHapNum++; + // APP_LOGD("OnFinished::resultCode:(%{public}d) resultMsg:(%{public}s).", + // resultCode, resultMsg.c_str()); + // if (static_cast(g_installedHapNum) >= totalHapNum_ && bundlePromise_ != nullptr) { + // bundlePromise_->NotifyAllTasksExecuteFinished(); + // } + } +}; + +bool RecentlyUnuseBundleAgingHandler::Process(AgingRequest &request) const +{ + bool needContinue = true; + APP_LOGD("aging handler start: %{public}s, currentTotalDataBytes: %{pubic}" PRId64, GetName().c_str(), + request.GetTotalDataBytes()); + if (!CanStart(request)) { + APP_LOGD("finsh the whole aging task, bacause removable fa space usage meet the standard."); + return false; + } + + std::vector &agingBundles = const_cast &>(request.GetAgingBundles()); + APP_LOGD("aging handler start: agingBundles size :%{public}d / %{public}lld", + 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 isBundleUnistalled = UnInstallBundle(iter->GetBundleName()); + if (isBundleUnistalled) { + request.UpdateTotalDataBytesAfterUninstalled(iter->GetDataBytes()); + } + iter = agingBundles.erase(iter); + } + 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::CanStart(const AgingRequest &request) const +{ + return true; +} + +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_LOGD("bundleInstaller is null."); + return false; + } + + sptr userReceiverImpl(new (std::nothrow) AgingUninstallReceiveIrmpl()); + InstallParam installParam; + installParam.userId = bundleDataMgr->GetActiveUserId(); + bundleInstaller->Uninstall(bundlename, installParam, userReceiverImpl); + return true; +} +} // namespace AppExecFwk +} // namespace OHOS \ No newline at end of file diff --git a/services/bundlemgr/src/base_bundle_installer.cpp b/services/bundlemgr/src/base_bundle_installer.cpp index 5eb0c1c5..975e2d0d 100644 --- a/services/bundlemgr/src/base_bundle_installer.cpp +++ b/services/bundlemgr/src/base_bundle_installer.cpp @@ -204,6 +204,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. @@ -255,6 +267,8 @@ ErrCode BaseBundleInstaller::InnerProcessBundleInstall(std::unordered_map bundleInfos; + if (Constants::INVALID_USERID == (userId = GetActiveUserId()) + || true != GetBundleInfos(GET_ALL_APPLICATION_INFO, bundleInfos, userId)) { + APP_LOGE("GetAllBundleInfos failed"); + return 0; + } + + int64_t allSize = 0; + int64_t curSize = 0; + 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}lld", 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}lld", item.applicationInfo.dataDir.c_str(), curSize); + } + } + } + + APP_LOGI("All sfreeInstall:%{public}lld", allSize); + return allSize; +} + bool BundleDataMgr::GetBundlesForUid(const int uid, std::vector &bundleNames) const { InnerBundleInfo innerBundleInfo; @@ -1556,6 +1617,79 @@ 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; + } + + auto infoWithIdItem = infoItem->second.find(Constants::CURRENT_DEVICE_ID); + if (infoWithIdItem == infoItem->second.end()) { + APP_LOGE("bundle:%{public}s device id not find", bundleName.c_str()); + return false; + } + + InnerBundleInfo newInfo = infoWithIdItem->second; + newInfo.SetModuleRemovable(moduleName, isEnable); + if (dataStorage_->SaveStorageBundleInfo(Constants::CURRENT_DEVICE_ID, newInfo)) { + bool ret = infoWithIdItem->second.SetModuleRemovable(moduleName, isEnable); + 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); + } + return true; + } else { + APP_LOGE("bundle:%{public}s SetModuleRemoved failed", bundleName.c_str()); + return false; + } +} + +bool BundleDataMgr::IsModuleRemovable(const std::string &packageName, const std::string &moduleName) const +{ + APP_LOGD("packageName is bundleName:%{public}s, moduleName:%{public}s", packageName.c_str(), moduleName.c_str()); + if (packageName.empty() || moduleName.empty()) { + APP_LOGE("packageName or moduleName is empty"); + return false; + } + std::lock_guard lock(bundleInfoMutex_); + + auto infoItem = bundleInfos_.find(packageName); + if (infoItem == bundleInfos_.end()) { + APP_LOGE("can not find bundle %{public}s", packageName.c_str()); + return false; + } + + auto infoWithIdItem = infoItem->second.find(Constants::CURRENT_DEVICE_ID); + if (infoWithIdItem == infoItem->second.end()) { + APP_LOGE("bundle:%{public}s device id not find", packageName.c_str()); + return false; + } + + return infoWithIdItem->second.isModuleRemovable(moduleName); +} + +bool BundleDataMgr::IsBundleRemovable(std::map &innerBundleInfo) const +{ + auto infoWithIdItem = innerBundleInfo.find(Constants::CURRENT_DEVICE_ID); + if (infoWithIdItem == innerBundleInfo.end()) { + APP_LOGE("bundle device id not find"); + return false; + } + APP_LOGD("IsBundleRemovable:%{public}d ", infoWithIdItem->second.IsBundleRemovable()); + return infoWithIdItem->second.IsBundleRemovable(); +} + bool BundleDataMgr::IsAbilityEnabled(const AbilityInfo &abilityInfo) const { int32_t flags = GET_ABILITY_INFO_DEFAULT; @@ -2655,6 +2789,18 @@ int32_t BundleDataMgr::GetUserIdByCallingUid() const return BundleUtil::GetUserIdByCallingUid(); } +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]; +} + std::set BundleDataMgr::GetAllUser() const { std::lock_guard lock(multiUserIdSetMutex_); @@ -3033,6 +3179,33 @@ std::shared_ptr BundleDataMgr::GetResourceMan return resourceManager; } +bool BundleDataMgr::GetRemovableBundleNameVec(std::vector& bundlenames) +{ + if (bundleInfos_.empty()) { + APP_LOGD("bundleInfos_ is data is empty."); + } + for (auto & it : bundleInfos_) { + APP_LOGD("bundleName: %{public}s", it.first.c_str()); + auto infoWithIdItem = it.second.find(Constants::CURRENT_DEVICE_ID); + if (infoWithIdItem == it.second.end()) { + APP_LOGE("bundle device id not find"); + continue; + } + + int32_t userId = GetActiveUserId(); + APP_LOGD("bundle userId is %{public}d, userId= %{public}d", + infoWithIdItem->second.GetUserId(), userId); + if (infoWithIdItem->second.GetUserId() != userId) { + continue; + } + if (IsBundleRemovable(it.second)) { + bundlenames.emplace_back(it.first); + } + } + return true; +} + + 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 6a0261f2..3bac0787 100644 --- a/services/bundlemgr/src/bundle_mgr_host_impl.cpp +++ b/services/bundlemgr/src/bundle_mgr_host_impl.cpp @@ -831,6 +831,16 @@ 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::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 8644e245..3ece08ae 100644 --- a/services/bundlemgr/src/bundle_mgr_service.cpp +++ b/services/bundlemgr/src/bundle_mgr_service.cpp @@ -196,6 +196,19 @@ bool BundleMgrService::Init() hidumpHelper_ = std::make_shared(dataMgr_); } + if (!agingMgr_) { + APP_LOGI("Create aging manager"); + agingMgr_ = DelayedSingleton::GetInstance(); + if (!agingMgr_) { + APP_LOGI("Create aging manager faild."); + } + if (agingMgr_) { + APP_LOGI("Create aging manager success."); + agingMgr_->InitAgingRunner(); + agingMgr_->InitAgingtTimer(); + } + } + CheckAllUser(); ready_ = true; APP_LOGI("init end success"); @@ -212,6 +225,11 @@ const std::shared_ptr BundleMgrService::GetDataMgr() const return dataMgr_; } +const std::shared_ptr BundleMgrService::GetAgingMgr() const +{ + return agingMgr_; +} + 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 4c5c0016..a420dccb 100644 --- a/services/bundlemgr/src/inner_bundle_info.cpp +++ b/services/bundlemgr/src/inner_bundle_info.cpp @@ -1216,6 +1216,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; @@ -2096,6 +2097,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 { 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 ed59abe1..f8586f79 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 @@ -22,6 +22,8 @@ ohos_unittest("BmsBundleKitServiceTest") { use_exceptions = true module_out_path = module_output_path include_dirs = [ + "//base/powermgr/display_manager/utils/native/include", + "//base/sensors/sensor/interfaces/native/include", "//third_party/jsoncpp/include", "//base/startup/syspara_lite/interfaces/innerkits/native/syspara/include", ] @@ -70,6 +72,7 @@ ohos_unittest("BmsBundleKitServiceTest") { } deps = [ "${libs_path}/libeventhandler:libeventhandler_target", + "//base/powermgr/display_manager/service:displaymgrservice", "//base/security/appverify/interfaces/innerkits/appverify:libhapverify", "//base/security/permission/interfaces/innerkits/permission_standard/permissionsdk:libpermissionsdk_standard", "//base/startup/syspara_lite/interfaces/innerkits/native/syspara:syspara", @@ -96,15 +99,20 @@ ohos_unittest("BmsBundleKitServiceTest") { "ability_runtime:app_manager", "bundle_framework:appexecfwk_base", "bundle_framework:appexecfwk_core", + "battery_manager_native:batterysrv_client", "bytrace_standard:bytrace_core", "ces_standard:cesfwk_innerkits", "device_manager_base:devicemanagersdk", + "display_manager_native:displaymgr", "hicollie_native:libhicollie", "hiviewdfx_hilog_native:libhilog", "init:libbegetutil", "ipc:ipc_core", "os_account_standard:os_account_innerkits", + "power_manager_native:powermgr_client", "resmgr_standard:global_resmgr", + "sensor:sensor_interface_native", + "startup_l2:syspara", ] defines = [] if (configpolicy_enable) { 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 89d07543..21262e4e 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 @@ -946,6 +946,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 -- Gitee From 6d68474ff7a18f71fe0978ac316768301e69dc55 Mon Sep 17 00:00:00 2001 From: cailing Date: Tue, 29 Mar 2022 08:04:51 +0000 Subject: [PATCH 2/2] update README_zh.md. --- README_zh.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README_zh.md b/README_zh.md index c94cab15..b8f3f998 100644 --- a/README_zh.md +++ b/README_zh.md @@ -9,6 +9,9 @@ ![](figures/appexecfwk.png) + + + ## 部件内子模块职责 | 子模块名称 | 职责 | -- Gitee