From 8a1ca5a97c1140093c9b933d54f4990bffa1ab23 Mon Sep 17 00:00:00 2001 From: ming-yue-liu1 Date: Thu, 4 Sep 2025 17:20:33 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=8D=B8=E8=BD=BD=E7=AE=A1?= =?UTF-8?q?=E6=8E=A7=E6=8E=A5=E5=8F=A3=E9=80=82=E9=85=8D=E4=B8=9C=E6=B9=96?= =?UTF-8?q?=E5=A4=9A=E7=94=A8=E6=88=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: ming-yue-liu1 --- .../include/bundlemgr/bundle_mgr_interface.h | 2 +- .../include/bundlemgr/bundle_mgr_proxy.h | 2 +- .../src/bundlemgr/bundle_mgr_host.cpp | 3 +- .../src/bundlemgr/bundle_mgr_proxy.cpp | 6 ++- services/bundlemgr/include/bundle_data_mgr.h | 2 + .../bundlemgr/include/bundle_mgr_host_impl.h | 2 +- .../bundlemgr/include/inner_bundle_info.h | 1 + .../include/inner_bundle_user_info.h | 1 + .../bundlemgr/src/base_bundle_installer.cpp | 10 +++++ services/bundlemgr/src/bundle_data_mgr.cpp | 39 ++++++++++++++++++- .../bundlemgr/src/bundle_mgr_host_impl.cpp | 9 ++++- services/bundlemgr/src/inner_bundle_info.cpp | 24 +++++++++++- .../bundlemgr/src/inner_bundle_user_info.cpp | 4 ++ 13 files changed, 96 insertions(+), 9 deletions(-) diff --git a/interfaces/inner_api/appexecfwk_core/include/bundlemgr/bundle_mgr_interface.h b/interfaces/inner_api/appexecfwk_core/include/bundlemgr/bundle_mgr_interface.h index b2968a5969..e800a11b42 100644 --- a/interfaces/inner_api/appexecfwk_core/include/bundlemgr/bundle_mgr_interface.h +++ b/interfaces/inner_api/appexecfwk_core/include/bundlemgr/bundle_mgr_interface.h @@ -1678,7 +1678,7 @@ public: } virtual ErrCode SwitchUninstallState(const std::string &bundleName, const bool &state, - bool isNeedSendNotify = true) + bool isNeedSendNotify = true, int32_t userId = Constants::INVALID_USERID) { return ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR; } diff --git a/interfaces/inner_api/appexecfwk_core/include/bundlemgr/bundle_mgr_proxy.h b/interfaces/inner_api/appexecfwk_core/include/bundlemgr/bundle_mgr_proxy.h index 06878c3b91..189097d0a9 100644 --- a/interfaces/inner_api/appexecfwk_core/include/bundlemgr/bundle_mgr_proxy.h +++ b/interfaces/inner_api/appexecfwk_core/include/bundlemgr/bundle_mgr_proxy.h @@ -1156,7 +1156,7 @@ public: * @return Returns ERR_OK if this function is successfully called; returns other ErrCode otherwise. */ virtual ErrCode SwitchUninstallState(const std::string &bundleName, const bool &state, - bool isNeedSendNotify = true) override; + bool isNeedSendNotify = true, int32_t userId = Constants::INVALID_USERID) override; /** * @brief Query the AbilityInfo by continueType. diff --git a/interfaces/inner_api/appexecfwk_core/src/bundlemgr/bundle_mgr_host.cpp b/interfaces/inner_api/appexecfwk_core/src/bundlemgr/bundle_mgr_host.cpp index bcbfc8bb7a..61ee734fa9 100644 --- a/interfaces/inner_api/appexecfwk_core/src/bundlemgr/bundle_mgr_host.cpp +++ b/interfaces/inner_api/appexecfwk_core/src/bundlemgr/bundle_mgr_host.cpp @@ -4219,7 +4219,8 @@ ErrCode BundleMgrHost::HandleSwitchUninstallState(MessageParcel &data, MessagePa std::string bundleName = data.ReadString(); bool state = data.ReadBool(); bool isNeedSendNotify = data.ReadBool(); - ErrCode ret = SwitchUninstallState(bundleName, state, isNeedSendNotify); + int32_t userId = data.ReadInt32(); + ErrCode ret = SwitchUninstallState(bundleName, state, isNeedSendNotify, userId); if (!reply.WriteInt32(ret)) { APP_LOGE("write failed"); return ERR_APPEXECFWK_PARCEL_ERROR; diff --git a/interfaces/inner_api/appexecfwk_core/src/bundlemgr/bundle_mgr_proxy.cpp b/interfaces/inner_api/appexecfwk_core/src/bundlemgr/bundle_mgr_proxy.cpp index f973df1569..d386c33cec 100644 --- a/interfaces/inner_api/appexecfwk_core/src/bundlemgr/bundle_mgr_proxy.cpp +++ b/interfaces/inner_api/appexecfwk_core/src/bundlemgr/bundle_mgr_proxy.cpp @@ -5472,7 +5472,7 @@ ErrCode BundleMgrProxy::GetAllPreinstalledApplicationInfos( } ErrCode BundleMgrProxy::SwitchUninstallState(const std::string &bundleName, const bool &state, - bool isNeedSendNotify) + bool isNeedSendNotify, int32_t userId) { HITRACE_METER_NAME_EX(HITRACE_LEVEL_INFO, HITRACE_TAG_APP, __PRETTY_FUNCTION__, nullptr); MessageParcel data; @@ -5492,6 +5492,10 @@ ErrCode BundleMgrProxy::SwitchUninstallState(const std::string &bundleName, cons APP_LOGE("write isNeedSendNotify failed"); return ERR_APPEXECFWK_PARCEL_ERROR; } + if (!data.WriteInt32(userId)) { + APP_LOGE("write userId failed"); + return ERR_APPEXECFWK_PARCEL_ERROR; + } MessageParcel reply; if (!SendTransactCmd(BundleMgrInterfaceCode::SWITCH_UNINSTALL_STATE, data, reply)) { APP_LOGE("SendTransactCmd failed"); diff --git a/services/bundlemgr/include/bundle_data_mgr.h b/services/bundlemgr/include/bundle_data_mgr.h index f473cfd14d..99dc61828e 100644 --- a/services/bundlemgr/include/bundle_data_mgr.h +++ b/services/bundlemgr/include/bundle_data_mgr.h @@ -1070,6 +1070,8 @@ public: std::vector &developerIdList, int32_t userId); ErrCode SwitchUninstallState(const std::string &bundleName, const bool &state, const bool isNeedSendNotify, bool &stateChange); + ErrCode SwitchUninstallStateByUserId(const std::string &bundleName, bool state, + const bool isNeedSendNotify, int32_t userId, bool &stateChange); ErrCode AddCloneBundle(const std::string &bundleName, const InnerBundleCloneInfo &attr); ErrCode RemoveCloneBundle(const std::string &bundleName, const int32_t userId, int32_t appIndex); diff --git a/services/bundlemgr/include/bundle_mgr_host_impl.h b/services/bundlemgr/include/bundle_mgr_host_impl.h index 08a625633b..5a2042b2c5 100644 --- a/services/bundlemgr/include/bundle_mgr_host_impl.h +++ b/services/bundlemgr/include/bundle_mgr_host_impl.h @@ -1100,7 +1100,7 @@ public: std::vector &developerIdList, int32_t userId) override; virtual ErrCode SwitchUninstallState(const std::string &bundleName, const bool &state, - bool isNeedSendNotify) override; + bool isNeedSendNotify, int32_t userId) override; virtual ErrCode QueryAbilityInfoByContinueType(const std::string &bundleName, const std::string &continueType, AbilityInfo &abilityInfo, int32_t userId = Constants::UNSPECIFIED_USERID) override; diff --git a/services/bundlemgr/include/inner_bundle_info.h b/services/bundlemgr/include/inner_bundle_info.h index 0c5e6a0a7b..3adcb8727a 100644 --- a/services/bundlemgr/include/inner_bundle_info.h +++ b/services/bundlemgr/include/inner_bundle_info.h @@ -2307,6 +2307,7 @@ public: void SetUninstallState(const bool &uninstallState); bool IsNeedSendNotify() const; void SetNeedSendNotify(const bool needStatus); + ErrCode SetCanUninstall(int32_t userId, bool state, bool &changed); void UpdateMultiAppMode(const InnerBundleInfo &newInfo); void UpdateReleaseType(const InnerBundleInfo &newInfo); ErrCode AddCloneBundle(const InnerBundleCloneInfo &attr); diff --git a/services/bundlemgr/include/inner_bundle_user_info.h b/services/bundlemgr/include/inner_bundle_user_info.h index 3478ea74e8..af5e540838 100644 --- a/services/bundlemgr/include/inner_bundle_user_info.h +++ b/services/bundlemgr/include/inner_bundle_user_info.h @@ -26,6 +26,7 @@ namespace AppExecFwk { struct InnerBundleUserInfo { // app install control bool isRemovable = true; + bool canUninstall = true; int32_t uid = Constants::INVALID_UID; uint32_t accessTokenId = 0; diff --git a/services/bundlemgr/src/base_bundle_installer.cpp b/services/bundlemgr/src/base_bundle_installer.cpp index 0e38ed0092..3e5afdeeba 100644 --- a/services/bundlemgr/src/base_bundle_installer.cpp +++ b/services/bundlemgr/src/base_bundle_installer.cpp @@ -1801,6 +1801,16 @@ ErrCode BaseBundleInstaller::ProcessBundleUninstall( } } + if (!installParam.GetForceExecuted() && + !curInnerBundleUserInfo.canUninstall && installParam.GetKillProcess() && + !installParam.GetIsUninstallAndRecover()) { + if (!isForcedUninstall) { + LOG_E(BMS_TAG_INSTALLER, "bundle : %{public}s can not be uninstalled, uninstallState : %{public}d", + bundleName.c_str(), oldInfo.GetUninstallState()); + return ERR_APPEXECFWK_UNINSTALL_STATE_NOT_ALLOW; + } + } + if (!UninstallAppControl(oldInfo.GetAppId(), oldInfo.GetAppIdentifier(), userId_)) { if (!isForcedUninstall) { LOG_E(BMS_TAG_INSTALLER, "bundleName: %{public}s is not allow uninstall", bundleName.c_str()); diff --git a/services/bundlemgr/src/bundle_data_mgr.cpp b/services/bundlemgr/src/bundle_data_mgr.cpp index 7d0cb071f6..74f31e50fa 100644 --- a/services/bundlemgr/src/bundle_data_mgr.cpp +++ b/services/bundlemgr/src/bundle_data_mgr.cpp @@ -2009,7 +2009,7 @@ void BundleDataMgr::GetMatchLauncherAbilityInfos(const Want& want, BmsExtensionDataMgr bmsExtensionDataMgr; if (mainAbilityInfo.applicationInfo.removable && !bmsExtensionDataMgr.IsTargetApp(info.GetBundleName(), info.GetAppIdentifier())) { - mainAbilityInfo.applicationInfo.removable = info.GetUninstallState(); + mainAbilityInfo.applicationInfo.removable = info.GetUninstallState() && bundleUserInfo.canUninstall; } mainAbilityInfo.installTime = installTime; // fix labelId or iconId is equal 0 @@ -9614,6 +9614,43 @@ ErrCode BundleDataMgr::SwitchUninstallState(const std::string &bundleName, const return ERR_OK; } +ErrCode BundleDataMgr::SwitchUninstallStateByUserId(const std::string &bundleName, bool state, + const bool isNeedSendNotify, int32_t userId, bool &stateChange) +{ + int32_t requestUserId = GetUserId(userId); + if (requestUserId == Constants::INVALID_USERID) { + APP_LOGE("name %{public}s invalid userid :%{public}d", bundleName.c_str(), userId); + return ERR_BUNDLE_MANAGER_INVALID_USER_ID; + } + std::unique_lock lock(bundleInfoMutex_); + auto item = bundleInfos_.find(bundleName); + if (item == bundleInfos_.end()) { + APP_LOGE("BundleName: %{public}s does not exist", bundleName.c_str()); + return ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST; + } + InnerBundleInfo &innerBundleInfo = item->second; + if (!innerBundleInfo.IsRemovable() && state) { + APP_LOGW("the bundle : %{public}s is not removable", bundleName.c_str()); + return ERR_BUNDLE_MANAGER_BUNDLE_CAN_NOT_BE_UNINSTALLED; + } + + auto ret = innerBundleInfo.SetCanUninstall(requestUserId, state, stateChange); + if (ret != ERR_OK) { + return ret; + } + + if (stateChange) { + innerBundleInfo.SetNeedSendNotify(isNeedSendNotify); + if (!dataStorage_->SaveStorageBundleInfo(innerBundleInfo)) { + APP_LOGW("update storage failed bundle:%{public}s", bundleName.c_str()); + return ERR_APPEXECFWK_SERVICE_INTERNAL_ERROR; + } + } else { + APP_LOGD("CanUninstall is not changed -n %{public}s -u %{public}d", bundleName.c_str(), userId); + } + return ERR_OK; +} + ErrCode BundleDataMgr::AddCloneBundle(const std::string &bundleName, const InnerBundleCloneInfo &attr) { std::unique_lock lock(bundleInfoMutex_); diff --git a/services/bundlemgr/src/bundle_mgr_host_impl.cpp b/services/bundlemgr/src/bundle_mgr_host_impl.cpp index 42df40ea52..15847b1421 100644 --- a/services/bundlemgr/src/bundle_mgr_host_impl.cpp +++ b/services/bundlemgr/src/bundle_mgr_host_impl.cpp @@ -5060,7 +5060,7 @@ ErrCode BundleMgrHostImpl::GetDeveloperIds(const std::string &appDistributionTyp } ErrCode BundleMgrHostImpl::SwitchUninstallState(const std::string &bundleName, const bool &state, - bool isNeedSendNotify) + bool isNeedSendNotify, int32_t userId) { APP_LOGD("start SwitchUninstallState, bundleName : %{public}s, state : %{public}d", bundleName.c_str(), state); if (!BundlePermissionMgr::IsSystemApp()) { @@ -5079,7 +5079,12 @@ ErrCode BundleMgrHostImpl::SwitchUninstallState(const std::string &bundleName, c return ERR_BUNDLE_MANAGER_INTERNAL_ERROR; } bool stateChange = false; - auto resCode = dataMgr->SwitchUninstallState(bundleName, state, isNeedSendNotify, stateChange); + ErrCode resCode = ERR_OK; + if (userId == Constants::INVALID_USERID) { + resCode = dataMgr->SwitchUninstallState(bundleName, state, isNeedSendNotify, stateChange); + } else { + resCode = dataMgr->SwitchUninstallStateByUserId(bundleName, state, isNeedSendNotify, userId, stateChange); + } if (resCode != ERR_OK) { APP_LOGE("set status fail"); return resCode; diff --git a/services/bundlemgr/src/inner_bundle_info.cpp b/services/bundlemgr/src/inner_bundle_info.cpp index 9f5713b3ff..28549ff329 100644 --- a/services/bundlemgr/src/inner_bundle_info.cpp +++ b/services/bundlemgr/src/inner_bundle_info.cpp @@ -2689,7 +2689,12 @@ void InnerBundleInfo::ProcessBundleFlags( BmsExtensionDataMgr bmsExtensionDataMgr; if (bundleInfo.applicationInfo.removable && !bmsExtensionDataMgr.IsTargetApp(GetBundleName(), GetAppIdentifier())) { - bundleInfo.applicationInfo.removable = GetUninstallState(); + InnerBundleUserInfo innerBundleUserInfo; + if (!GetInnerBundleUserInfo(userId, innerBundleUserInfo)) { + APP_LOGE("not find userId %{public}d when get applicationInfo", userId); + return; + } + bundleInfo.applicationInfo.removable = GetUninstallState() && innerBundleUserInfo.canUninstall; } } bundleInfo.applicationInfo.appIndex = appIndex; @@ -4826,6 +4831,23 @@ void InnerBundleInfo::SetNeedSendNotify(const bool needStatus) isNeedSendNotify_ = needStatus; } +ErrCode InnerBundleInfo::SetCanUninstall(int32_t userId, bool state, bool &stateChange) { + auto& key = NameAndUserIdToKey(GetBundleName(), userId); + auto infoItem = innerBundleUserInfos_.find(key); + if (infoItem == innerBundleUserInfos_.end()) { + APP_LOGE("SetCanUninstall not find :%{public}s in userId: %{public}d", GetBundleName().c_str(), userId); + return ERR_BUNDLE_MANAGER_BUNDLE_NOT_EXIST; + } + if (infoItem->second.canUninstall == state) { + stateChange = false; + return ERR_OK; + } + + infoItem->second.canUninstall = state; + stateChange = true; + return ERR_OK; +} + std::vector InnerBundleInfo::GetAllExtensionDirsInSpecifiedModule(const std::string &moduleName) const { std::vector dirVec; diff --git a/services/bundlemgr/src/inner_bundle_user_info.cpp b/services/bundlemgr/src/inner_bundle_user_info.cpp index a83691843d..c00283920b 100644 --- a/services/bundlemgr/src/inner_bundle_user_info.cpp +++ b/services/bundlemgr/src/inner_bundle_user_info.cpp @@ -28,6 +28,7 @@ constexpr const char* INNER_BUNDLE_USER_INFO_UPDATE_TIME = "updateTime"; constexpr const char* INNER_BUNDLE_USER_INFO_FIRST_INSTALL_TIME = "firstInstallTime"; constexpr const char* INNER_BUNDLE_USER_INFO_BUNDLE_USER_INFO = "bundleUserInfo"; constexpr const char* INNER_BUNDLE_USER_INFO_IS_REMOVABLE = "isRemovable"; +constexpr const char* INNER_BUNDLE_USER_INFO_CAN_UNINSTALL = "canUninstall"; constexpr const char* INNER_BUNDLE_USER_INFO_CLONE_INFOS = "cloneInfos"; constexpr const char* INNER_BUNDLE_USER_INFO_KEYID = "keyId"; constexpr const char* INNER_BUNDLE_USER_INFO_INSTALLED_PLUGIN_SET = "installedPluginSet"; @@ -47,6 +48,7 @@ void to_json(nlohmann::json& jsonObject, const InnerBundleUserInfo& innerBundleU {INNER_BUNDLE_USER_INFO_FIRST_INSTALL_TIME, innerBundleUserInfo.firstInstallTime}, {INNER_BUNDLE_USER_INFO_BUNDLE_USER_INFO, innerBundleUserInfo.bundleUserInfo}, {INNER_BUNDLE_USER_INFO_IS_REMOVABLE, innerBundleUserInfo.isRemovable}, + {INNER_BUNDLE_USER_INFO_CAN_UNINSTALL, innerBundleUserInfo.canUninstall}, {INNER_BUNDLE_USER_INFO_CLONE_INFOS, innerBundleUserInfo.cloneInfos}, {INNER_BUNDLE_USER_INFO_KEYID, innerBundleUserInfo.keyId}, {INNER_BUNDLE_USER_INFO_INSTALLED_PLUGIN_SET, innerBundleUserInfo.installedPluginSet}, @@ -78,6 +80,8 @@ void from_json(const nlohmann::json& jsonObject, InnerBundleUserInfo& innerBundl innerBundleUserInfo.bundleUserInfo, JsonType::OBJECT, false, parseResult, ArrayType::NOT_ARRAY); BMSJsonUtil::GetBoolValueIfFindKey(jsonObject, jsonObjectEnd, INNER_BUNDLE_USER_INFO_IS_REMOVABLE, innerBundleUserInfo.isRemovable, false, parseResult); + BMSJsonUtil::GetBoolValueIfFindKey(jsonObject, jsonObjectEnd, INNER_BUNDLE_USER_INFO_CAN_UNINSTALL, + innerBundleUserInfo.canUninstall, false, parseResult); GetValueIfFindKey>(jsonObject, jsonObjectEnd, INNER_BUNDLE_USER_INFO_CLONE_INFOS, innerBundleUserInfo.cloneInfos, JsonType::OBJECT, false, parseResult, ArrayType::NOT_ARRAY); -- Gitee