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