/* * Copyright (c) 2021 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_record.h" #include "hilog_wrapper.h" #include "ability_util.h" namespace OHOS { namespace AAFwk { int MissionRecord::nextMissionId_ = 0; MissionRecord::MissionRecord(const std::string &bundleName) : bundleName_(bundleName) { missionId_ = GetNextMissionId(); option_.missionId = missionId_; } MissionRecord::MissionRecord(const std::shared_ptr &mission) { bundleName_ = mission->bundleName_; missionId_ = mission->missionId_; abilities_.insert(abilities_.begin(), mission->abilities_.begin(), mission->abilities_.end()); isLauncherCreate_ = mission->isLauncherCreate_; preMissionRecord_ = mission->preMissionRecord_; parentMissionStack_ = mission->parentMissionStack_; missionDescriptionInfo_ = mission->missionDescriptionInfo_; } MissionRecord::~MissionRecord() {} int MissionRecord::GetNextMissionId() { return nextMissionId_++; } int MissionRecord::GetMissionRecordId() const { return missionId_; } int MissionRecord::GetAbilityRecordCount() const { return abilities_.size(); } std::shared_ptr MissionRecord::GetBottomAbilityRecord() const { if (abilities_.empty()) { HILOG_ERROR("abilities is empty"); return nullptr; } return abilities_.back(); } std::shared_ptr MissionRecord::GetTopAbilityRecord() const { if (abilities_.empty()) { HILOG_ERROR("abilities is empty"); return nullptr; } return abilities_.front(); } std::shared_ptr MissionRecord::GetLastTopAbility() const { if (abilities_.empty() || abilities_.size() == 1) { HILOG_WARN("no last top ability."); return nullptr; } auto iter = abilities_.begin(); return (*(++iter)); } std::shared_ptr MissionRecord::GetAbilityRecordByToken(const sptr &token) const { auto abilityToFind = Token::GetAbilityRecordByToken(token); CHECK_POINTER_AND_RETURN(abilityToFind, nullptr); auto isExist = [targetAbility = abilityToFind](const std::shared_ptr &ability) { if (ability == nullptr) { return false; } return targetAbility == ability; }; auto iter = std::find_if(abilities_.begin(), abilities_.end(), isExist); if (iter != abilities_.end()) { return *iter; } return nullptr; } std::shared_ptr MissionRecord::GetAbilityRecordById(const int64_t recordId) const { for (std::shared_ptr ability : abilities_) { if (ability != nullptr && ability->GetRecordId() == recordId) { return ability; } } return nullptr; } std::shared_ptr MissionRecord::GetAbilityRecordByCaller( const std::shared_ptr &caller, int requestCode) { for (auto &ability : abilities_) { auto callerList = ability->GetCallerRecordList(); for (auto callerAbility : callerList) { if (callerAbility->GetCaller() == caller && callerAbility->GetRequestCode() == requestCode) { return ability; } } } return nullptr; } void MissionRecord::AddAbilityRecordToTop(std::shared_ptr ability) { CHECK_POINTER(ability); auto isExist = [targetAbility = ability](const std::shared_ptr &ability) { if (ability == nullptr) { return false; } return targetAbility == ability; }; auto iter = std::find_if(abilities_.begin(), abilities_.end(), isExist); if (iter == abilities_.end()) { abilities_.push_front(ability); ability->ForceProcessConfigurationChange(GetConfiguration()); } } bool MissionRecord::RemoveAbilityRecord(std::shared_ptr ability) { CHECK_POINTER_RETURN_BOOL(ability); for (auto iter = abilities_.begin(); iter != abilities_.end(); iter++) { if ((*iter) == ability) { abilities_.erase(iter); return true; } } HILOG_ERROR("can not find ability"); return false; } bool MissionRecord::RemoveTopAbilityRecord() { if (abilities_.empty()) { HILOG_ERROR("abilities is empty"); return false; } abilities_.pop_front(); return true; } void MissionRecord::RemoveAll() { abilities_.clear(); } void MissionRecord::Dump(std::vector &info) { std::string dumpInfo = " MissionRecord ID #" + std::to_string(missionId_); std::shared_ptr bottomAbility = GetBottomAbilityRecord(); if (bottomAbility) { dumpInfo += " bottom app [" + bottomAbility->GetAbilityInfo().name + "]"; info.push_back(dumpInfo); for (auto abilityRecord : abilities_) { abilityRecord->Dump(info); } } } bool MissionRecord::IsSameMissionRecord(const std::string &bundleName) const { if (bundleName.empty() || bundleName_.empty()) { return false; } return (bundleName == bundleName_); } void MissionRecord::GetAllAbilityInfo(std::vector &abilityInfos) { for (auto ability : abilities_) { AbilityRecordInfo abilityInfo; ability->GetAbilityRecordInfo(abilityInfo); abilityInfos.emplace_back(abilityInfo); } } bool MissionRecord::IsTopAbilityRecordByName(const std::string &abilityName) { std::shared_ptr topAbility = GetTopAbilityRecord(); if (topAbility == nullptr) { return false; } return (topAbility->GetAbilityInfo().name.compare(abilityName) == 0); } void MissionRecord::SetIsLauncherCreate() { isLauncherCreate_ = true; } bool MissionRecord::IsLauncherCreate() const { return isLauncherCreate_; } void MissionRecord::SetPreMissionRecord(const std::shared_ptr &record) { preMissionRecord_ = record; } std::shared_ptr MissionRecord::GetPreMissionRecord() const { return preMissionRecord_.lock(); } bool MissionRecord::IsExistAbilityRecord(int32_t id) { for (auto &it : abilities_) { if (it->GetRecordId() == id) { return true; } } return false; } bool MissionRecord::SupportMultWindow() const { auto bottom = GetBottomAbilityRecord(); if (bottom != nullptr) { return bottom->SupportMultWindow(); } return false; } void MissionRecord::SetMissionStack(const std::shared_ptr &missionStack, int stackId) { CHECK_POINTER(missionStack); parentMissionStack_ = missionStack; ConfigurationHolder::Init(missionStack->GetConfiguration()); for (auto &it : abilities_) { it->SetMissionStackId(stackId); } } std::shared_ptr MissionRecord::GetMissionStack() const { return parentMissionStack_.lock(); } void MissionRecord::SetMissionOption(const MissionOption &option) { if (option.winModeKey != option_.winModeKey) { HILOG_ERROR("Batch processing notify multi window mode changed."); for (auto &it : abilities_) { CHECK_POINTER(it); bool flag = option.winModeKey == AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_PRIMARY || option.winModeKey == AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_SECONDARY || option.winModeKey == AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_FLOATING; // true : old is multi win, target is fullscreen. // false : old is fullscreen, target is multi win. auto key = flag ? option.winModeKey : option_.winModeKey; if (it->IsReady()) { it->NotifyMultiWinModeChanged(key, flag); } } } option_ = option; } const MissionOption &MissionRecord::GetMissionOption() const { return option_; } bool MissionRecord::IsEmpty() { return abilities_.empty(); } std::shared_ptr MissionRecord::GetParent() { return parentMissionStack_.lock(); } unsigned int MissionRecord::GetChildSize() { return abilities_.size(); } std::shared_ptr MissionRecord::FindChild(unsigned int index) { if (index < abilities_.size() && index >= 0) { auto iter = abilities_.begin(); std::advance(iter, index); return (*iter); } return nullptr; } void MissionRecord::Resume(const std::shared_ptr &backup) { HILOG_INFO("mission resume."); // backup abilities_ size = 1, singleton ability need resume if (std::equal(abilities_.begin(), abilities_.end(), backup->abilities_.begin()) && backup->abilities_.size() > 1) { HILOG_ERROR("List equality, no resume"); return; } std::list> diffAbilitys; for (auto &ability : backup->abilities_) { if (abilities_.front() == ability) { break; } ability->SetAbilityState(AbilityState::INITIAL); diffAbilitys.emplace_back(ability); } abilities_.insert(abilities_.begin(), diffAbilitys.begin(), diffAbilitys.end()); for (auto &ability : abilities_) { if (ability->IsAbilityState(AbilityState::INITIAL)) { ability->ClearFlag(); ability->SetRestarting(true); } } } } // namespace AAFwk } // namespace OHOS