* Copyright (c) 2021-2024 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 "mission_list.h"
#include "hilog_tag_wrapper.h"
#include "hitrace_meter.h"
namespace OHOS {
namespace AAFwk {
MissionList::MissionList(MissionListType type) : type_(type)
{
}
MissionList::~MissionList()
{
}
void MissionList::AddMissionToTop(const std::shared_ptr<Mission> &mission)
{
if (!mission) {
return;
}
if (!missions_.empty() && missions_.front() == mission) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "mission is already at the top of list");
return;
}
missions_.remove(mission);
missions_.push_front(mission);
mission->SetMissionList(shared_from_this());
}
void MissionList::RemoveMission(const std::shared_ptr<Mission> &mission)
{
for (auto iter = missions_.begin(); iter != missions_.end(); iter++) {
if (*iter == mission) {
missions_.erase(iter);
return;
}
}
}
std::shared_ptr<Mission> MissionList::GetTopMission() const
{
if (missions_.empty()) {
return nullptr;
}
return missions_.front();
}
std::shared_ptr<Mission> MissionList::GetSingletonMissionByName(const std::string &missionName) const
{
if (missionName.empty()) {
return nullptr;
}
for (auto mission : missions_) {
if (mission && mission->IsSingletonAbility() && mission->GetMissionName() == missionName) {
return mission;
}
}
return nullptr;
}
std::shared_ptr<Mission> MissionList::GetSpecifiedMission(
const std::string &missionName, const std::string& flag) const
{
if (missionName.empty() || flag.empty()) {
return nullptr;
}
for (auto& mission : missions_) {
if (mission && mission->IsSpecifiedAbility() && mission->GetMissionName() == missionName &&
mission->GetSpecifiedFlag() == flag) {
return mission;
}
}
return nullptr;
}
std::shared_ptr<Mission> MissionList::GetRecentStandardMission(const std::string &missionName) const
{
if (missionName.empty()) {
return nullptr;
}
std::string missionTime = "0";
std::shared_ptr<Mission> result = nullptr;
for (auto& mission : missions_) {
if (mission && mission->IsStandardAbility() && mission->GetMissionName() == missionName &&
mission->GetMissionTime() >= missionTime) {
result = mission;
missionTime = mission->GetMissionTime();
}
}
return result;
}
std::shared_ptr<AbilityRecord> MissionList::GetAbilityRecordByToken(const sptr<IRemoteObject> &token) const
{
for (auto mission : missions_) {
if (!mission) {
continue;
}
std::shared_ptr<AbilityRecord> abilityRecord = mission->GetAbilityRecord();
if (abilityRecord && token == abilityRecord->GetToken()->AsObject()) {
return abilityRecord;
}
}
return nullptr;
}
void MissionList::RemoveMissionByAbilityRecord(const std::shared_ptr<AbilityRecord> &abilityRecord)
{
for (auto iter = missions_.begin(); iter != missions_.end(); iter++) {
if ((*iter)->GetAbilityRecord() == abilityRecord) {
missions_.erase(iter);
return;
}
}
}
std::shared_ptr<Mission> MissionList::GetMissionById(int missionId) const
{
for (auto mission : missions_) {
if (mission && mission->GetMissionId() == missionId) {
return mission;
}
}
return nullptr;
}
std::shared_ptr<Mission> MissionList::GetMissionBySpecifiedFlag(const AAFwk::Want &want, const std::string &flag) const
{
for (auto mission : missions_) {
if (!mission) {
return nullptr;
}
auto ability = mission->GetAbilityRecord();
if (!ability) {
return nullptr;
}
std::string srcAbilityName = ability->GetAbilityInfo().name;
std::string srcBundleName = ability->GetApplicationInfo().bundleName;
std::string tarAbilityName = want.GetAbilityNameRef();
std::string tarBundleName = want.GetBundleNameRef();
if ((srcBundleName == tarBundleName) &&
(srcAbilityName == tarAbilityName) &&
(ability->GetSpecifiedFlag() == flag)) {
return mission;
}
}
return nullptr;
}
bool MissionList::IsEmpty()
{
return missions_.empty();
}
MissionAbilityRecordPtr MissionList::GetTopAbility() const
{
if (missions_.empty()) {
return nullptr;
}
auto& topMission = missions_.front();
if (topMission) {
return topMission->GetAbilityRecord();
}
return nullptr;
}
std::list<std::shared_ptr<Mission>>& MissionList::GetAllMissions()
{
return missions_;
}
MissionListType MissionList::GetType() const
{
return type_;
}
MissionAbilityRecordPtr MissionList::GetLauncherRoot() const
{
for (auto mission : missions_) {
if (!mission) {
continue;
}
auto ability = mission->GetAbilityRecord();
if (ability && ability->IsLauncherRoot()) {
return ability;
}
}
return nullptr;
}
std::shared_ptr<AbilityRecord> MissionList::GetAbilityRecordById(int64_t abilityRecordId) const
{
for (std::shared_ptr<Mission> mission : missions_) {
if (mission && mission->GetAbilityRecord()->GetAbilityRecordId() == abilityRecordId) {
return mission->GetAbilityRecord();
}
}
return nullptr;
}
std::shared_ptr<AbilityRecord> MissionList::GetAbilityRecordByCaller(
const std::shared_ptr<AbilityRecord> &caller, int requestCode)
{
for (auto mission : missions_) {
auto callerList = mission->GetAbilityRecord()->GetCallerRecordList();
if (callerList.empty()) {
continue;
}
for (auto callerAbility : callerList) {
if (callerAbility->GetCaller() == caller && callerAbility->GetRequestCode() == requestCode) {
return mission->GetAbilityRecord();
}
}
}
return nullptr;
}
std::shared_ptr<AbilityRecord> MissionList::GetAbilityRecordByName(const AppExecFwk::ElementName &element)
{
for (auto mission : missions_) {
if (mission) {
const AppExecFwk::AbilityInfo &abilityInfo = mission->GetAbilityRecord()->GetAbilityInfo();
AppExecFwk::ElementName localElement(abilityInfo.deviceId, abilityInfo.bundleName,
abilityInfo.name, abilityInfo.moduleName);
AppExecFwk::ElementName localElementNoModuleName(abilityInfo.deviceId,
abilityInfo.bundleName, abilityInfo.name);
if (localElement == element || localElementNoModuleName == element) {
return mission->GetAbilityRecord();
}
}
}
return nullptr;
}
void MissionList::GetAbilityRecordsByName(
const AppExecFwk::ElementName &element, std::vector<std::shared_ptr<AbilityRecord>> &records)
{
for (auto mission : missions_) {
if (mission && mission->GetAbilityRecord() != nullptr) {
const AppExecFwk::AbilityInfo &abilityInfo = mission->GetAbilityRecord()->GetAbilityInfo();
AppExecFwk::ElementName localElement(abilityInfo.deviceId, abilityInfo.bundleName,
abilityInfo.name, abilityInfo.moduleName);
AppExecFwk::ElementName localElementNoModuleName(abilityInfo.deviceId,
abilityInfo.bundleName, abilityInfo.name);
if (localElement == element || localElementNoModuleName == element) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "find element %{public}s", localElement.GetURI().c_str());
records.push_back(mission->GetAbilityRecord());
}
}
}
}
sptr<IRemoteObject> MissionList::GetAbilityTokenByMissionId(int32_t missionId)
{
for (auto mission : missions_) {
if (mission && mission->GetMissionId() == missionId) {
auto abilityRecord = mission->GetAbilityRecord();
if (abilityRecord) {
return abilityRecord->GetToken();
}
}
}
return nullptr;
}
std::string MissionList::GetTypeName()
{
switch (type_) {
case MissionListType::CURRENT: {
return "NORMAL";
}
case MissionListType::DEFAULT_STANDARD: {
return "DEFAULT_STANDARD";
}
case MissionListType::DEFAULT_SINGLE: {
return "DEFAULT_SINGLE";
}
case MissionListType::LAUNCHER: {
return "LAUNCHER";
}
default: {
return "INVALID";
}
}
}
void MissionList::HandleUnInstallApp(const std::string &bundleName, int32_t uid)
{
for (auto it = missions_.begin(); it != missions_.end();) {
auto mission = *it;
if (MatchedInitialMission(mission, bundleName, uid)) {
it = missions_.erase(it);
} else {
it++;
}
}
}
bool MissionList::MatchedInitialMission(const std::shared_ptr<Mission>& mission,
const std::string &bundleName, int32_t uid)
{
if (!mission) {
return false;
}
auto abilityRecord = mission->GetAbilityRecord();
if (!abilityRecord) {
return false;
}
if (abilityRecord->GetAbilityInfo().bundleName == bundleName && abilityRecord->GetUid() == uid) {
abilityRecord->SetIsUninstallAbility();
if (abilityRecord->IsAbilityState(AbilityState::INITIAL)) {
return true;
}
}
return false;
}
void MissionList::Dump(std::vector<std::string>& info)
{
std::string dumpInfo = " MissionList Type #" + GetTypeName();
info.push_back(dumpInfo);
for (const auto& mission : missions_) {
if (mission) {
mission->Dump(info);
}
}
}
void MissionList::DumpStateByRecordId(
std::vector<std::string> &info, bool isClient, int32_t abilityRecordId, const std::vector<std::string> ¶ms)
{
for (const auto& mission : missions_) {
if (mission) {
auto abilityRecord = mission->GetAbilityRecord();
if (abilityRecord) {
if (abilityRecord->GetRecordId() == abilityRecordId) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "record begin to call DumpAbilityState %{public}s", __func__);
abilityRecord->DumpAbilityState(info, isClient, params);
return;
}
}
}
}
}
void MissionList::DumpList(std::vector<std::string> &info, bool isClient)
{
std::string dumpInfo = " MissionList Type #" + GetTypeName();
info.push_back(dumpInfo);
for (const auto& mission : missions_) {
if (mission) {
dumpInfo = " Mission ID #" + std::to_string(mission->GetMissionId());
dumpInfo += " mission name #[" + mission->GetMissionName() + "]" +
" lockedState #" + std::to_string(mission->IsLockedState());
info.push_back(dumpInfo);
auto abilityRecord = mission->GetAbilityRecord();
if (abilityRecord) {
TAG_LOGI(AAFwkTag::ABILITYMGR, "record begin to call DumpAbilityState %{public}s", __func__);
std::vector<std::string> params;
abilityRecord->DumpAbilityState(info, isClient, params);
}
}
}
}
int32_t MissionList::GetMissionCountByUid(int32_t targetUid) const
{
int32_t count = 0;
for (const auto& mission : missions_) {
if (!mission) {
continue;
}
auto abilityRecord = mission->GetAbilityRecord();
if (!abilityRecord) {
continue;
}
if (abilityRecord->GetUid() == targetUid) {
count++;
}
}
return count;
}
void MissionList::FindEarliestMission(std::shared_ptr<Mission>& targetMission) const
{
for (const auto& mission : missions_) {
if (!mission) {
continue;
}
auto abilityRecord = mission->GetAbilityRecord();
if (!abilityRecord) {
continue;
}
if (!abilityRecord->IsAbilityState(AbilityState::BACKGROUND) ||
(targetMission && targetMission->GetMissionTime() < mission->GetMissionTime())) {
continue;
}
targetMission = mission;
}
}
int32_t MissionList::GetMissionCount() const
{
return static_cast<int32_t>(missions_.size());
}
void MissionList::GetActiveAbilityList(int32_t uid, std::vector<std::string> &abilityList, int32_t pid)
{
for (auto mission : missions_) {
if (!mission) {
continue;
}
auto abilityRecord = mission->GetAbilityRecord();
if (!abilityRecord) {
continue;
}
if (pid != NO_PID && abilityRecord->GetPid() != pid) {
continue;
}
const AppExecFwk::AbilityInfo &abilityInfo = abilityRecord->GetAbilityInfo();
if (abilityInfo.applicationInfo.uid == uid && !abilityInfo.name.empty()) {
TAG_LOGD(AAFwkTag::ABILITYMGR, "find ability name is %{public}s", abilityInfo.name.c_str());
abilityList.push_back(abilityInfo.name);
}
}
}
void MissionList::SignRestartAppFlag(int32_t uid, const std::string &instanceKey)
{
for (auto it = missions_.begin(); it != missions_.end();) {
auto mission = *it;
if (!mission) {
it++;
continue;
}
auto abilityRecord = mission->GetAbilityRecord();
if (!abilityRecord) {
it++;
continue;
}
if (abilityRecord->GetUid() != uid) {
it++;
continue;
}
if (abilityRecord->GetInstanceKey() != instanceKey) {
it++;
continue;
}
abilityRecord->SetRestartAppFlag(true);
it = missions_.erase(it);
}
}
}
}