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 b2968a5969cc3623f0dd9da1155267db4123f0ef..e800a11b4227f530ff201ce6def013c3f77c4778 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 06878c3b918bcbf5468e803479261cada6b1c22a..189097d0a905c63545d1f52985334f1563900336 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 bcbfc8bb7a11fa3519529be825afa06c78a69e4b..61ee734fa9eacf42c3a4b0b70cd218285f586672 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 f973df156964dd0d4ef2b69a78d8b135ecbb5c75..d386c33cec59d9c64c15441b5b4c480f1f9c3855 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 f473cfd14d4c086c6f3d6e62bf14e3d394faf207..99dc61828e66626237e1c47ffe3795d7dba81b86 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 08a625633b77b31e5352630732d80322a1fd6110..5a2042b2c505c65795183b2606ec825049c36b05 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 0c5e6a0a7bc51ddce03a3a9178aefa9f5a89d54f..3adcb8727ab78319ccd992626c5afdfbcc0fb37d 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 3478ea74e824d79ffa71428f7af77008fd147ed6..af5e540838b59fd859cc6b6afafe1901774d3f59 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 0e38ed0092e7a306bf22fffe54c7a030a083049a..3e5afdeebab6225bac47f9b25d11976e4025aa6b 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 7d0cb071f604b3cc45f79d6dcbb0f5771bc7beb5..74f31e50fa172d27f452a0152e85002e7313d207 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 42df40ea5233d743d9cbdb30361871f73dba7175..15847b1421e5603cc5ada1617dd85890360e45cb 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 9f5713b3ffec1ada446b807c15b714c54247d665..28549ff32905f854aea71a6c0fd75b9fb2160bc7 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 a83691843dcda557fb3cc4e798609bde743513b6..c00283920b639408496a56e27f1534ef21d5dbf7 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);