!10339 普通用户常驻应用2

Merge pull request !10339 from wangzhen/resident2
This commit is contained in:
openharmony_ci 2024-09-08 08:14:27 +00:00 committed by Gitee
commit bfc3ec8279
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
10 changed files with 190 additions and 111 deletions

View File

@ -621,8 +621,7 @@ private:
void AddConnectObjectToMap(sptr<IRemoteObject> connectObject, const ConnectListType &connectRecordList,
bool updateOnly);
void GetKeepAliveAbilities();
bool IsInKeepAliveList(const AppExecFwk::AbilityInfo &abilityInfo);
void KeepAbilityAlive(const std::shared_ptr<AbilityRecord> &abilityRecord, int32_t currentUserId);
void ProcessEliminateAbilityRecord(std::shared_ptr<AbilityRecord> eliminateRecord);
std::string GetServiceKey(const std::shared_ptr<AbilityRecord> &service);
@ -666,9 +665,6 @@ private:
std::unique_ptr<UIExtensionAbilityConnectManager> uiExtensionAbilityRecordMgr_ = nullptr;
uint32_t sceneBoardTokenId_ = 0;
std::mutex keepAliveAbilitiesMutex_;
std::vector<std::pair<std::string, std::string>> keepAliveAbilities_;
DISALLOW_COPY_AND_MOVE(AbilityConnectManager);
};
} // namespace AAFwk

View File

@ -957,6 +957,10 @@ public:
int32_t GetRestartCount() const;
void SetRestartCount(int32_t restartCount);
bool GetKeepAlive() const;
bool IsKeepAliveBundle() const
{
return keepAliveBundle_;
}
void SetLoading(bool status);
bool IsLoading() const;
int64_t GetRestartTime();
@ -1260,7 +1264,7 @@ private:
bool minimizeReason_ = false;
bool clearMissionFlag_ = false;
bool keepAliveBundle_ = false;
int32_t restartCount_ = -1;
int32_t restartMax_ = -1;
std::string specifiedFlag_;

View File

@ -50,6 +50,7 @@ constexpr const char* UIEATENSION_TYPE_PICKER = "typePicker";
constexpr const char* MULTI_USER_TYPE = "multiUserType";
constexpr const char* SUPPORT_BACK_TO_CALLER = "supportBackToCaller";
constexpr const char* SUPPORT_SCB_CRASH_REBOOT = "supportSCBCrashReboot";
constexpr const char* RESIDENT_WHITE_LIST = "normal_resident_apps";
} // namespace AmsConfig
enum class SatrtUiMode { STATUSBAR = 1, NAVIGATIONBAR = 2, STARTUIBOTH = 3 };
@ -65,6 +66,8 @@ enum class JsonValueType {
class AmsConfigurationParameter final {
public:
enum { READ_OK = 0, READ_FAIL = 1, READ_JSON_FAIL = 2 };
static AmsConfigurationParameter &GetInstance();
/**
* return true : ams no config file
@ -134,7 +137,7 @@ public:
const std::map<std::string, std::string>& GetPickerMap() const;
enum { READ_OK = 0, READ_FAIL = 1, READ_JSON_FAIL = 2 };
bool InResidentWhiteList(const std::string &bundleName) const;
private:
AmsConfigurationParameter();
@ -156,6 +159,7 @@ private:
void LoadUIExtensionPickerConfig(const std::string &filePath);
int32_t LoadBackToCallerConfig(nlohmann::json& Object);
int32_t LoadSupportSCBCrashRebootConfig(nlohmann::json& Object);
void LoadResidentWhiteListConfig(nlohmann::json& Object);
private:
bool nonConfigFile_ {false};
@ -176,6 +180,7 @@ private:
int multiUserType_ {0};
bool supportBackToCaller_ {true};
bool supportSceneboardCrashReboot_{true};
std::vector<std::string> residentWhiteList_;
};
} // namespace AAFwk
} // namespace OHOS

View File

@ -16,12 +16,33 @@
#ifndef OHOS_ABILITY_RUNTIME_RESIDENT_PROCESS_MANAGER_H
#define OHOS_ABILITY_RUNTIME_RESIDENT_PROCESS_MANAGER_H
#include <list>
#include <mutex>
#include "app_scheduler.h"
#include "bundle_info.h"
#include "singleton.h"
namespace OHOS {
namespace AAFwk {
struct ResidentAbilityInfo {
std::string bundleName;
std::string abilityName;
int32_t userId = 0;
int32_t residentId = -1;
};
class ResidentAbilityInfoGuard {
public:
ResidentAbilityInfoGuard() = default;
~ResidentAbilityInfoGuard();
ResidentAbilityInfoGuard(ResidentAbilityInfoGuard &) = delete;
void operator=(ResidentAbilityInfoGuard &) = delete;
ResidentAbilityInfoGuard(const std::string &bundleName, std::string &abilityName, int32_t userId);
void SetResidentAbilityInfo(const std::string &bundleName, std::string &abilityName, int32_t userId);
private:
int32_t residentId_ = -1;
};
/**
* @class ResidentProcessManager
* ResidentProcessManager
@ -48,10 +69,17 @@ public:
void StartResidentProcess(const std::vector<AppExecFwk::BundleInfo> &bundleInfos);
void StartResidentProcessWithMainElement(std::vector<AppExecFwk::BundleInfo> &bundleInfos, int32_t userId);
void OnAppStateChanged(const AppInfo &info);
int32_t PutResidentAbility(const std::string &bundleName, std::string &abilityName, int32_t userId);
bool IsResidentAbility(const std::string &bundleName, const std::string &abilityName, int32_t userId);
void RemoveResidentAbility(int32_t residentId);
private:
bool CheckMainElement(const AppExecFwk::HapModuleInfo &hapModuleInfo, const std::string &processName,
std::string &mainElement, std::set<uint32_t> &needEraseIndexSet, size_t bundleInfoIndex, int32_t userId = 0);
void UpdateResidentProcessesStatus(const std::string &bundleName, bool localEnable, bool updateEnable);
std::mutex residentAbilityInfoMutex_;
std::list<ResidentAbilityInfo> residentAbilityInfos_;
int32_t residentId_ = 0;
};
} // namespace AAFwk
} // namespace OHOS

View File

@ -83,75 +83,6 @@ bool IsSpecialAbility(const AppExecFwk::AbilityInfo &abilityInfo)
}
}
void AbilityConnectManager::GetKeepAliveAbilities()
{
if (!keepAliveAbilities_.empty()) {
return;
}
auto bundleMgrHelper = AbilityUtil::GetBundleManagerHelper();
CHECK_POINTER(bundleMgrHelper);
std::vector<AppExecFwk::BundleInfo> bundleInfos;
bool getBundleInfos = bundleMgrHelper->GetBundleInfos(
OHOS::AppExecFwk::GET_BUNDLE_DEFAULT, bundleInfos, userId_);
if (!getBundleInfos) {
TAG_LOGE(AAFwkTag::ABILITYMGR, "getBundleInfos fail");
return;
}
auto checkIsAbilityNeedKeepAlive = [](const AppExecFwk::HapModuleInfo &hapModuleInfo,
const std::string &processName, std::string &mainElement) {
if (hapModuleInfo.isModuleJson) {
// new application model
if (hapModuleInfo.process == processName) {
mainElement = hapModuleInfo.mainElementName;
return true;
}
return false;
}
// old application model
mainElement = hapModuleInfo.mainAbility;
for (auto abilityInfo : hapModuleInfo.abilityInfos) {
if (abilityInfo.process == processName && abilityInfo.name == mainElement) {
return true;
}
}
return false;
};
for (const auto &bundleInfo : bundleInfos) {
std::string processName = bundleInfo.applicationInfo.process;
if (!bundleInfo.isKeepAlive || processName.empty()) {
continue;
}
std::string bundleName = bundleInfo.name;
for (auto hapModuleInfo : bundleInfo.hapModuleInfos) {
std::string mainElement;
if (checkIsAbilityNeedKeepAlive(hapModuleInfo, processName, mainElement) && !mainElement.empty()) {
keepAliveAbilities_.emplace_back(bundleName, mainElement);
}
}
}
}
bool AbilityConnectManager::IsInKeepAliveList(const AppExecFwk::AbilityInfo &abilityInfo)
{
std::lock_guard guard(keepAliveAbilitiesMutex_);
GetKeepAliveAbilities();
for (const auto &pair : keepAliveAbilities_) {
if (abilityInfo.bundleName == pair.first && abilityInfo.name == pair.second) {
// Fault tolerance processing, originally returning true here
bool keepAliveEnable = true;
AmsResidentProcessRdb::GetInstance().GetResidentProcessEnable(abilityInfo.bundleName, keepAliveEnable);
TAG_LOGD(AAFwkTag::ABILITYMGR, "%{public}s get keep alive enable: %{public}d",
abilityInfo.bundleName.c_str(), static_cast<int32_t>(keepAliveEnable));
return keepAliveEnable;
}
}
return false;
}
AbilityConnectManager::AbilityConnectManager(int userId) : userId_(userId)
{
uiExtensionAbilityRecordMgr_ = std::make_unique<AbilityRuntime::ExtensionRecordManager>(userId);
@ -488,14 +419,12 @@ void AbilityConnectManager::GetOrCreateServiceRecord(const AbilityRequest &abili
isLoadedAbility = true;
if (noReuse || targetService == nullptr) {
targetService = AbilityRecord::CreateAbilityRecord(abilityRequest);
if (targetService) {
targetService->SetOwnerMissionUserId(userId_);
}
if (isCreatedByConnect && targetService != nullptr) {
CHECK_POINTER(targetService);
targetService->SetOwnerMissionUserId(userId_);
if (isCreatedByConnect) {
targetService->SetCreateByConnectMode();
}
if (targetService && abilityRequest.abilityInfo.name == AbilityConfig::LAUNCHER_ABILITY_NAME) {
if (abilityRequest.abilityInfo.name == AbilityConfig::LAUNCHER_ABILITY_NAME) {
targetService->SetLauncherRoot();
targetService->SetRestartTime(abilityRequest.restartTime);
targetService->SetRestartCount(abilityRequest.restartCount);
@ -2146,10 +2075,7 @@ bool AbilityConnectManager::IsAbilityNeedKeepAlive(const std::shared_ptr<Ability
return true;
}
if (IsInKeepAliveList(abilityInfo)) {
return true;
}
return false;
return abilityRecord->IsKeepAliveBundle();
}
void AbilityConnectManager::ClearPreloadUIExtensionRecord(const std::shared_ptr<AbilityRecord> &abilityRecord)
@ -2384,6 +2310,11 @@ void AbilityConnectManager::RestartAbility(const std::shared_ptr<AbilityRecord>
requestInfo.restart = true;
requestInfo.uid = abilityRecord->GetUid();
abilityRecord->SetRestarting(true);
ResidentAbilityInfoGuard residentAbilityInfoGuard;
if (abilityRecord->IsKeepAliveBundle()) {
residentAbilityInfoGuard.SetResidentAbilityInfo(requestInfo.abilityInfo.bundleName,
requestInfo.abilityInfo.name, userId_);
}
if (AppUtils::GetInstance().IsLauncherAbility(abilityRecord->GetAbilityInfo().name)) {
if (currentUserId != userId_) {

View File

@ -2261,7 +2261,7 @@ void AbilityManagerService::AppUpgradeCompleted(const std::string &bundleName, i
auto bms = GetBundleManager();
CHECK_POINTER(bms);
auto userId = uid / BASE_USER_RANGE;
if (userId != U0_USER_ID || userId != GetUserId()) {
if (userId != U0_USER_ID && userId != GetUserId()) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "not current user");
return;
}

View File

@ -233,6 +233,14 @@ std::shared_ptr<AbilityRecord> AbilityRecord::CreateAbilityRecord(const AbilityR
abilityRecord->collaboratorType_ = abilityRequest.collaboratorType;
abilityRecord->missionAffinity_ = abilityRequest.want.GetStringParam(PARAM_MISSION_AFFINITY_KEY);
auto userId = abilityRequest.appInfo.uid / BASE_USER_RANGE;
if ((userId == 0 ||
AmsConfigurationParameter::GetInstance().InResidentWhiteList(abilityRequest.abilityInfo.bundleName)) &&
DelayedSingleton<ResidentProcessManager>::GetInstance()->IsResidentAbility(
abilityRequest.abilityInfo.bundleName, abilityRequest.abilityInfo.name, userId)) {
abilityRecord->keepAliveBundle_ = true;
}
return abilityRecord;
}
@ -2799,7 +2807,7 @@ bool AbilityRecord::GetKeepAlive() const
return true;
}
}
bool keepAliveEnable = false;
bool keepAliveEnable = keepAliveBundle_;
AmsResidentProcessRdb::GetInstance().GetResidentProcessEnable(applicationInfo_.bundleName, keepAliveEnable);
return keepAliveEnable;
}

View File

@ -22,8 +22,9 @@
namespace OHOS {
namespace AAFwk {
namespace {
const int LOAD_CONFIGURATION_FAILED = -1;
const int LOAD_CONFIGURATION_SUCCESS = 0;
constexpr int32_t LOAD_CONFIGURATION_FAILED = -1;
constexpr int32_t LOAD_CONFIGURATION_SUCCESS = 0;
constexpr int32_t MAX_RESIDENT_WHITE_LIST_SIZE = 100;
}
AmsConfigurationParameter::AmsConfigurationParameter() {}
@ -218,6 +219,7 @@ int AmsConfigurationParameter::LoadAmsConfiguration(const std::string &filePath)
LoadBackToCallerConfig(amsJson);
LoadSupportSCBCrashRebootConfig(amsJson);
SetPickerJsonObject(amsJson);
LoadResidentWhiteListConfig(amsJson);
amsJson.clear();
inFile.close();
@ -349,5 +351,42 @@ int AmsConfigurationParameter::MultiUserType() const
{
return multiUserType_;
}
void AmsConfigurationParameter::LoadResidentWhiteListConfig(nlohmann::json& Object)
{
if (!Object.contains(AmsConfig::RESIDENT_WHITE_LIST)) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "no normal_resident_apps");
return;
}
const auto &whiteListJson = Object.at(AmsConfig::RESIDENT_WHITE_LIST);
if (!whiteListJson.is_array()) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "normal_resident_apps type error");
return;
}
auto size = whiteListJson.size();
if (size > MAX_RESIDENT_WHITE_LIST_SIZE) {
size = MAX_RESIDENT_WHITE_LIST_SIZE;
}
for (decltype(size) i = 0; i < size; i++) {
const auto &item = whiteListJson.at(i);
if (item.is_string()) {
residentWhiteList_.push_back(item.get<std::string>());
}
}
}
bool AmsConfigurationParameter::InResidentWhiteList(const std::string &bundleName) const
{
if (residentWhiteList_.empty()) {
return true;
}
for (const auto &item: residentWhiteList_) {
if (bundleName == item) {
return true;
}
}
return false;
}
} // namespace AAFwk
} // namespace OHOS

View File

@ -23,23 +23,53 @@
namespace OHOS {
namespace AAFwk {
namespace {
bool IsMainElementTypeOk(const AppExecFwk::AbilityInfo &abilityInfo, int32_t userId)
bool IsMainElementTypeOk(const AppExecFwk::HapModuleInfo &hapModuleInfo, const std::string &mainElement,
int32_t userId)
{
if (userId == 0) {
if (abilityInfo.type != AppExecFwk::AbilityType::PAGE) {
return true;
for (const auto &abilityInfo: hapModuleInfo.abilityInfos) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "compare ability: %{public}s", abilityInfo.name.c_str());
if (abilityInfo.name == mainElement) {
return abilityInfo.type != AppExecFwk::AbilityType::PAGE;
}
}
return true;
} else {
if (abilityInfo.type == AppExecFwk::AbilityType::EXTENSION &&
abilityInfo.extensionAbilityType == AppExecFwk::ExtensionAbilityType::SERVICE) {
return true;
for (const auto &extensionInfo: hapModuleInfo.extensionInfos) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "compare extension: %{public}s", extensionInfo.name.c_str());
if (extensionInfo.name == mainElement) {
return extensionInfo.type == AppExecFwk::ExtensionAbilityType::SERVICE;
}
}
return false;
}
TAG_LOGI(AAFwkTag::ABILITYMGR, "IsMainElementTypeOk: %{public}s, %{public}d, %{public}d",
abilityInfo.name.c_str(), userId, abilityInfo.type);
return false;
}
}
ResidentAbilityInfoGuard::ResidentAbilityInfoGuard(const std::string &bundleName,
std::string &abilityName, int32_t userId)
{
residentId_ = DelayedSingleton<ResidentProcessManager>::GetInstance()->PutResidentAbility(bundleName,
abilityName, userId);
}
ResidentAbilityInfoGuard::~ResidentAbilityInfoGuard()
{
if (residentId_ != -1) {
DelayedSingleton<ResidentProcessManager>::GetInstance()->RemoveResidentAbility(residentId_);
}
}
void ResidentAbilityInfoGuard::SetResidentAbilityInfo(const std::string &bundleName,
std::string &abilityName, int32_t userId)
{
if (residentId_ != -1) {
return;
}
residentId_ = DelayedSingleton<ResidentProcessManager>::GetInstance()->PutResidentAbility(bundleName,
abilityName, userId);
}
ResidentProcessManager::ResidentProcessManager()
{}
@ -63,6 +93,10 @@ void ResidentProcessManager::StartResidentProcessWithMainElement(std::vector<App
std::set<uint32_t> needEraseIndexSet;
for (size_t i = 0; i < bundleInfos.size(); i++) {
if (userId != 0 && !AmsConfigurationParameter::GetInstance().InResidentWhiteList(bundleInfos[i].name)) {
needEraseIndexSet.insert(i);
continue;
}
std::string processName = bundleInfos[i].applicationInfo.process;
bool keepAliveEnable = bundleInfos[i].isKeepAlive;
// Check startup permissions
@ -81,6 +115,7 @@ void ResidentProcessManager::StartResidentProcessWithMainElement(std::vector<App
// startAbility
Want want;
want.SetElementName(hapModuleInfo.bundleName, mainElement);
ResidentAbilityInfoGuard residentAbilityInfoGuard(hapModuleInfo.bundleName, mainElement, userId);
TAG_LOGI(AAFwkTag::ABILITYMGR, "call, bundleName: %{public}s, mainElement: %{public}s",
hapModuleInfo.bundleName.c_str(), mainElement.c_str());
DelayedSingleton<AbilityManagerService>::GetInstance()->StartAbility(want, userId,
@ -130,26 +165,21 @@ bool ResidentProcessManager::CheckMainElement(const AppExecFwk::HapModuleInfo &h
return false;
}
} else {
TAG_LOGI(AAFwkTag::ABILITYMGR, "new mode: %{public}s", hapModuleInfo.bundleName.c_str());
// new application model
mainElement = hapModuleInfo.mainElementName;
if (mainElement.empty()) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "mainElement empty");
return false;
}
// new application model, user model 'process'
if (hapModuleInfo.process != processName) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "processName err: %{public}s", processName.c_str());
return false;
}
}
// ability need to start, but need to filt page ability
for (auto abilityInfo : hapModuleInfo.abilityInfos) {
if (abilityInfo.name == mainElement) {
return IsMainElementTypeOk(abilityInfo, userId);
}
}
return userId == 0 ? true : false;
return IsMainElementTypeOk(hapModuleInfo, mainElement, userId);
}
int32_t ResidentProcessManager::SetResidentProcessEnabled(
@ -275,5 +305,42 @@ void ResidentProcessManager::OnAppStateChanged(const AppInfo &info)
}
IN_PROCESS_CALL_WITHOUT_RET(appMgrClient->SetKeepAliveEnableState(bundleName, localEnable));
}
int32_t ResidentProcessManager::PutResidentAbility(const std::string &bundleName,
std::string &abilityName, int32_t userId)
{
std::lock_guard lock(residentAbilityInfoMutex_);
auto residentId = residentId_++;
residentAbilityInfos_.push_back(ResidentAbilityInfo {
.bundleName = bundleName,
.abilityName = abilityName,
.userId = userId,
.residentId = residentId
});
return residentId;
}
bool ResidentProcessManager::IsResidentAbility(const std::string &bundleName,
const std::string &abilityName, int32_t userId)
{
std::lock_guard lock(residentAbilityInfoMutex_);
for (const auto &item: residentAbilityInfos_) {
if (item.bundleName == bundleName && item.abilityName == abilityName && item.userId == userId) {
return true;
}
}
return false;
}
void ResidentProcessManager::RemoveResidentAbility(int32_t residentId)
{
std::lock_guard lock(residentAbilityInfoMutex_);
for (auto it = residentAbilityInfos_.begin(); it != residentAbilityInfos_.end(); ++it) {
if (it->residentId == residentId) {
residentAbilityInfos_.erase(it);
return;
}
}
}
} // namespace AAFwk
} // namespace OHOS

View File

@ -2174,6 +2174,7 @@ std::shared_ptr<AppRunningRecord> AppMgrServiceInner::CreateAppRunningRecord(spt
}
appRecord->SetProcessAndExtensionType(abilityInfo);
appRecord->SetKeepAliveEnableState(bundleInfo.isKeepAlive);
appRecord->SetEmptyKeepAliveAppState(false);
appRecord->SetTaskHandler(taskHandler_);
appRecord->SetEventHandler(eventHandler_);
@ -3764,8 +3765,7 @@ void AppMgrServiceInner::RestartResidentProcess(std::shared_ptr<AppRunningRecord
auto bundleMgrHelper = remoteClientManager_->GetBundleManagerHelper();
BundleInfo bundleInfo;
auto callerUid = IPCSkeleton::GetCallingUid();
auto userId = GetUserIdByUid(callerUid);
auto userId = GetUserIdByUid(appRecord->GetUid());
if (!IN_PROCESS_CALL(bundleMgrHelper->GetBundleInfo(
appRecord->GetBundleName(), BundleFlag::GET_BUNDLE_DEFAULT, bundleInfo, userId))) {
TAG_LOGE(AAFwkTag::APPMGR, "getBundleInfo fail");
@ -6461,7 +6461,8 @@ void AppMgrServiceInner::ClearAppRunningDataForKeepAlive(const std::shared_ptr<A
return;
}
if (appRecord->IsKeepAliveApp()) {
auto userId = GetUserIdByUid(appRecord->GetUid());
if (appRecord->IsKeepAliveApp() && (userId == 0 || userId == currentUserId_)) {
if (ExitResidentProcessManager::GetInstance().IsKilledForUpgradeWeb(appRecord->GetBundleName())) {
TAG_LOGI(AAFwkTag::APPMGR, "is killed for upgrade web");
return;