1 /*
2 * Copyright (c) 2023-2025 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 "status_mgr_center/form_status_mgr.h"
17 #include "status_mgr_center/form_status_queue.h"
18 #include "status_mgr_center/form_status.h"
19 #include "status_mgr_center/form_event_timeout_queue.h"
20 #include "status_mgr_center/form_event_retry_mgr.h"
21 #include "data_center/form_data_mgr.h"
22 #include "common/timer_mgr/form_timer_mgr.h"
23 #include "fms_log_wrapper.h"
24 #include "form_status_print.h"
25
26 namespace OHOS {
27 namespace AppExecFwk {
FormStatusMgr()28 FormStatusMgr::FormStatusMgr()
29 {
30 HILOG_DEBUG("create FormStatusMgr");
31 }
32
~FormStatusMgr()33 FormStatusMgr::~FormStatusMgr()
34 {
35 HILOG_DEBUG("destroy FormStatusMgr");
36 }
37
PostFormEvent(const int64_t formId,const FormFsmEvent event,std::function<void ()> func)38 void FormStatusMgr::PostFormEvent(const int64_t formId, const FormFsmEvent event, std::function<void()> func)
39 {
40 auto task = [formId, event, func]() {
41 FormStatusMgr::GetInstance().ExecStatusMachineTask(formId, event, func);
42 };
43
44 FormStatusQueue::GetInstance().ScheduleTask(0, task);
45 }
46
CancelFormEventTimeout(const int64_t formId,std::string eventId)47 void FormStatusMgr::CancelFormEventTimeout(const int64_t formId, std::string eventId)
48 {
49 FormEventTimeoutQueue::GetInstance().CancelDelayTask(std::make_pair(formId, eventId));
50 }
51
ExecFormTaskTimeout(const int64_t formId,FormEventTimeout timeoutMs,FormFsmEvent event,FormFsmStatus status)52 void FormStatusMgr::ExecFormTaskTimeout(
53 const int64_t formId, FormEventTimeout timeoutMs, FormFsmEvent event, FormFsmStatus status)
54 {
55 if (timeoutMs == FormEventTimeout::TIMEOUT_NO_NEED) {
56 HILOG_DEBUG("no need exec timeout task, formId:%{public}" PRId64, formId);
57 return;
58 }
59
60 SetFormEventId(formId);
61 std::string eventId = GetFormEventId(formId);
62 if (eventId.empty()) {
63 HILOG_ERROR("get eventId failed, formId:%{public}" PRId64, formId);
64 return;
65 }
66
67 auto timeoutTask = [formId, event, status, eventId]() {
68 HILOG_ERROR("excute timeout, event:%{public}s, status:%{public}s, formId:%{public}" PRId64,
69 FormStatusPrint::FormEventToString(event).c_str(),
70 FormStatusPrint::FormStatusToString(status).c_str(),
71 formId);
72 FormStatusMgr::GetInstance().ExecStatusMachineTask(formId, FormFsmEvent::EXECUTION_TIMEOUT);
73 FormEventTimeoutQueue::GetInstance().CancelDelayTask(std::make_pair(formId, eventId));
74 };
75 FormEventTimeoutQueue::GetInstance().ScheduleDelayTask(
76 std::make_pair(formId, eventId), static_cast<uint32_t>(timeoutMs), timeoutTask);
77 }
78
ExecStatusMachineTask(const int64_t formId,const FormFsmEvent event,std::function<void ()> func)79 bool FormStatusMgr::ExecStatusMachineTask(const int64_t formId, const FormFsmEvent event, std::function<void()> func)
80 {
81 // get status machine info
82 if (!FormStatus::GetInstance().HasFormStatus(formId)) {
83 HILOG_INFO("create new status.");
84 FormStatus::GetInstance().SetFormStatus(formId, FormFsmStatus::INIT);
85 }
86 FormFsmStatus status = FormStatus::GetInstance().GetFormStatus(formId);
87
88 FormStatusMachineInfo info;
89 if (!FormStatusTable::GetInstance().GetFormStatusInfo(status, event, info)) {
90 HILOG_ERROR("get form status info failed, formId:%{public}" PRId64, formId);
91 return false;
92 }
93
94 HILOG_INFO("state transition, formId:%{public}" PRId64
95 ", status is %{public}s, event is %{public}s, nextStatus is %{public}s, processType is %{public}d.",
96 formId,
97 FormStatusPrint::FormStatusToString(status).c_str(),
98 FormStatusPrint::FormEventToString(event).c_str(),
99 FormStatusPrint::FormStatusToString(info.nextStatus).c_str(),
100 static_cast<int32_t>(info.processType));
101
102 // state machine switches to the next state.
103 FormStatus::GetInstance().SetFormStatus(formId, info.nextStatus);
104
105 // state machine timeout process
106 FormStatusMgr::GetInstance().ExecFormTaskTimeout(formId, info.timeoutMs, event, status);
107
108 // state machine excute
109 FormStatusMgr::GetInstance().ExecFormTask(info.processType, formId, event, func);
110 return true;
111 }
112
ExecFormTask(FormFsmProcessType processType,const int64_t formId,const FormFsmEvent event,std::function<void ()> func)113 void FormStatusMgr::ExecFormTask(
114 FormFsmProcessType processType, const int64_t formId, const FormFsmEvent event, std::function<void()> func)
115 {
116 switch (processType) {
117 case FormFsmProcessType::PROCESS_TASK_DIRECT:
118 ProcessTaskDirect(formId, event, func);
119 break;
120 case FormFsmProcessType::ADD_TASK_TO_QUEUE_UNIQUE:
121 AddTaskToQueueUnique(formId, event, func);
122 break;
123 case FormFsmProcessType::ADD_TASK_TO_QUEUE_PUSH:
124 AddTaskToQueuePush(formId, event, func);
125 break;
126 case FormFsmProcessType::ADD_TASK_TO_QUEUE_DELETE:
127 AddTaskToQueueDelete(formId, event, func);
128 break;
129 case FormFsmProcessType::PROCESS_TASK_FROM_QUEUE:
130 ProcessTaskFromQueue(formId);
131 break;
132 case FormFsmProcessType::PROCESS_TASK_DELETE:
133 ProcessTaskDelete(formId);
134 break;
135 case FormFsmProcessType::PROCESS_TASK_RETRY:
136 ProcessTaskFromRetry(formId);
137 break;
138 default:
139 break;
140 }
141 }
142
ProcessTaskDirect(const int64_t formId,const FormFsmEvent event,std::function<void ()> func)143 void FormStatusMgr::ProcessTaskDirect(const int64_t formId, const FormFsmEvent event, std::function<void()> func)
144 {
145 if (func == nullptr) {
146 HILOG_ERROR("func is nullptr");
147 return;
148 }
149
150 FormEventTaskInfo taskInfo{formId, event, func};
151 FormEventRetryMgr::GetInstance().SetLastFormEvent(formId, taskInfo);
152
153 func();
154 }
155
AddTaskToQueueUnique(const int64_t formId,const FormFsmEvent event,std::function<void ()> func)156 void FormStatusMgr::AddTaskToQueueUnique(const int64_t formId, const FormFsmEvent event, std::function<void()> func)
157 {
158 std::shared_ptr<FormEventQueue> formEventQueue = GetFormEventQueue(formId);
159
160 FormEventTaskInfo taskInfo{formId, event, func};
161 formEventQueue->PushFormEvent(taskInfo);
162
163 std::queue<FormEventTaskInfo> temptaskInfoQueue;
164 while (!formEventQueue->IsEventQueueEmpty()) {
165 FormEventTaskInfo eventTaskInfo{};
166 if (!formEventQueue->PopFormEvent(eventTaskInfo)) {
167 HILOG_INFO("formEventQueue is empty.");
168 break;
169 }
170 if (eventTaskInfo.getFormEvent() == FormFsmEvent::RENDER_FORM ||
171 eventTaskInfo.getFormEvent() == FormFsmEvent::DELETE_FORM) {
172 temptaskInfoQueue.push(eventTaskInfo);
173 }
174 }
175
176 while (!temptaskInfoQueue.empty()) {
177 FormEventTaskInfo eventTaskInfo = temptaskInfoQueue.front();
178 temptaskInfoQueue.pop();
179 formEventQueue->PushFormEvent(eventTaskInfo);
180 }
181 HILOG_INFO("formEventQueue event size %{public}d.", static_cast<int32_t>(formEventQueue->GetEventQueue().size()));
182
183 FormDataMgr::GetInstance().UpdateFormRecordSetIsExistRecycleTask(formId, false);
184 }
185
AddTaskToQueuePush(const int64_t formId,const FormFsmEvent event,std::function<void ()> func)186 void FormStatusMgr::AddTaskToQueuePush(const int64_t formId, const FormFsmEvent event, std::function<void()> func)
187 {
188 std::shared_ptr<FormEventQueue> formEventQueue = GetFormEventQueue(formId);
189 FormEventTaskInfo taskInfo{formId, event, func};
190 formEventQueue->PushFormEvent(taskInfo);
191
192 if (event == FormFsmEvent::RECYCLE_DATA || event == FormFsmEvent::RECYCLE_FORM) {
193 FormDataMgr::GetInstance().UpdateFormRecordSetIsExistRecycleTask(formId, true);
194 }
195 }
196
AddTaskToQueueDelete(const int64_t formId,const FormFsmEvent event,std::function<void ()> func)197 void FormStatusMgr::AddTaskToQueueDelete(const int64_t formId, const FormFsmEvent event, std::function<void()> func)
198 {
199 FormDataMgr::GetInstance().UpdateFormRecordSetIsExistRecycleTask(formId, false);
200
201 std::shared_ptr<FormEventQueue> formEventQueue = GetFormEventQueue(formId);
202 FormEventTaskInfo taskInfo{formId, event, func};
203 if (formEventQueue->IsEventQueueEmpty()) {
204 formEventQueue->PushFormEvent(taskInfo);
205 return;
206 }
207
208 while (!formEventQueue->IsEventQueueEmpty()) {
209 FormEventTaskInfo eventTaskInfo{};
210 if (!formEventQueue->PopFormEvent(eventTaskInfo)) {
211 HILOG_INFO("formEventQueue is empty.");
212 break;
213 }
214 }
215 formEventQueue->PushFormEvent(taskInfo);
216 HILOG_INFO("formEventQueue event size %{public}d.", static_cast<int32_t>(formEventQueue->GetEventQueue().size()));
217 }
218
ProcessTaskFromQueue(const int64_t formId)219 void FormStatusMgr::ProcessTaskFromQueue(const int64_t formId)
220 {
221 if (!HasFormEventQueue(formId)) {
222 HILOG_INFO("formEventQueue is empty, not process.");
223 return;
224 }
225 std::shared_ptr<FormEventQueue> formEventQueue = GetFormEventQueue(formId);
226
227 FormEventTaskInfo eventTaskInfo{};
228 if (!formEventQueue->PopFormEvent(eventTaskInfo)) {
229 HILOG_INFO("formEventQueue is empty, not process.");
230 return;
231 }
232
233 auto func = eventTaskInfo.getFunc();
234 auto event = eventTaskInfo.getFormEvent();
235 if (event == FormFsmEvent::RECYCLE_FORM) {
236 FormDataMgr::GetInstance().UpdateFormRecordSetIsExistRecycleTask(formId, false);
237 }
238
239 FormStatusMgr::GetInstance().ExecStatusMachineTask(formId, event, func);
240 }
241
ProcessTaskDelete(const int64_t formId)242 void FormStatusMgr::ProcessTaskDelete(const int64_t formId)
243 {
244 DeleteFormEventQueue(formId);
245 DeleteFormEventId(formId);
246 FormStatus::GetInstance().DeleteFormStatus(formId);
247 FormEventRetryMgr::GetInstance().DeleteLastFormEvent(formId);
248 FormEventRetryMgr::GetInstance().DeleteRetryCount(formId);
249 }
250
ProcessTaskFromRetry(const int64_t formId)251 void FormStatusMgr::ProcessTaskFromRetry(const int64_t formId)
252 {
253 int32_t retryCount = FORM_EVENT_RETRY_MAX;
254 bool ret = FormEventRetryMgr::GetInstance().GetRetryCount(formId, retryCount);
255 if (ret && retryCount == FORM_EVENT_RETRY_MAX) {
256 HILOG_INFO("retry reached count.");
257 FormEventRetryMgr::GetInstance().DeleteRetryCount(formId);
258 ProcessTaskFromQueue(formId);
259 return;
260 }
261 HILOG_INFO("set retry count 1.");
262 FormEventRetryMgr::GetInstance().SetRetryCount(formId, 1);
263
264 FormEventTaskInfo formEventInfo;
265 ret = FormEventRetryMgr::GetInstance().GetLastFormEvent(formId, formEventInfo);
266 if (!ret) {
267 HILOG_ERROR("GetLastFormEvent failed.");
268 return;
269 }
270
271 auto func = formEventInfo.getFunc();
272 auto event = formEventInfo.getFormEvent();
273 FormStatusMgr::GetInstance().ExecStatusMachineTask(formId, event, func);
274 }
275
HasFormEventQueue(const int64_t formId)276 bool FormStatusMgr::HasFormEventQueue(const int64_t formId)
277 {
278 std::shared_lock<std::shared_mutex> lock(formEventQueueMutex_);
279 return !(formEventQueueMap_.find(formId) == formEventQueueMap_.end());
280 }
281
GetFormEventQueue(const int64_t formId)282 const std::shared_ptr<FormEventQueue> FormStatusMgr::GetFormEventQueue(const int64_t formId)
283 {
284 std::unique_lock<std::shared_mutex> lock(formEventQueueMutex_);
285 if (formEventQueueMap_.find(formId) == formEventQueueMap_.end()) {
286 std::shared_ptr<FormEventQueue> formEventQueue = std::make_shared<FormEventQueue>(formId);
287 formEventQueueMap_.emplace(formId, formEventQueue);
288 HILOG_INFO("formEventQueueMap_ insert, formId:%{public}" PRId64 ". ", formId);
289 }
290
291 return formEventQueueMap_[formId];
292 }
293
DeleteFormEventQueue(const int64_t formId)294 void FormStatusMgr::DeleteFormEventQueue(const int64_t formId)
295 {
296 std::unique_lock<std::shared_mutex> lock(formEventQueueMutex_);
297 auto iter = formEventQueueMap_.find(formId);
298 if (iter != formEventQueueMap_.end()) {
299 HILOG_INFO("formId:%{public}" PRId64 ". ", formId);
300 formEventQueueMap_.erase(iter);
301 }
302 }
303
GetFormEventId(const int64_t formId)304 std::string FormStatusMgr::GetFormEventId(const int64_t formId)
305 {
306 std::shared_lock<std::shared_mutex> lock(formEventIdMapMutex_);
307 if (formEventIdMap_.find(formId) == formEventIdMap_.end()) {
308 HILOG_ERROR("eventId is not existed, formId:%{public}" PRId64 ".", formId);
309 return "";
310 }
311
312 HILOG_INFO("formId:%{public}" PRId64 ", eventId:%{public}s.", formId, (formEventIdMap_[formId]).c_str());
313 return formEventIdMap_[formId];
314 }
315
SetFormEventId(const int64_t formId)316 void FormStatusMgr::SetFormEventId(const int64_t formId)
317 {
318 int64_t eventId = FormUtil::GetCurrentNanosecond();
319 std::string tidString = std::to_string(eventId);
320 HILOG_INFO("formId:%{public}" PRId64 ", eventId:%{public}s.", formId, tidString.c_str());
321 std::unique_lock<std::shared_mutex> lock(formEventIdMapMutex_);
322 if (formEventIdMap_.find(formId) == formEventIdMap_.end()) {
323 formEventIdMap_.emplace(formId, std::to_string(eventId));
324 return;
325 }
326 formEventIdMap_[formId] = tidString;
327 }
328
DeleteFormEventId(const int64_t formId)329 void FormStatusMgr::DeleteFormEventId(const int64_t formId)
330 {
331 std::unique_lock<std::shared_mutex> lock(formEventIdMapMutex_);
332 auto iter = formEventIdMap_.find(formId);
333 if (iter != formEventIdMap_.end()) {
334 HILOG_INFO("formId:%{public}" PRId64 ". ", formId);
335 formEventIdMap_.erase(iter);
336 }
337 }
338 } // namespace AppExecFwk
339 } // namespace OHOS
340