1 /*
2 * Copyright (c) 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_task_mgr.h"
17 #include "form_render_interface.h"
18 #include "fms_log_wrapper.h"
19 #include "common/util/form_util.h"
20 #include "common/event/form_event_report.h"
21 #include "status_mgr_center/form_status_queue.h"
22 #include "status_mgr_center/form_status_mgr.h"
23 #include "status_mgr_center/form_status.h"
24 #include "form_mgr/form_mgr_queue.h"
25 #include "data_center/form_record/form_record_report.h"
26 #include "form_provider/form_supply_callback.h"
27 #include "data_center/form_data_mgr.h"
28 #include "data_center/form_cache_mgr.h"
29
30 namespace OHOS {
31 namespace AppExecFwk {
32 namespace {
33 constexpr int64_t WAIT_RELEASE_RENDERER_TIMEOUT = 3000;
34 constexpr int64_t WAIT_RELEASE_RENDERER_MSG = 1;
35 constexpr int64_t RELEASE_RENDER_DELAY_TIME = 20;
36 constexpr int64_t RELEASE_RENDER_DELAY_MSG = 2;
37 }
FormStatusTaskMgr()38 FormStatusTaskMgr::FormStatusTaskMgr()
39 {}
40
~FormStatusTaskMgr()41 FormStatusTaskMgr::~FormStatusTaskMgr()
42 {}
43
44 /**
45 * @brief Post recycle forms.
46 * @param formIds the Ids of forms to be recycled.
47 * @param want The want of the request.
48 * @param remoteObjectOfHost Form host proxy object.
49 * @param remoteObjectOfRender Form render proxy object.
50 */
PostRecycleForms(const std::vector<int64_t> & formIds,const Want & want,const sptr<IRemoteObject> & remoteObjectOfHost,const sptr<IRemoteObject> & remoteObjectOfRender)51 void FormStatusTaskMgr::PostRecycleForms(const std::vector<int64_t> &formIds, const Want &want,
52 const sptr<IRemoteObject> &remoteObjectOfHost, const sptr<IRemoteObject> &remoteObjectOfRender)
53 {
54 HILOG_DEBUG("start");
55
56 for (const int64_t formId : formIds) {
57 auto recycleForm = [formId, remoteObjectOfHost, remoteObjectOfRender]() {
58 FormStatusTaskMgr::GetInstance().RecycleForm(formId, remoteObjectOfHost, remoteObjectOfRender);
59 };
60 FormStatusMgr::GetInstance().PostFormEvent(formId, FormFsmEvent::RECYCLE_DATA, recycleForm);
61 }
62 HILOG_DEBUG("end");
63 }
64
65 /**
66 * @brief Post recover forms.
67 * @param formIds the Ids of forms to be recycled.
68 * @param want The want of the request.
69 * @param remoteObject Form render proxy object.
70 */
PostRecoverForm(const FormRecord & record,const Want & want,const sptr<IRemoteObject> & remoteObject)71 void FormStatusTaskMgr::PostRecoverForm(
72 const FormRecord &record, const Want &want, const sptr<IRemoteObject> &remoteObject)
73 {
74 HILOG_DEBUG("start");
75
76 auto formId = record.formId;
77 auto recoverForm = [record, want, remoteObject]() {
78 FormStatusTaskMgr::GetInstance().RecoverForm(record, want, remoteObject);
79 };
80 FormStatusMgr::GetInstance().PostFormEvent(formId, FormFsmEvent::RECOVER_FORM, recoverForm);
81 HILOG_DEBUG("end");
82 }
83
84 /**
85 * @brief Post release form.
86 * @param formIds The Id of form to be recovered.
87 * @param compId The compId of the forms.
88 * @param uid calling user id.
89 * @param remoteObject Form render proxy object.
90 * @param isDynamic isDynamic flag.
91 */
PostReleaseRenderer(int64_t formId,const std::string & compId,const std::string & uid,const sptr<IRemoteObject> & remoteObject,bool isDynamic)92 void FormStatusTaskMgr::PostReleaseRenderer(int64_t formId, const std::string &compId, const std::string &uid,
93 const sptr<IRemoteObject> &remoteObject, bool isDynamic)
94 {
95 HILOG_DEBUG("start");
96
97 auto deleterenderForm = [formId, compId, uid, remoteObject]() {
98 FormStatusTaskMgr::GetInstance().CancelRecycleTimeout(formId);
99 FormStatusTaskMgr::GetInstance().PostDelayReleaseRenderer(formId, compId, uid, remoteObject);
100 };
101 FormStatusMgr::GetInstance().PostFormEvent(formId, FormFsmEvent::RECYCLE_FORM, deleterenderForm);
102 HILOG_DEBUG("end");
103 }
104
105 /**
106 * @brief Post render form.
107 * @param formRecord The form record.
108 * @param want The want of the request.
109 * @param remoteObject Form render proxy object.
110 */
PostRenderForm(const FormRecord & formRecord,const Want & want,const sptr<IRemoteObject> & remoteObject)111 void FormStatusTaskMgr::PostRenderForm(
112 const FormRecord &formRecord, const Want &want, const sptr<IRemoteObject> &remoteObject)
113 {
114 HILOG_DEBUG("start");
115
116 auto renderForm = [formRecord, want, remoteObject]() {
117 FormStatusTaskMgr::GetInstance().RenderForm(formRecord, want, remoteObject);
118 };
119
120 FormStatusMgr::GetInstance().PostFormEvent(formRecord.formId, FormFsmEvent::RENDER_FORM, renderForm);
121 HILOG_DEBUG("end");
122 }
123
124 /**
125 * @brief Post stop rendering form.
126 * @param formRecord The form record.
127 * @param want The want of the request.
128 * @param remoteObject Form render proxy object.
129 */
PostStopRenderingForm(const FormRecord & formRecord,const Want & want,const sptr<IRemoteObject> & remoteObject)130 void FormStatusTaskMgr::PostStopRenderingForm(
131 const FormRecord &formRecord, const Want &want, const sptr<IRemoteObject> &remoteObject)
132 {
133 HILOG_DEBUG("start");
134
135 auto formId = formRecord.formId;
136 auto deleterenderForm = [formRecord, want, remoteObject]() {
137 FormStatusTaskMgr::GetInstance().StopRenderingForm(formRecord, want, remoteObject);
138 };
139
140 FormStatusMgr::GetInstance().PostFormEvent(formId, FormFsmEvent::DELETE_FORM, deleterenderForm);
141 HILOG_DEBUG("end");
142 }
143
144 /**
145 * @brief Schedules form recycle timeout task
146 * @param formId Form ID
147 * @return bool Returns true if the timeout was successfully scheduled, false otherwise
148 */
ScheduleRecycleTimeout(const int64_t formId)149 bool FormStatusTaskMgr::ScheduleRecycleTimeout(const int64_t formId)
150 {
151 FormStatusQueue::GetInstance().CancelDelayTask(std::make_pair(formId, WAIT_RELEASE_RENDERER_MSG));
152
153 auto timeoutTask = [formId]() {
154 HILOG_ERROR("RecycleForm failed, wait form release timeout, formId:%{public}" PRId64, formId);
155 FormStatus::GetInstance().SetFormStatus(formId, FormFsmStatus::UNPROCESSABLE);
156 FormStatusQueue::GetInstance().CancelDelayTask(std::make_pair(formId, WAIT_RELEASE_RENDERER_MSG));
157 };
158 return FormStatusQueue::GetInstance().ScheduleDelayTask(
159 std::make_pair(formId, WAIT_RELEASE_RENDERER_MSG), WAIT_RELEASE_RENDERER_TIMEOUT, timeoutTask);
160 }
161
162 /**
163 * @brief Cancel form recycle timeout task
164 * @param formId Form ID
165 * @return bool Returns true if the timeout was successfully canceled, false otherwise
166 */
CancelRecycleTimeout(const int64_t formId)167 bool FormStatusTaskMgr::CancelRecycleTimeout(const int64_t formId)
168 {
169 return FormStatusQueue::GetInstance().CancelDelayTask(std::make_pair(formId, WAIT_RELEASE_RENDERER_MSG));
170 }
171
RecycleForm(const int64_t & formId,const sptr<IRemoteObject> & remoteObjectOfHost,const sptr<IRemoteObject> & remoteObjectOfRender)172 void FormStatusTaskMgr::RecycleForm(const int64_t &formId, const sptr<IRemoteObject> &remoteObjectOfHost,
173 const sptr<IRemoteObject> &remoteObjectOfRender)
174 {
175 HILOG_INFO("start formId: %{public}" PRId64, formId);
176
177 sptr<IFormRender> remoteFormRender = iface_cast<IFormRender>(remoteObjectOfRender);
178 if (remoteFormRender == nullptr) {
179 HILOG_ERROR("fail get form render proxy, formId is %{public}" PRId64, formId);
180 return;
181 }
182
183 FormRecord formRecord;
184 if (!FormDataMgr::GetInstance().GetFormRecord(formId, formRecord)) {
185 HILOG_ERROR("form %{public}" PRId64 " not exist", formId);
186 return;
187 }
188
189 Want want;
190 want.SetParam(Constants::FORM_SUPPLY_UID, std::to_string(formRecord.providerUserId) + formRecord.bundleName);
191 want.SetParam(Constants::PARAM_FORM_HOST_TOKEN, remoteObjectOfHost);
192 std::string eventId = FormStatusMgr::GetInstance().GetFormEventId(formId);
193 want.SetParam(Constants::FORM_STATUS_EVENT_ID, eventId);
194 int32_t error = remoteFormRender->RecycleForm(formId, want);
195 if (error != ERR_OK) {
196 HILOG_ERROR("RecycleForm fail formId: %{public}" PRId64 " error: %{public}d", formId, error);
197 FormEventReport::SendFormFailedEvent(FormEventName::RECYCLE_RECOVER_FORM_FAILED,
198 formId,
199 formRecord.bundleName,
200 formRecord.formName,
201 static_cast<int32_t>(RecycleRecoverFormErrorType::RECYCLE_FORM_FAILED),
202 error);
203 }
204 }
205
RecoverForm(const FormRecord & record,const Want & want,const sptr<IRemoteObject> & remoteObject)206 void FormStatusTaskMgr::RecoverForm(const FormRecord &record, const Want &want, const sptr<IRemoteObject> &remoteObject)
207 {
208 HILOG_INFO("start formId: %{public}" PRId64, record.formId);
209
210 auto connectId = want.GetIntParam(Constants::FORM_CONNECT_ID, 0);
211 sptr<IFormRender> remoteFormRender = iface_cast<IFormRender>(remoteObject);
212 if (remoteFormRender == nullptr) {
213 RemoveConnection(connectId);
214 HILOG_ERROR("get formRenderProxy failed");
215 return;
216 }
217
218 FormJsInfo formJsInfo;
219 FormDataMgr::GetInstance().CreateFormJsInfo(record.formId, record, formJsInfo);
220 Want newWant(want);
221 std::string eventId = FormStatusMgr::GetInstance().GetFormEventId(record.formId);
222 newWant.SetParam(Constants::FORM_STATUS_EVENT_ID, eventId);
223
224 int32_t error = remoteFormRender->RecoverForm(formJsInfo, newWant);
225 if (error != ERR_OK) {
226 RemoveConnection(connectId);
227 HILOG_ERROR("fail recover form");
228 FormEventReport::SendFormFailedEvent(FormEventName::RECYCLE_RECOVER_FORM_FAILED,
229 record.formId,
230 record.bundleName,
231 record.formName,
232 static_cast<int64_t>(RecycleRecoverFormErrorType::RECOVER_FORM_FAILED),
233 error);
234 }
235 HILOG_DEBUG("end");
236 }
237
ReleaseRenderer(int64_t formId,const std::string & compId,const std::string & uid,const sptr<IRemoteObject> & remoteObject)238 void FormStatusTaskMgr::ReleaseRenderer(
239 int64_t formId, const std::string &compId, const std::string &uid, const sptr<IRemoteObject> &remoteObject)
240 {
241 HILOG_INFO("begin formId: %{public}" PRId64, formId);
242
243 sptr<IFormRender> remoteFormDeleteRender = iface_cast<IFormRender>(remoteObject);
244 if (remoteFormDeleteRender == nullptr) {
245 HILOG_ERROR("get formRenderProxy failed");
246 return;
247 }
248
249 Want newWant;
250 std::string eventId = FormStatusMgr::GetInstance().GetFormEventId(formId);
251 newWant.SetParam(Constants::FORM_STATUS_EVENT_ID, eventId);
252
253 int32_t error = remoteFormDeleteRender->ReleaseRenderer(formId, compId, uid, newWant);
254 if (error != ERR_OK) {
255 HILOG_ERROR("fail release form renderer");
256 }
257 HILOG_INFO("end formId: %{public}" PRId64, formId);
258 }
259
PostDelayReleaseRenderer(int64_t formId,const std::string & compId,const std::string & uid,const sptr<IRemoteObject> & remoteObject)260 bool FormStatusTaskMgr::PostDelayReleaseRenderer(
261 int64_t formId, const std::string &compId, const std::string &uid, const sptr<IRemoteObject> &remoteObject)
262 {
263 FormStatusQueue::GetInstance().CancelDelayTask(std::make_pair(formId, RELEASE_RENDER_DELAY_MSG));
264
265 auto recycleForm = [formId, compId, uid, remoteObject]() {
266 FormStatusTaskMgr::GetInstance().ReleaseRenderer(formId, compId, uid, remoteObject);
267 FormStatusQueue::GetInstance().CancelDelayTask(std::make_pair(formId, RELEASE_RENDER_DELAY_MSG));
268 };
269 return FormStatusQueue::GetInstance().ScheduleDelayTask(
270 std::make_pair(formId, RELEASE_RENDER_DELAY_MSG), RELEASE_RENDER_DELAY_TIME, recycleForm);
271 }
272
StopRenderingForm(const FormRecord & formRecord,const Want & want,const sptr<IRemoteObject> & remoteObject)273 void FormStatusTaskMgr::StopRenderingForm(
274 const FormRecord &formRecord, const Want &want, const sptr<IRemoteObject> &remoteObject)
275 {
276 HILOG_INFO("begin formId: %{public}" PRId64, formRecord.formId);
277
278 auto connectId = want.GetIntParam(Constants::FORM_CONNECT_ID, 0);
279 sptr<IFormRender> remoteFormDeleteRender = iface_cast<IFormRender>(remoteObject);
280 if (remoteFormDeleteRender == nullptr) {
281 RemoveConnection(connectId);
282 HILOG_ERROR("get formRenderProxy failed");
283 return;
284 }
285
286 FormJsInfo formInfo;
287 FormDataMgr::GetInstance().CreateFormJsInfo(formRecord.formId, formRecord, formInfo);
288 Want newWant(want);
289 std::string eventId = FormStatusMgr::GetInstance().GetFormEventId(formRecord.formId);
290 newWant.SetParam(Constants::FORM_STATUS_EVENT_ID, eventId);
291
292 int32_t error = remoteFormDeleteRender->StopRenderingForm(formInfo, newWant, FormSupplyCallback::GetInstance());
293 if (error != ERR_OK) {
294 RemoveConnection(connectId);
295 HILOG_ERROR("fail add form renderer");
296 }
297 HILOG_INFO("end");
298 }
299
RenderForm(const FormRecord & formRecord,const Want & want,const sptr<IRemoteObject> & remoteObject)300 void FormStatusTaskMgr::RenderForm(
301 const FormRecord &formRecord, const Want &want, const sptr<IRemoteObject> &remoteObject)
302 {
303 HILOG_INFO("render form formId: %{public}" PRId64 ",%{public}zu", formRecord.formId,
304 formRecord.formProviderInfo.GetFormDataString().length());
305
306 auto connectId = want.GetIntParam(Constants::FORM_CONNECT_ID, 0);
307 sptr<IFormRender> remoteFormRender = iface_cast<IFormRender>(remoteObject);
308 if (remoteFormRender == nullptr) {
309 RemoveConnection(connectId);
310 HILOG_ERROR("get formRenderProxy failed");
311 return;
312 }
313
314 FormJsInfo formInfo;
315 FormDataMgr::GetInstance().CreateFormJsInfo(formRecord.formId, formRecord, formInfo);
316 Want newWant(want);
317 std::string eventId = FormStatusMgr::GetInstance().GetFormEventId(formRecord.formId);
318 newWant.SetParam(Constants::FORM_STATUS_EVENT_ID, eventId);
319
320 int32_t error = remoteFormRender->RenderForm(formInfo, newWant, FormSupplyCallback::GetInstance());
321 FormRecordReport::GetInstance().IncreaseUpdateTimes(formRecord.formId, HiSysEventPointType::TYPE_DAILY_REFRESH);
322 if (!formRecord.isVisible) {
323 FormRecordReport::GetInstance().IncreaseUpdateTimes(
324 formRecord.formId, HiSysEventPointType::TYPE_INVISIBLE_UPDATE);
325 }
326 if (error != ERR_OK) {
327 RemoveConnection(connectId);
328 HILOG_ERROR("fail add form renderer");
329 }
330
331 HILOG_DEBUG("end");
332 }
333
RemoveConnection(int32_t connectId)334 void FormStatusTaskMgr::RemoveConnection(int32_t connectId)
335 {
336 auto formSupplyCallback = FormSupplyCallback::GetInstance();
337 if (formSupplyCallback == nullptr) {
338 HILOG_ERROR("formSupplyCallback is nullptr.");
339 return;
340 }
341 formSupplyCallback->RemoveConnection(connectId);
342 }
343 } // namespace AppExecFwk
344 } // namespace OHOS