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 "datetime_ex.h"
17 #include "sam_log.h"
18 #include "string_ex.h"
19 #include "samgr_err_code.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("Scheduler:context is null");
46 return SA_CONTEXT_NULL;
47 }
48 if (abilityStateHandlerMap_.count(nextState) == 0) {
49 HILOGE("Scheduler:invalid next state:%{public}d", nextState);
50 return INVALID_SA_NEXT_STATE;
51 }
52 std::shared_ptr<SystemAbilityStateHandler> handler = abilityStateHandlerMap_[nextState];
53 if (handler == nullptr) {
54 HILOGE("Scheduler:next state:%{public}d handler is null", nextState);
55 return SA_STATE_HANDLER_NULL;
56 }
57 SystemAbilityState currentState = context->state;
58 if (currentState == nextState) {
59 HILOGI("Scheduler SA:%{public}d state current %{public}d is same as next %{public}d",
60 context->systemAbilityId, currentState, nextState);
61 return ERR_OK;
62 }
63 if (!handler->CanEnter(currentState)) {
64 HILOGE("Scheduler SA:%{public}d can't state %{public}d to %{public}d",
65 context->systemAbilityId, currentState, nextState);
66 return TRANSIT_SA_STATE_FAIL;
67 }
68 if (!UpdateStateCount(context->ownProcessContext, currentState, nextState)) {
69 HILOGE("Scheduler SA:%{public}d update state count fail", context->systemAbilityId);
70 return UPDATE_STATE_COUNT_FAIL;
71 }
72 context->state = nextState;
73 HILOGD("Scheduler SA:%{public}d state %{public}d to %{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("Scheduler:proc context is null");
84 return false;
85 }
86 std::lock_guard<samgr::mutex> autoLock(context->stateCountLock);
87 if (!context->abilityStateCountMap.count(fromState) || !context->abilityStateCountMap.count(toState)) {
88 HILOGE("Scheduler proc:%{public}s invalid state",
89 Str16ToStr8(context->processName).c_str());
90 return false;
91 }
92 if (context->abilityStateCountMap[fromState] <= 0) {
93 HILOGE("Scheduler proc:%{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("Scheduler:proc context is null");
107 return PROC_CONTEXT_NULL;
108 }
109 if (processStateHandlerMap_.count(nextState) == 0) {
110 HILOGE("Scheduler:invalid next state:%{public}d", nextState);
111 return INVALID_PROC_NEXT_STATE;
112 }
113 std::shared_ptr<SystemProcessStateHandler> handler = processStateHandlerMap_[nextState];
114 if (handler == nullptr) {
115 HILOGE("Scheduler:next state:%{public}d handler is null", nextState);
116 return PROC_STATE_HANDLER_NULL;
117 }
118 SystemProcessState currentState = context->state;
119 if (currentState == nextState) {
120 HILOGI("Scheduler proc:%{public}s state current %{public}d is same as next %{public}d",
121 Str16ToStr8(context->processName).c_str(), currentState, nextState);
122 return ERR_OK;
123 }
124 if (!handler->CanEnter(currentState)) {
125 HILOGI("Scheduler proc:%{public}s can't state %{public}d to %{public}d",
126 Str16ToStr8(context->processName).c_str(), currentState, nextState);
127 return TRANSIT_PROC_STATE_FAIL;
128 }
129 context->state = nextState;
130 HILOGI("Scheduler proc:%{public}s state %{public}d to %{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("Scheduler:listener is null");
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("Scheduler:listener is null");
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 context->lastIdleTime = -1;
179 auto listener = listener_.lock();
180 if (listener == nullptr) {
181 HILOGE("Scheduler:listener is null");
182 return;
183 }
184 listener->OnAbilityLoadedLocked(context->systemAbilityId);
185 }
186
CanEnter(SystemAbilityState fromState)187 bool UnloadableStateHandler::CanEnter(SystemAbilityState fromState)
188 {
189 return fromState == SystemAbilityState::LOADED;
190 }
191
OnEnter(const std::shared_ptr<SystemAbilityContext> & context)192 void UnloadableStateHandler::OnEnter(const std::shared_ptr<SystemAbilityContext>& context)
193 {
194 context->lastIdleTime = GetTickCount();
195 auto listener = listener_.lock();
196 if (listener == nullptr) {
197 HILOGE("Scheduler:listener is null");
198 return;
199 }
200 listener->OnAbilityUnloadableLocked(context->systemAbilityId);
201 }
202
CanEnter(SystemAbilityState fromState)203 bool UnloadingStateHandler::CanEnter(SystemAbilityState fromState)
204 {
205 return fromState == SystemAbilityState::UNLOADABLE;
206 }
207
OnEnter(const std::shared_ptr<SystemAbilityContext> & context)208 void UnloadingStateHandler::OnEnter(const std::shared_ptr<SystemAbilityContext>& context)
209 {
210 auto listener = listener_.lock();
211 if (listener == nullptr) {
212 HILOGE("Scheduler:listener is null");
213 return;
214 }
215 listener->OnAbilityUnloadingLocked(context->systemAbilityId);
216 }
217
CanEnter(SystemProcessState fromState)218 bool NotStartedStateHandler::CanEnter(SystemProcessState fromState)
219 {
220 return fromState != SystemProcessState::NOT_STARTED;
221 }
222
OnEnter(const std::shared_ptr<SystemProcessContext> & context)223 void NotStartedStateHandler::OnEnter(const std::shared_ptr<SystemProcessContext>& context)
224 {
225 auto listener = listener_.lock();
226 if (listener == nullptr) {
227 HILOGE("Scheduler:listener is null");
228 return;
229 }
230 context->lastStopTime = GetTickCount(); //进程退出
231 listener->OnProcessNotStartedLocked(context->processName);
232 }
233
CanEnter(SystemProcessState fromState)234 bool StartedStateHandler::CanEnter(SystemProcessState fromState)
235 {
236 return fromState == SystemProcessState::NOT_STARTED;
237 }
238
OnEnter(const std::shared_ptr<SystemProcessContext> & context)239 void StartedStateHandler::OnEnter(const std::shared_ptr<SystemProcessContext>& context)
240 {
241 auto listener = listener_.lock();
242 if (listener == nullptr) {
243 HILOGE("Scheduler:listener is null");
244 return;
245 }
246 listener->OnProcessStartedLocked(context->processName);
247 }
248
CanEnter(SystemProcessState fromState)249 bool StoppingStateHandler::CanEnter(SystemProcessState fromState)
250 {
251 return fromState == SystemProcessState::STARTED;
252 }
253
OnEnter(const std::shared_ptr<SystemProcessContext> & context)254 void StoppingStateHandler::OnEnter(const std::shared_ptr<SystemProcessContext>& context)
255 {
256 auto listener = listener_.lock();
257 if (listener == nullptr) {
258 HILOGE("Scheduler:listener is null");
259 return;
260 }
261 listener->OnProcessStoppingLocked(context->processName);
262 }
263 } // namespace OHOS