/* * Copyright (c) 2020 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 "ability_mission_stack.h" #include "util/abilityms_log.h" namespace OHOS { namespace { constexpr static uint16_t MISSION_RECORD_LIST_CAPACITY = 10240; } AbilityMissionStack::AbilityMissionStack(StackType type) : stackType_(type) { } AbilityMissionStack::~AbilityMissionStack() { for (auto iterator = missionRecords_.begin(); iterator != missionRecords_.end();) { AbilityMissionRecord *missionRecord = *iterator; iterator = missionRecords_.erase(iterator); delete missionRecord; } } StackType AbilityMissionStack::GetStackType() const { return stackType_; } void AbilityMissionStack::PushTopMissionRecord(AbilityMissionRecord &missionRecord) { missionRecord.SetMissionStack(this); if (missionRecords_.size() >= MISSION_RECORD_LIST_CAPACITY) { return; } missionRecords_.emplace_back(&missionRecord); } void AbilityMissionStack::MoveMissionRecordToTop(AbilityMissionRecord &missionRecord) { if (missionRecords_.back() != &missionRecord) { missionRecords_.remove(&missionRecord); missionRecords_.emplace_back(&missionRecord); } } void AbilityMissionStack::RemoveMissionRecord(AbilityMissionRecord &missionRecord) { missionRecords_.remove(&missionRecord); // clear prev mission record for (const auto currentMission : missionRecords_) { if (currentMission != nullptr && currentMission->GetPrevMissionRecord() == &missionRecord) { currentMission->SetPrevMissionRecord(nullptr); } } } void AbilityMissionStack::RemoveMissionRecord(AbilityConnectMission *connectMission, const char *bundleName) { AbilityMissionRecord *missionRecord = GetTargetMissionRecord(bundleName); CHECK_NULLPTR_RETURN(missionRecord, "AbilityMissionStack", "missionRecord is null"); missionRecord->ClearPageAbility(connectMission); RemoveMissionRecord(*missionRecord); delete missionRecord; } bool AbilityMissionStack::IsTopMissionRecord(const char *bundleName) const { if (bundleName == nullptr) { return false; } AbilityMissionRecord *topMissionRecord = missionRecords_.back(); if (topMissionRecord != nullptr) { return topMissionRecord->IsSameMissionRecord(bundleName); } return false; } AbilityMissionRecord *AbilityMissionStack::GetTargetMissionRecord(const char *bundleName) const { CHECK_NULLPTR_RETURN_PTR(bundleName, "AbilityMissionStack", "invalid argument"); for (const auto missionRecord : missionRecords_) { if (missionRecord != nullptr && missionRecord->IsSameMissionRecord(bundleName)) { return missionRecord; } } return nullptr; } const AbilityMissionRecord *AbilityMissionStack::GetTopMissionRecord() const { return missionRecords_.back(); } PageAbilityRecord *AbilityMissionStack::FindPageAbility(uint64_t token) const { for (const auto missionRecord : missionRecords_) { if (missionRecord == nullptr) { continue; } PageAbilityRecord *record = missionRecord->FindPageAbility(token); if (record != nullptr) { return record; } } return nullptr; } PageAbilityRecord *AbilityMissionStack::FindPageAbility(const Want &want) const { CHECK_NULLPTR_RETURN_PTR(want.element, "AbilityMissionStack", "invalid argument"); AbilityMissionRecord *missionRecord = GetTargetMissionRecord(want.element->bundleName); if (missionRecord != nullptr) { return missionRecord->FindPageAbility(want); } return nullptr; } const PageAbilityRecord *AbilityMissionStack::GetTopPageAbility() const { if (!missionRecords_.empty()) { return missionRecords_.back()->GetTopPageAbility(); } return nullptr; } #ifdef OHOS_DEBUG AbilityMsStatus AbilityMissionStack::DumpMissionStack() const { if (missionRecords_.size() <= 0) { return AbilityMsStatus::DumpStatus(""); } std::string stackType = (stackType_ == LAUNCHER) ? "launcher\n" : "default\n"; std::string stackInfo = "MissionStack Type: " + stackType; AbilityMsStatus result = AbilityMsStatus::DumpStatus(stackInfo.c_str()); for (const auto missionRecord : missionRecords_) { if (missionRecord != nullptr) { result.DumpAppend(missionRecord->DumpMissionRecord()); } } return result; } #endif } // namespace OHOS