1 /*
2 * Copyright (c) 2020 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 "ability_slice_scheduler.h"
17
18 #include <ability_state.h>
19 #include <log.h>
20
21 #include "ability_loader.h"
22 #include "ability_slice_manager.h"
23
24 namespace OHOS {
AbilitySliceScheduler(AbilitySliceManager & abilitySliceManager)25 AbilitySliceScheduler::AbilitySliceScheduler(AbilitySliceManager &abilitySliceManager)
26 : abilitySliceManager_(abilitySliceManager)
27 {
28 abilitySliceRoute_ = new AbilitySliceRoute();
29 abilitySliceStack_ = new AbilitySliceStack();
30 }
31
~AbilitySliceScheduler()32 AbilitySliceScheduler::~AbilitySliceScheduler()
33 {
34 delete abilitySliceRoute_;
35 abilitySliceRoute_ = nullptr;
36 delete abilitySliceStack_;
37 abilitySliceStack_ = nullptr;
38 }
39
HandleStartAbilitySlice(const Want & want)40 void AbilitySliceScheduler::HandleStartAbilitySlice(const Want &want)
41 {
42 if (topAbilitySlice_ == nullptr) {
43 topAbilitySlice_ = GetTargetAbilitySlice();
44 if (topAbilitySlice_ == nullptr) {
45 HILOG_ERROR(HILOG_MODULE_APP, "Cannot get slice [%{public}s]", abilitySliceRoute_->GetMainRoute().c_str());
46 return;
47 }
48 }
49 topAbilitySlice_->Init(abilitySliceManager_);
50
51 topAbilitySlice_->OnStart(want);
52 }
53
HandleInactiveAbilitySlice()54 void AbilitySliceScheduler::HandleInactiveAbilitySlice()
55 {
56 if (topAbilitySlice_ == nullptr) {
57 return;
58 }
59
60 topAbilitySlice_->OnInactive();
61 }
62
HandleActiveAbilitySlice(const Want & want)63 void AbilitySliceScheduler::HandleActiveAbilitySlice(const Want &want)
64 {
65 if (topAbilitySlice_ == nullptr) {
66 HILOG_ERROR(HILOG_MODULE_APP, "top ability slice is null, active slice error");
67 return;
68 }
69
70 // add want when implicit match, not support jump by want temporary.
71
72 topAbilitySlice_->OnActive(want);
73 }
74
HandleMoveAbilitySliceToBackground()75 void AbilitySliceScheduler::HandleMoveAbilitySliceToBackground()
76 {
77 if (topAbilitySlice_ == nullptr) {
78 return;
79 }
80
81 topAbilitySlice_->OnBackground();
82 }
83
HandleStopAbilitySlice()84 void AbilitySliceScheduler::HandleStopAbilitySlice()
85 {
86 if (topAbilitySlice_ == nullptr) {
87 return;
88 }
89
90 topAbilitySlice_->OnStop();
91 while (!abilitySliceStack_->IsEmpty()) {
92 auto abilitySlice = abilitySliceStack_->Pop();
93 if (abilitySlice != nullptr) {
94 abilitySlice->OnStop();
95 }
96 }
97 delete topAbilitySlice_;
98 topAbilitySlice_ = nullptr;
99 }
100
AddAbilitySlice(const AbilitySlice & caller,AbilitySlice & target,const Want & want)101 void AbilitySliceScheduler::AddAbilitySlice(const AbilitySlice &caller, AbilitySlice &target, const Want &want)
102 {
103 // Check if this jump is legal.
104 if (!CheckLegalForAdd(caller, target, want)) {
105 HILOG_WARN(HILOG_MODULE_APP, "Cannot jump to target AbilitySlice");
106 return;
107 }
108
109 // Scheduler top slice to inactive.
110 if (topAbilitySlice_->GetState() == STATE_ACTIVE) {
111 topAbilitySlice_->OnInactive();
112 }
113
114 // Scheduler target slice to Active.
115 if (target.GetState() == STATE_UNINITIALIZED) {
116 target.Init(abilitySliceManager_);
117 }
118 if (target.GetState() == STATE_INITIAL) {
119 target.OnStart(want);
120 }
121 target.OnActive(want);
122
123 // Scheduler top slice to background.
124 if (topAbilitySlice_->GetState() == STATE_INACTIVE) {
125 topAbilitySlice_->OnBackground();
126 }
127
128 // Update the topAbilitySlice and stack.
129 abilitySliceStack_->Push(topAbilitySlice_);
130 topAbilitySlice_ = ⌖
131 }
132
RemoveAbilitySlice(AbilitySlice & slice)133 void AbilitySliceScheduler::RemoveAbilitySlice(AbilitySlice &slice)
134 {
135 // Check if this slice is legal.
136 if (!CheckLegalForRemove(slice)) {
137 HILOG_WARN(HILOG_MODULE_APP, "Cannot terminate target AbilitySlice");
138 return;
139 }
140
141 if (&slice == topAbilitySlice_) {
142 // Scheduler the slice need to exit to inactive.
143 topAbilitySlice_->OnInactive();
144
145 Want want { nullptr, nullptr, nullptr, 0 };
146 // Scheduler the top slice in the stack to Active.
147 auto next = abilitySliceStack_->Pop();
148 if (next == nullptr) {
149 topAbilitySlice_->OnActive(want);
150 return;
151 }
152 next->OnActive(want);
153
154 // Scheduler the slice need to exit(State:initial).
155 topAbilitySlice_->OnBackground();
156 topAbilitySlice_->OnStop();
157
158 // Update the topAbilitySLice and stack.
159 topAbilitySlice_ = next;
160 } else {
161 // Scheduler the background slice to stop
162 slice.OnStop();
163 abilitySliceStack_->Remove(&slice);
164 }
165 }
166
SetMainRoute(const std::string & entry)167 void AbilitySliceScheduler::SetMainRoute(const std::string &entry)
168 {
169 abilitySliceRoute_->SetMainRoute(entry);
170 }
171
AddActionRoute(const std::string & action,const std::string & entry)172 void AbilitySliceScheduler::AddActionRoute(const std::string &action, const std::string &entry)
173 {
174 abilitySliceRoute_->AddActionRoute(action, entry);
175 }
176
GetTargetAbilitySlice() const177 AbilitySlice *AbilitySliceScheduler::GetTargetAbilitySlice() const
178 {
179 std::string mainEntry = abilitySliceRoute_->GetMainRoute();
180
181 return AbilityLoader::GetInstance().GetAbilitySliceByName(mainEntry);
182 }
183
CheckLegalForAdd(const AbilitySlice & caller,AbilitySlice & target,const Want & want)184 bool AbilitySliceScheduler::CheckLegalForAdd(const AbilitySlice &caller, AbilitySlice &target, const Want &want)
185 {
186 if (topAbilitySlice_ == nullptr) {
187 return false;
188 }
189 if (abilitySliceManager_.GetAbilityState() != STATE_ACTIVE) {
190 return false;
191 }
192 if (caller.GetState() <= STATE_INITIAL) {
193 return false;
194 }
195 if (target.GetState() == STATE_ACTIVE) {
196 return false;
197 }
198 if (&target == topAbilitySlice_) {
199 return false;
200 }
201
202 return true;
203 }
204
CheckLegalForRemove(const AbilitySlice & slice)205 bool AbilitySliceScheduler::CheckLegalForRemove(const AbilitySlice &slice)
206 {
207 if (topAbilitySlice_ == nullptr) {
208 return false;
209 }
210 if (abilitySliceManager_.GetAbilityState() != STATE_ACTIVE) {
211 return false;
212 }
213 if ((!abilitySliceStack_->Exist(&slice)) && (&slice != topAbilitySlice_)) {
214 return false;
215 }
216 if (slice.GetState() <= STATE_INITIAL) {
217 return false;
218 }
219 if (abilitySliceStack_->IsEmpty()) {
220 abilitySliceManager_.TerminateAbility();
221 return false;
222 }
223
224 return true;
225 }
226
GetSliceStackInfo() const227 const std::string AbilitySliceScheduler::GetSliceStackInfo() const
228 {
229 if (topAbilitySlice_ == nullptr) {
230 return " none";
231 }
232 std::string buff;
233 buff += " [" + std::string(typeid(*topAbilitySlice_).name()) +
234 "] State: [" + std::to_string(topAbilitySlice_->GetState()) + "]\n";
235 auto slices = abilitySliceStack_->GetAllSlices();
236 for (auto slice : slices) {
237 buff += " [" + std::string(typeid(*slice).name()) + "] State: [" + std::to_string(slice->GetState()) + "]\n";
238 }
239 return buff;
240 }
241 } // namespace OHOS