• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "mission_record.h"
17 
18 #include "hilog_wrapper.h"
19 #include "ability_util.h"
20 
21 namespace OHOS {
22 namespace AAFwk {
23 int MissionRecord::nextMissionId_ = 0;
24 
MissionRecord(const std::string & bundleName)25 MissionRecord::MissionRecord(const std::string &bundleName) : bundleName_(bundleName)
26 {
27     missionId_ = GetNextMissionId();
28     option_.missionId = missionId_;
29 }
30 
MissionRecord(const std::shared_ptr<MissionRecord> & mission)31 MissionRecord::MissionRecord(const std::shared_ptr<MissionRecord> &mission)
32 {
33     bundleName_ = mission->bundleName_;
34     missionId_ = mission->missionId_;
35     abilities_.insert(abilities_.begin(), mission->abilities_.begin(), mission->abilities_.end());
36     isLauncherCreate_ = mission->isLauncherCreate_;
37     preMissionRecord_ = mission->preMissionRecord_;
38     parentMissionStack_ = mission->parentMissionStack_;
39     missionDescriptionInfo_ = mission->missionDescriptionInfo_;
40 }
41 
~MissionRecord()42 MissionRecord::~MissionRecord()
43 {}
44 
GetNextMissionId()45 int MissionRecord::GetNextMissionId()
46 {
47     return nextMissionId_++;
48 }
49 
GetMissionRecordId() const50 int MissionRecord::GetMissionRecordId() const
51 {
52     return missionId_;
53 }
54 
GetAbilityRecordCount() const55 int MissionRecord::GetAbilityRecordCount() const
56 {
57     return abilities_.size();
58 }
59 
GetBottomAbilityRecord() const60 std::shared_ptr<AbilityRecord> MissionRecord::GetBottomAbilityRecord() const
61 {
62     if (abilities_.empty()) {
63         HILOG_ERROR("abilities is empty");
64         return nullptr;
65     }
66     return abilities_.back();
67 }
68 
GetTopAbilityRecord() const69 std::shared_ptr<AbilityRecord> MissionRecord::GetTopAbilityRecord() const
70 {
71     if (abilities_.empty()) {
72         HILOG_ERROR("abilities is empty");
73         return nullptr;
74     }
75     return abilities_.front();
76 }
77 
GetLastTopAbility() const78 std::shared_ptr<AbilityRecord> MissionRecord::GetLastTopAbility() const
79 {
80     if (abilities_.empty() || abilities_.size() == 1) {
81         HILOG_WARN("no last top ability.");
82         return nullptr;
83     }
84     auto iter = abilities_.begin();
85     return (*(++iter));
86 }
87 
GetAbilityRecordByToken(const sptr<IRemoteObject> & token) const88 std::shared_ptr<AbilityRecord> MissionRecord::GetAbilityRecordByToken(const sptr<IRemoteObject> &token) const
89 {
90     auto abilityToFind = Token::GetAbilityRecordByToken(token);
91     CHECK_POINTER_AND_RETURN(abilityToFind, nullptr);
92 
93     auto isExist = [targetAbility = abilityToFind](const std::shared_ptr<AbilityRecord> &ability) {
94         if (ability == nullptr) {
95             return false;
96         }
97         return targetAbility == ability;
98     };
99 
100     auto iter = std::find_if(abilities_.begin(), abilities_.end(), isExist);
101     if (iter != abilities_.end()) {
102         return *iter;
103     }
104 
105     return nullptr;
106 }
107 
GetAbilityRecordById(const int64_t recordId) const108 std::shared_ptr<AbilityRecord> MissionRecord::GetAbilityRecordById(const int64_t recordId) const
109 {
110     for (std::shared_ptr<AbilityRecord> ability : abilities_) {
111         if (ability != nullptr && ability->GetRecordId() == recordId) {
112             return ability;
113         }
114     }
115     return nullptr;
116 }
117 
GetAbilityRecordByCaller(const std::shared_ptr<AbilityRecord> & caller,int requestCode)118 std::shared_ptr<AbilityRecord> MissionRecord::GetAbilityRecordByCaller(
119     const std::shared_ptr<AbilityRecord> &caller, int requestCode)
120 {
121     for (auto &ability : abilities_) {
122         auto callerList = ability->GetCallerRecordList();
123         for (auto callerAbility : callerList) {
124             if (callerAbility->GetCaller() == caller && callerAbility->GetRequestCode() == requestCode) {
125                 return ability;
126             }
127         }
128     }
129     return nullptr;
130 }
131 
AddAbilityRecordToTop(std::shared_ptr<AbilityRecord> ability)132 void MissionRecord::AddAbilityRecordToTop(std::shared_ptr<AbilityRecord> ability)
133 {
134     CHECK_POINTER(ability);
135     auto isExist = [targetAbility = ability](const std::shared_ptr<AbilityRecord> &ability) {
136         if (ability == nullptr) {
137             return false;
138         }
139         return targetAbility == ability;
140     };
141     auto iter = std::find_if(abilities_.begin(), abilities_.end(), isExist);
142     if (iter == abilities_.end()) {
143         abilities_.push_front(ability);
144         ability->ForceProcessConfigurationChange(GetConfiguration());
145     }
146 }
147 
RemoveAbilityRecord(std::shared_ptr<AbilityRecord> ability)148 bool MissionRecord::RemoveAbilityRecord(std::shared_ptr<AbilityRecord> ability)
149 {
150     CHECK_POINTER_RETURN_BOOL(ability);
151     for (auto iter = abilities_.begin(); iter != abilities_.end(); iter++) {
152         if ((*iter) == ability) {
153             abilities_.erase(iter);
154             return true;
155         }
156     }
157     HILOG_ERROR("can not find ability");
158     return false;
159 }
160 
RemoveTopAbilityRecord()161 bool MissionRecord::RemoveTopAbilityRecord()
162 {
163     if (abilities_.empty()) {
164         HILOG_ERROR("abilities is empty");
165         return false;
166     }
167     abilities_.pop_front();
168     return true;
169 }
170 
RemoveAll()171 void MissionRecord::RemoveAll()
172 {
173     abilities_.clear();
174 }
175 
Dump(std::vector<std::string> & info)176 void MissionRecord::Dump(std::vector<std::string> &info)
177 {
178     std::string dumpInfo = "    MissionRecord ID #" + std::to_string(missionId_);
179     std::shared_ptr<AbilityRecord> bottomAbility = GetBottomAbilityRecord();
180     if (bottomAbility) {
181         dumpInfo += "  bottom app [" + bottomAbility->GetAbilityInfo().name + "]";
182         info.push_back(dumpInfo);
183         for (auto abilityRecord : abilities_) {
184             abilityRecord->Dump(info);
185         }
186     }
187 }
188 
IsSameMissionRecord(const std::string & bundleName) const189 bool MissionRecord::IsSameMissionRecord(const std::string &bundleName) const
190 {
191     if (bundleName.empty() || bundleName_.empty()) {
192         return false;
193     }
194     return (bundleName == bundleName_);
195 }
196 
GetAllAbilityInfo(std::vector<AbilityRecordInfo> & abilityInfos)197 void MissionRecord::GetAllAbilityInfo(std::vector<AbilityRecordInfo> &abilityInfos)
198 {
199     for (auto ability : abilities_) {
200         AbilityRecordInfo abilityInfo;
201         ability->GetAbilityRecordInfo(abilityInfo);
202         abilityInfos.emplace_back(abilityInfo);
203     }
204 }
205 
IsTopAbilityRecordByName(const std::string & abilityName)206 bool MissionRecord::IsTopAbilityRecordByName(const std::string &abilityName)
207 {
208     std::shared_ptr<AbilityRecord> topAbility = GetTopAbilityRecord();
209     if (topAbility == nullptr) {
210         return false;
211     }
212 
213     return (topAbility->GetAbilityInfo().name.compare(abilityName) == 0);
214 }
215 
SetIsLauncherCreate()216 void MissionRecord::SetIsLauncherCreate()
217 {
218     isLauncherCreate_ = true;
219 }
220 
IsLauncherCreate() const221 bool MissionRecord::IsLauncherCreate() const
222 {
223     return isLauncherCreate_;
224 }
225 
SetPreMissionRecord(const std::shared_ptr<MissionRecord> & record)226 void MissionRecord::SetPreMissionRecord(const std::shared_ptr<MissionRecord> &record)
227 {
228     preMissionRecord_ = record;
229 }
230 
GetPreMissionRecord() const231 std::shared_ptr<MissionRecord> MissionRecord::GetPreMissionRecord() const
232 {
233     return preMissionRecord_.lock();
234 }
235 
IsExistAbilityRecord(int32_t id)236 bool MissionRecord::IsExistAbilityRecord(int32_t id)
237 {
238     for (auto &it : abilities_) {
239         if (it->GetRecordId() == id) {
240             return true;
241         }
242     }
243     return false;
244 }
245 
SupportMultWindow() const246 bool MissionRecord::SupportMultWindow() const
247 {
248     auto bottom = GetBottomAbilityRecord();
249     if (bottom != nullptr) {
250         return bottom->SupportMultWindow();
251     }
252     return false;
253 }
254 
SetMissionStack(const std::shared_ptr<MissionStack> & missionStack,int stackId)255 void MissionRecord::SetMissionStack(const std::shared_ptr<MissionStack> &missionStack, int stackId)
256 {
257     CHECK_POINTER(missionStack);
258     parentMissionStack_ = missionStack;
259     ConfigurationHolder::Init(missionStack->GetConfiguration());
260     for (auto &it : abilities_) {
261         it->SetMissionStackId(stackId);
262     }
263 }
264 
GetMissionStack() const265 std::shared_ptr<MissionStack> MissionRecord::GetMissionStack() const
266 {
267     return parentMissionStack_.lock();
268 }
269 
SetMissionOption(const MissionOption & option)270 void MissionRecord::SetMissionOption(const MissionOption &option)
271 {
272     if (option.winModeKey != option_.winModeKey) {
273         HILOG_ERROR("Batch processing notify multi window mode changed.");
274         for (auto &it : abilities_) {
275             CHECK_POINTER(it);
276             bool flag = option.winModeKey == AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_PRIMARY ||
277                         option.winModeKey == AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_SECONDARY ||
278                         option.winModeKey == AbilityWindowConfiguration::MULTI_WINDOW_DISPLAY_FLOATING;
279             // true : old is multi win, target is fullscreen.
280             // false : old is fullscreen, target is multi win.
281             auto key = flag ? option.winModeKey : option_.winModeKey;
282             if (it->IsReady()) {
283                 it->NotifyMultiWinModeChanged(key, flag);
284             }
285         }
286     }
287 
288     option_ = option;
289 }
290 
GetMissionOption() const291 const MissionOption &MissionRecord::GetMissionOption() const
292 {
293     return option_;
294 }
295 
IsEmpty()296 bool MissionRecord::IsEmpty()
297 {
298     return abilities_.empty();
299 }
300 
GetParent()301 std::shared_ptr<ConfigurationHolder> MissionRecord::GetParent()
302 {
303     return parentMissionStack_.lock();
304 }
305 
GetChildSize()306 unsigned int MissionRecord::GetChildSize()
307 {
308     return abilities_.size();
309 }
310 
FindChild(unsigned int index)311 std::shared_ptr<ConfigurationHolder> MissionRecord::FindChild(unsigned int index)
312 {
313     if (index < abilities_.size() && index >= 0) {
314         auto iter = abilities_.begin();
315         std::advance(iter, index);
316         return (*iter);
317     }
318     return nullptr;
319 }
320 
Resume(const std::shared_ptr<MissionRecord> & backup)321 void MissionRecord::Resume(const std::shared_ptr<MissionRecord> &backup)
322 {
323     HILOG_INFO("mission resume.");
324     // backup abilities_ size = 1, singleton ability need resume
325     if (std::equal(abilities_.begin(), abilities_.end(), backup->abilities_.begin()) && backup->abilities_.size() > 1) {
326         HILOG_ERROR("List equality, no resume");
327         return;
328     }
329 
330     std::list<std::shared_ptr<AbilityRecord>> diffAbilitys;
331     for (auto &ability : backup->abilities_) {
332         if (abilities_.front() == ability) {
333             break;
334         }
335 
336         ability->SetAbilityState(AbilityState::INITIAL);
337         diffAbilitys.emplace_back(ability);
338     }
339 
340     abilities_.insert(abilities_.begin(), diffAbilitys.begin(), diffAbilitys.end());
341 
342     for (auto &ability : abilities_) {
343         if (ability->IsAbilityState(AbilityState::INITIAL)) {
344             ability->ClearFlag();
345             ability->SetRestarting(true);
346         }
347     }
348 }
349 }  // namespace AAFwk
350 }  // namespace OHOS
351