• 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 <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