1 /*
2 * Copyright (c) 2023 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 <shared_mutex>
17
18 #include "sam_log.h"
19 #include "string_ex.h"
20 #include "schedule/system_ability_state_machine.h"
21
22 namespace OHOS {
SystemAbilityStateMachine(const std::shared_ptr<SystemAbilityStateListener> & listener)23 SystemAbilityStateMachine::SystemAbilityStateMachine(const std::shared_ptr<SystemAbilityStateListener>& listener)
24 {
25 InitStateHandlerMap(listener);
26 }
27
InitStateHandlerMap(const std::shared_ptr<SystemAbilityStateListener> & listener)28 void SystemAbilityStateMachine::InitStateHandlerMap(const std::shared_ptr<SystemAbilityStateListener>& listener)
29 {
30 abilityStateHandlerMap_[SystemAbilityState::NOT_LOADED] = std::make_shared<NotLoadedStateHandler>(listener);
31 abilityStateHandlerMap_[SystemAbilityState::LOADING] = std::make_shared<LoadingStateHandler>(listener);
32 abilityStateHandlerMap_[SystemAbilityState::LOADED] = std::make_shared<LoadedStateHandler>(listener);
33 abilityStateHandlerMap_[SystemAbilityState::UNLOADABLE] = std::make_shared<UnloadableStateHandler>(listener);
34 abilityStateHandlerMap_[SystemAbilityState::UNLOADING] = std::make_shared<UnloadingStateHandler>(listener);
35
36 processStateHandlerMap_[SystemProcessState::NOT_STARTED] = std::make_shared<NotStartedStateHandler>(listener);
37 processStateHandlerMap_[SystemProcessState::STARTED] = std::make_shared<StartedStateHandler>(listener);
38 processStateHandlerMap_[SystemProcessState::STOPPING] = std::make_shared<StoppingStateHandler>(listener);
39 }
40
AbilityStateTransitionLocked(const std::shared_ptr<SystemAbilityContext> & context,const SystemAbilityState nextState)41 int32_t SystemAbilityStateMachine::AbilityStateTransitionLocked(const std::shared_ptr<SystemAbilityContext>& context,
42 const SystemAbilityState nextState)
43 {
44 if (context == nullptr) {
45 HILOGE("[SA Scheduler] context is nullptr");
46 return ERR_INVALID_VALUE;
47 }
48 if (abilityStateHandlerMap_.count(nextState) == 0) {
49 HILOGE("[SA Scheduler] invalid next state: %{public}d", nextState);
50 return ERR_INVALID_VALUE;
51 }
52 std::shared_ptr<SystemAbilityStateHandler> handler = abilityStateHandlerMap_[nextState];
53 if (handler == nullptr) {
54 HILOGE("[SA Scheduler] next state: %{public}d handler is nullptr", nextState);
55 return ERR_INVALID_VALUE;
56 }
57 SystemAbilityState currentState = context->state;
58 if (currentState == nextState) {
59 HILOGI("[SA Scheduler][SA: %{public}d] current state %{public}d is same as next state %{public}d",
60 context->systemAbilityId, currentState, nextState);
61 return ERR_OK;
62 }
63 if (!handler->CanEnter(currentState)) {
64 HILOGE("[SA Scheduler][SA: %{public}d] cannot transiton from state %{public}d to state %{public}d",
65 context->systemAbilityId, currentState, nextState);
66 return ERR_INVALID_VALUE;
67 }
68 if (!UpdateStateCount(context->ownProcessContext, currentState, nextState)) {
69 HILOGE("[SA Scheduler][SA: %{public}d] update state count failed", context->systemAbilityId);
70 return ERR_INVALID_VALUE;
71 }
72 context->state = nextState;
73 HILOGD("[SA Scheduler][SA: %{public}d] transiton from state %{public}d to state %{public}d",
74 context->systemAbilityId, currentState, nextState);
75 handler->OnEnter(context);
76 return ERR_OK;
77 }
78
UpdateStateCount(const std::shared_ptr<SystemProcessContext> & context,SystemAbilityState fromState,SystemAbilityState toState)79 bool SystemAbilityStateMachine::UpdateStateCount(const std::shared_ptr<SystemProcessContext>& context,
80 SystemAbilityState fromState, SystemAbilityState toState)
81 {
82 if (context == nullptr) {
83 HILOGE("[SA Scheduler] process context is nullptr");
84 return false;
85 }
86 std::unique_lock<std::shared_mutex> uniqueLock(context->stateCountLock);
87 if (!context->abilityStateCountMap.count(fromState) || !context->abilityStateCountMap.count(toState)) {
88 HILOGE("[SA Scheduler][process: %{public}s] invalid state",
89 Str16ToStr8(context->processName).c_str());
90 return false;
91 }
92 if (context->abilityStateCountMap[fromState] <= 0) {
93 HILOGE("[SA Scheduler][process: %{public}s] invalid current state count",
94 Str16ToStr8(context->processName).c_str());
95 return false;
96 }
97 context->abilityStateCountMap[fromState]--;
98 context->abilityStateCountMap[toState]++;
99 return true;
100 }
101
ProcessStateTransitionLocked(const std::shared_ptr<SystemProcessContext> & context,SystemProcessState nextState)102 int32_t SystemAbilityStateMachine::ProcessStateTransitionLocked(const std::shared_ptr<SystemProcessContext>& context,
103 SystemProcessState nextState)
104 {
105 if (context == nullptr) {
106 HILOGE("[SA Scheduler] process context is nullptr");
107 return ERR_INVALID_VALUE;
108 }
109 if (processStateHandlerMap_.count(nextState) == 0) {
110 HILOGE("[SA Scheduler] invalid next state: %{public}d", nextState);
111 return ERR_INVALID_VALUE;
112 }
113 std::shared_ptr<SystemProcessStateHandler> handler = processStateHandlerMap_[nextState];
114 if (handler == nullptr) {
115 HILOGE("[SA Scheduler] next state: %{public}d handler is nullptr", nextState);
116 return ERR_INVALID_VALUE;
117 }
118 SystemProcessState currentState = context->state;
119 if (currentState == nextState) {
120 HILOGI("[SA Scheduler][process: %{public}s] current state %{public}d is same as next state %{public}d",
121 Str16ToStr8(context->processName).c_str(), currentState, nextState);
122 return ERR_OK;
123 }
124 if (!handler->CanEnter(currentState)) {
125 HILOGI("[SA Scheduler][process: %{public}s] cannot transiton from state %{public}d to state %{public}d",
126 Str16ToStr8(context->processName).c_str(), currentState, nextState);
127 return ERR_INVALID_VALUE;
128 }
129 context->state = nextState;
130 HILOGI("[SA Scheduler][process: %{public}s] transiton from state %{public}d to state %{public}d",
131 Str16ToStr8(context->processName).c_str(), currentState, nextState);
132 handler->OnEnter(context);
133 return ERR_OK;
134 }
135
CanEnter(SystemAbilityState fromState)136 bool NotLoadedStateHandler::CanEnter(SystemAbilityState fromState)
137 {
138 return fromState != SystemAbilityState::NOT_LOADED;
139 }
140
OnEnter(const std::shared_ptr<SystemAbilityContext> & context)141 void NotLoadedStateHandler::OnEnter(const std::shared_ptr<SystemAbilityContext>& context)
142 {
143 auto listener = listener_.lock();
144 if (listener == nullptr) {
145 HILOGE("[SA Scheduler] listener is nullptr");
146 return;
147 }
148 listener->OnAbilityNotLoadedLocked(context->systemAbilityId);
149 }
150
CanEnter(SystemAbilityState fromState)151 bool LoadingStateHandler::CanEnter(SystemAbilityState fromState)
152 {
153 return fromState == SystemAbilityState::NOT_LOADED;
154 }
155
OnEnter(const std::shared_ptr<SystemAbilityContext> & context)156 void LoadingStateHandler::OnEnter(const std::shared_ptr<SystemAbilityContext>& context)
157 {
158 auto listener = listener_.lock();
159 if (listener == nullptr) {
160 HILOGE("[SA Scheduler] listener is nullptr");
161 return;
162 }
163 listener->OnAbilityLoadingLocked(context->systemAbilityId);
164 }
165
CanEnter(SystemAbilityState fromState)166 bool LoadedStateHandler::CanEnter(SystemAbilityState fromState)
167 {
168 if (fromState == SystemAbilityState::NOT_LOADED
169 || fromState == SystemAbilityState::LOADING
170 || fromState == SystemAbilityState::UNLOADABLE) {
171 return true;
172 }
173 return false;
174 }
175
OnEnter(const std::shared_ptr<SystemAbilityContext> & context)176 void LoadedStateHandler::OnEnter(const std::shared_ptr<SystemAbilityContext>& context)
177 {
178 auto listener = listener_.lock();
179 if (listener == nullptr) {
180 HILOGE("[SA Scheduler] listener is nullptr");
181 return;
182 }
183 listener->OnAbilityLoadedLocked(context->systemAbilityId);
184 }
185
CanEnter(SystemAbilityState fromState)186 bool UnloadableStateHandler::CanEnter(SystemAbilityState fromState)
187 {
188 return fromState == SystemAbilityState::LOADED;
189 }
190
OnEnter(const std::shared_ptr<SystemAbilityContext> & context)191 void UnloadableStateHandler::OnEnter(const std::shared_ptr<SystemAbilityContext>& context)
192 {
193 auto listener = listener_.lock();
194 if (listener == nullptr) {
195 HILOGE("[SA Scheduler] listener is nullptr");
196 return;
197 }
198 listener->OnAbilityUnloadableLocked(context->systemAbilityId);
199 }
200
CanEnter(SystemAbilityState fromState)201 bool UnloadingStateHandler::CanEnter(SystemAbilityState fromState)
202 {
203 return fromState == SystemAbilityState::UNLOADABLE;
204 }
205
OnEnter(const std::shared_ptr<SystemAbilityContext> & context)206 void UnloadingStateHandler::OnEnter(const std::shared_ptr<SystemAbilityContext>& context)
207 {
208 auto listener = listener_.lock();
209 if (listener == nullptr) {
210 HILOGE("[SA Scheduler] listener is nullptr");
211 return;
212 }
213 listener->OnAbilityUnloadingLocked(context->systemAbilityId);
214 }
215
CanEnter(SystemProcessState fromState)216 bool NotStartedStateHandler::CanEnter(SystemProcessState fromState)
217 {
218 return fromState != SystemProcessState::NOT_STARTED;
219 }
220
OnEnter(const std::shared_ptr<SystemProcessContext> & context)221 void NotStartedStateHandler::OnEnter(const std::shared_ptr<SystemProcessContext>& context)
222 {
223 auto listener = listener_.lock();
224 if (listener == nullptr) {
225 HILOGE("[SA Scheduler] listener is nullptr");
226 return;
227 }
228 listener->OnProcessNotStartedLocked(context->processName);
229 }
230
CanEnter(SystemProcessState fromState)231 bool StartedStateHandler::CanEnter(SystemProcessState fromState)
232 {
233 return fromState == SystemProcessState::NOT_STARTED;
234 }
235
OnEnter(const std::shared_ptr<SystemProcessContext> & context)236 void StartedStateHandler::OnEnter(const std::shared_ptr<SystemProcessContext>& context)
237 {
238 auto listener = listener_.lock();
239 if (listener == nullptr) {
240 HILOGE("[SA Scheduler] listener is nullptr");
241 return;
242 }
243 listener->OnProcessStartedLocked(context->processName);
244 }
245
CanEnter(SystemProcessState fromState)246 bool StoppingStateHandler::CanEnter(SystemProcessState fromState)
247 {
248 return fromState == SystemProcessState::STARTED;
249 }
250
OnEnter(const std::shared_ptr<SystemProcessContext> & context)251 void StoppingStateHandler::OnEnter(const std::shared_ptr<SystemProcessContext>& context)
252 {
253 auto listener = listener_.lock();
254 if (listener == nullptr) {
255 HILOGE("[SA Scheduler] listener is nullptr");
256 return;
257 }
258 listener->OnProcessStoppingLocked(context->processName);
259 }
260 } // namespace OHOS