• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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