1 /*
2 * Copyright (c) 2021-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 "form_provider/form_supply_callback.h"
17
18 #include <cinttypes>
19
20 #include "fms_log_wrapper.h"
21 #include "ams_mgr/form_ams_helper.h"
22 #include "form_constants.h"
23 #include "data_center/form_data_proxy_mgr.h"
24 #include "form_mgr_errors.h"
25 #include "form_provider/form_provider_mgr.h"
26 #include "form_provider/form_provider_task_mgr.h"
27 #include "form_render/form_render_mgr.h"
28 #include "feature/form_share/form_share_mgr.h"
29 #include "common/util/form_util.h"
30 #include "hitrace_meter.h"
31 #include "data_center/form_info/form_info_rdb_storage_mgr.h"
32 #include "data_center/form_data_mgr.h"
33 #include "form_host_interface.h"
34 #include "common/util/form_report.h"
35 #include "data_center/form_record/form_record_report.h"
36 #include "form_mgr/form_mgr_adapter.h"
37 #include "status_mgr_center/form_status_mgr.h"
38 #include "status_mgr_center/form_event_retry_mgr.h"
39 #include "status_mgr_center/form_status_task_mgr.h"
40 #include "common/util/form_task_common.h"
41
42 namespace OHOS {
43 namespace AppExecFwk {
44 sptr<FormSupplyCallback> FormSupplyCallback::instance_ = nullptr;
45 std::mutex FormSupplyCallback::mutex_;
46 const std::string EMPTY_STATUS_DATA = "empty_status_data";
47
GetInstance()48 sptr<FormSupplyCallback> FormSupplyCallback::GetInstance()
49 {
50 if (instance_ == nullptr) {
51 std::lock_guard<std::mutex> lock(mutex_);
52 if (instance_ == nullptr) {
53 instance_ = new (std::nothrow) FormSupplyCallback();
54 if (instance_ == nullptr) {
55 HILOG_ERROR("create FormSupplyCallback failed");
56 }
57 }
58 }
59 return instance_;
60 }
61
ProcessFormAcquisition(int64_t formId)62 void FormSupplyCallback::ProcessFormAcquisition(int64_t formId)
63 {
64 FormRecord record;
65 bool hasRecord = FormDataMgr::GetInstance().GetFormRecord(formId, record);
66 if (hasRecord) {
67 int64_t endTime;
68 FormReport::GetInstance().GetEndAquireTime(formId, endTime);
69 if (!endTime) {
70 FormReport::GetInstance().SetEndAquireTime(formId, FormUtil::GetCurrentSteadyClockMillseconds());
71 FormReport::GetInstance().HandleAddFormStatistic(formId);
72 }
73 }
74 }
75 /**
76 * @brief Accept form binding data from form provider.
77 * @param providerFormInfo Form binding data.
78 * @param want input data.
79 * @return Returns ERR_OK on success, others on failure.
80 */
OnAcquire(const FormProviderInfo & formProviderInfo,const Want & want)81 int FormSupplyCallback::OnAcquire(const FormProviderInfo &formProviderInfo, const Want &want)
82 {
83 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
84 HILOG_INFO("call");
85 auto connectId = want.GetIntParam(Constants::FORM_CONNECT_ID, 0);
86 int errCode = want.GetIntParam(Constants::PROVIDER_FLAG, ERR_OK);
87 if (errCode != ERR_OK) {
88 RemoveConnection(connectId);
89 HILOG_ERROR("errCode:%{public}d", errCode);
90 return errCode;
91 }
92
93 std::string strFormId = want.GetStringParam(Constants::PARAM_FORM_IDENTITY_KEY);
94 if (strFormId.empty()) {
95 HILOG_ERROR("empty formId");
96 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
97 }
98 int64_t formId = std::stoll(strFormId);
99 FormReport::GetInstance().SetAddFormFinish(formId);
100 FormReport::GetInstance().SetStartAquireTime(formId, FormUtil::GetCurrentSteadyClockMillseconds());
101 FormRecordReport::GetInstance().SetFormRecordRecordInfo(formId, want);
102 FormReport::GetInstance().SetFormRecordInfo(formId, want);
103 ProcessFormAcquisition(formId);
104 if (IsRemoveConnection(formId, want.GetRemoteObject(Constants::PARAM_FORM_HOST_TOKEN))) {
105 RemoveConnection(connectId);
106 }
107
108 if (FormRenderMgr::GetInstance().IsNeedRender(formId)) {
109 errCode = FormRenderMgr::GetInstance().UpdateRenderingForm(formId, formProviderInfo.GetFormData(),
110 want.GetParams(), false);
111 FormDataProxyMgr::GetInstance().SubscribeFormData(formId, formProviderInfo.GetFormProxies(), want);
112 return errCode;
113 }
114
115 int32_t ret = ERR_APPEXECFWK_FORM_INVALID_PARAM;
116 int type = want.GetIntParam(Constants::ACQUIRE_TYPE, 0);
117 HILOG_DEBUG("%{public}" PRId64 ",%{public}d,%{public}d",
118 formId, connectId, type);
119 switch (type) {
120 case Constants::ACQUIRE_TYPE_CREATE_FORM:
121 ret = FormProviderMgr::GetInstance().AcquireForm(formId, formProviderInfo);
122 break;
123 case Constants::ACQUIRE_TYPE_RECREATE_FORM:
124 ret = FormProviderMgr::GetInstance().UpdateForm(formId, formProviderInfo);
125 break;
126 default:
127 HILOG_WARN("onAcquired type:%{public}d", type);
128 }
129
130 FormDataProxyMgr::GetInstance().SubscribeFormData(formId, formProviderInfo.GetFormProxies(), want);
131 HILOG_INFO("end");
132 return ret;
133 }
134
135 /**
136 * @brief Accept other event.
137 * @param want input data.
138 * @return Returns ERR_OK on success, others on failure.
139 */
OnEventHandle(const Want & want)140 int FormSupplyCallback::OnEventHandle(const Want &want)
141 {
142 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
143 HILOG_INFO("call");
144 auto connectId = want.GetIntParam(Constants::FORM_CONNECT_ID, 0);
145 std::string supplyInfo = want.GetStringParam(Constants::FORM_SUPPLY_INFO);
146 HILOG_DEBUG("%{public}d,%{public}s", connectId, supplyInfo.c_str());
147 RemoveConnection(connectId);
148 HILOG_INFO("end");
149 return ERR_OK;
150 }
151
152 /**
153 * @brief Accept form state from form provider.
154 * @param state Form state.
155 * @param provider provider info.
156 * @param wantArg The want of onAcquireFormState.
157 * @param want input data.
158 * @return Returns ERR_OK on success, others on failure.
159 */
OnAcquireStateResult(FormState state,const std::string & provider,const Want & wantArg,const Want & want)160 int FormSupplyCallback::OnAcquireStateResult(FormState state,
161 const std::string &provider, const Want &wantArg, const Want &want)
162 {
163 HILOG_INFO("call");
164 auto connectId = want.GetIntParam(Constants::FORM_CONNECT_ID, 0);
165 RemoveConnection(connectId);
166
167 ErrCode errCode = FormProviderMgr::GetInstance().AcquireFormStateBack(state, provider, wantArg);
168 HILOG_INFO("errCode:%{public}d", errCode);
169 return errCode;
170 }
171
OnAcquireDataResult(const AAFwk::WantParams & wantParams,int64_t requestCode)172 int FormSupplyCallback::OnAcquireDataResult(const AAFwk::WantParams &wantParams, int64_t requestCode)
173 {
174 HILOG_DEBUG("call");
175 ErrCode errCode = FormProviderMgr::GetInstance().AcquireFormDataBack(wantParams, requestCode);
176 HILOG_INFO("errCode:%{public}d", errCode);
177 return errCode;
178 }
179
180 /**
181 * @brief Save ability Connection for the callback.
182 * @param connection ability connection.
183 */
AddConnection(sptr<FormAbilityConnection> connection)184 void FormSupplyCallback::AddConnection(sptr<FormAbilityConnection> connection)
185 {
186 HILOG_DEBUG("call");
187 if (connection == nullptr) {
188 return;
189 }
190 int32_t connectKey = static_cast<int32_t>(FormUtil::GetCurrentSteadyClockMillseconds());
191 std::lock_guard<std::mutex> lock(conMutex_);
192 while (connections_.find(connectKey) != connections_.end()) {
193 connectKey++;
194 }
195 connection->SetConnectId(connectKey);
196 connections_.emplace(connectKey, connection);
197 HILOG_DEBUG("end");
198 }
199
200 /**
201 * @brief Delete ability connection after the callback come.
202 * @param connectId The ability connection id generated when save.
203 */
RemoveConnection(int32_t connectId)204 void FormSupplyCallback::RemoveConnection(int32_t connectId)
205 {
206 HILOG_DEBUG("call");
207 sptr<FormAbilityConnection> connection = nullptr;
208 {
209 std::lock_guard<std::mutex> lock(conMutex_);
210 auto conIterator = connections_.find(connectId);
211 if (conIterator != connections_.end()) {
212 connection = conIterator->second;
213 connections_.erase(connectId);
214 }
215 }
216
217 if (connection != nullptr) {
218 if (CanDisconnect(connection)) {
219 FormAmsHelper::GetInstance().DisconnectServiceAbility(connection);
220 HILOG_INFO("disconnect service ability");
221 } else {
222 FormAmsHelper::GetInstance().DisconnectServiceAbilityDelay(connection);
223 HILOG_INFO("disconnect service ability delay");
224 }
225 }
226 HILOG_DEBUG("end");
227 }
228 /**
229 * @brief check if disconnect ability or not.
230 * @param connection The ability connection.
231 */
CanDisconnect(sptr<FormAbilityConnection> & connection)232 bool FormSupplyCallback::CanDisconnect(sptr<FormAbilityConnection> &connection)
233 {
234 if (connection == nullptr) {
235 HILOG_ERROR("null connection");
236 return false;
237 }
238 HILOG_INFO("call");
239 int count = 0;
240 std::lock_guard<std::mutex> lock(conMutex_);
241 for (auto &conn : connections_) {
242 if (connection->GetProviderKey() == conn.second->GetProviderKey()) {
243 HILOG_INFO("key:%{public}s", conn.second->GetProviderKey().c_str());
244 count++;
245 if (count >= 1) {
246 HILOG_INFO("true count:%{public}d", count);
247 return true;
248 }
249 }
250 }
251 HILOG_INFO("false count:%{public}d", count);
252 return false;
253 }
254
OnShareAcquire(int64_t formId,const std::string & remoteDeviceId,const AAFwk::WantParams & wantParams,int64_t requestCode,const bool & result)255 void FormSupplyCallback::OnShareAcquire(int64_t formId, const std::string &remoteDeviceId,
256 const AAFwk::WantParams &wantParams, int64_t requestCode, const bool &result)
257 {
258 HILOG_DEBUG("formId %{public}" PRId64 " call", formId);
259 DelayedSingleton<FormShareMgr>::GetInstance()->HandleProviderShareData(
260 formId, remoteDeviceId, wantParams, requestCode, result);
261 }
262
IsRemoveConnection(int64_t formId,const sptr<IRemoteObject> & hostToken)263 bool FormSupplyCallback::IsRemoveConnection(int64_t formId, const sptr<IRemoteObject> &hostToken)
264 {
265 HILOG_DEBUG("formId is %{public}" PRId64, formId);
266 if (hostToken == nullptr) {
267 return true;
268 }
269
270 std::lock_guard<std::mutex> lock(conMutex_);
271 // keep one connection for each in application form in the same host
272 int32_t count = 0;
273 for (const auto &conn : connections_) {
274 if (hostToken == conn.second->GetHostToken() && formId == conn.second->GetFormId()) {
275 count++;
276 if (count > 1) {
277 break;
278 }
279 }
280 }
281 HILOG_DEBUG("count is %{public}d", count);
282 if (count == 1) {
283 HILOG_DEBUG("keep the connection");
284 return false;
285 }
286 return true;
287 }
288
RemoveConnection(int64_t formId,const sptr<IRemoteObject> & hostToken)289 void FormSupplyCallback::RemoveConnection(int64_t formId, const sptr<IRemoteObject> &hostToken)
290 {
291 HILOG_DEBUG("formId is %{public}" PRId64, formId);
292 if (hostToken == nullptr) {
293 return;
294 }
295
296 std::lock_guard<std::mutex> lock(conMutex_);
297 for (const auto &conn : connections_) {
298 if (hostToken == conn.second->GetHostToken() && formId == conn.second->GetFormId()) {
299 Want want;
300 want.SetParam(Constants::FORM_CONNECT_ID, conn.first);
301 want.SetParam(Constants::PARAM_FORM_HOST_TOKEN, hostToken);
302 FormProviderTaskMgr::GetInstance().PostDeleteTask(formId, want, conn.second->GetProviderToken());
303 HILOG_DEBUG("remove the connection, connect id is %{public}d", conn.first);
304 }
305 }
306 }
307
HandleHostDied(const sptr<IRemoteObject> & hostToken)308 void FormSupplyCallback::HandleHostDied(const sptr<IRemoteObject> &hostToken)
309 {
310 HILOG_DEBUG("call");
311 if (hostToken == nullptr) {
312 HILOG_ERROR("null hostToken");
313 return;
314 }
315
316 std::vector<int32_t> connectIds;
317 {
318 std::lock_guard<std::mutex> lock(conMutex_);
319 for (const auto &conn : connections_) {
320 if (hostToken == conn.second->GetHostToken()) {
321 connectIds.push_back(conn.first);
322 HILOG_DEBUG("remove the connection, connect id is %{public}d", conn.first);
323 }
324 }
325 }
326
327 for (const auto &connectId : connectIds) {
328 RemoveConnection(connectId);
329 }
330 }
331
OnRenderTaskDone(int64_t formId,const Want & want)332 int32_t FormSupplyCallback::OnRenderTaskDone(int64_t formId, const Want &want)
333 {
334 HILOG_DEBUG("call");
335 FormRenderMgr::GetInstance().RenderFormCallback(formId, want);
336 return ERR_OK;
337 }
338
OnStopRenderingTaskDone(int64_t formId,const Want & want)339 int32_t FormSupplyCallback::OnStopRenderingTaskDone(int64_t formId, const Want &want)
340 {
341 HILOG_INFO("call");
342 FormRenderMgr::GetInstance().StopRenderingFormCallback(formId, want);
343 return ERR_OK;
344 }
345
OnRenderingBlock(const std::string & bundleName)346 int32_t FormSupplyCallback::OnRenderingBlock(const std::string &bundleName)
347 {
348 HILOG_INFO("bundleName:%{public}s", bundleName.c_str());
349 FormRenderMgr::GetInstance().OnRenderingBlock(bundleName);
350 return ERR_OK;
351 }
352
OnRecycleForm(const int64_t formId,const Want & want)353 int32_t FormSupplyCallback::OnRecycleForm(const int64_t formId, const Want &want)
354 {
355 std::string statusData = want.GetStringParam(Constants::FORM_STATUS_DATA);
356 if (statusData.empty()) {
357 HILOG_WARN("status data of %{public}" PRId64 " is empty", formId);
358 statusData = EMPTY_STATUS_DATA;
359 }
360 if (FormInfoRdbStorageMgr::GetInstance().UpdateStatusData(std::to_string(formId), statusData) != ERR_OK) {
361 HILOG_ERROR("update status data of %{public}" PRId64 " failed", formId);
362 return ERR_APPEXECFWK_FORM_COMMON_CODE;
363 }
364
365 std::string eventId = want.GetStringParam(Constants::FORM_STATUS_EVENT_ID);
366 std::string curTid = FormStatusMgr::GetInstance().GetFormEventId(formId);
367 int32_t event =
368 want.GetIntParam(Constants::FORM_STATUS_EVENT, static_cast<int32_t>(FormFsmEvent::RECYCLE_DATA_FAIL));
369 HILOG_INFO("formId:%{public}" PRId64 ", eventId:%{public}s, curTid:%{public}s, event:%{public}d.",
370 formId,
371 eventId.c_str(),
372 curTid.c_str(),
373 event);
374 if (event != static_cast<int32_t>(FormFsmEvent::RECYCLE_DATA_FAIL)) {
375 FormEventRetryMgr::GetInstance().DeleteRetryCount(formId);
376 }
377 if (!eventId.empty() && eventId == curTid) {
378 FormStatusMgr::GetInstance().CancelFormEventTimeout(formId, eventId);
379
380 auto reCycleForm = [formId, want]() {
381 sptr<IRemoteObject> remoteObjectOfHost = want.GetRemoteObject(Constants::PARAM_FORM_HOST_TOKEN);
382 if (remoteObjectOfHost == nullptr) {
383 HILOG_ERROR("null remoteObjectOfHost");
384 return;
385 }
386 sptr<IFormHost> remoteFormHost = iface_cast<IFormHost>(remoteObjectOfHost);
387 if (remoteFormHost == nullptr) {
388 HILOG_ERROR("null remoteFormHost");
389 return;
390 }
391 remoteFormHost->OnRecycleForm(formId);
392 FormStatusTaskMgr::GetInstance().ScheduleRecycleTimeout(formId);
393 };
394 FormStatusMgr::GetInstance().PostFormEvent(formId, (FormFsmEvent)event, reCycleForm);
395 }
396 return ERR_OK;
397 }
398
OnRecoverFormsByConfigUpdate(std::vector<int64_t> & formIds)399 int32_t FormSupplyCallback::OnRecoverFormsByConfigUpdate(std::vector<int64_t> &formIds)
400 {
401 HILOG_INFO("recover forms by config update");
402 Want want;
403 return FormMgrAdapter::GetInstance().RecoverForms(formIds, want);
404 }
405
OnNotifyRefreshForm(const int64_t formId)406 int32_t FormSupplyCallback::OnNotifyRefreshForm(const int64_t formId)
407 {
408 FormMgrAdapter::GetInstance().OnNotifyRefreshForm(formId);
409 return ERR_OK;
410 }
411
OnRenderFormDone(const int64_t formId,const Want & want)412 int32_t FormSupplyCallback::OnRenderFormDone(const int64_t formId, const Want &want)
413 {
414 std::string eventId = want.GetStringParam(Constants::FORM_STATUS_EVENT_ID);
415 std::string curTid = FormStatusMgr::GetInstance().GetFormEventId(formId);
416 int32_t event =
417 want.GetIntParam(Constants::FORM_STATUS_EVENT, static_cast<int32_t>(FormFsmEvent::RENDER_FORM_FAIL));
418 HILOG_INFO("formId:%{public}" PRId64 ", eventId:%{public}s, curTid:%{public}s, event:%{public}d.",
419 formId,
420 eventId.c_str(),
421 curTid.c_str(),
422 event);
423 if (event != static_cast<int32_t>(FormFsmEvent::RENDER_FORM_FAIL)) {
424 FormEventRetryMgr::GetInstance().DeleteRetryCount(formId);
425 }
426 if (!eventId.empty() && eventId == curTid) {
427 FormStatusMgr::GetInstance().CancelFormEventTimeout(formId, eventId);
428 FormStatusMgr::GetInstance().PostFormEvent(formId, (FormFsmEvent)event);
429 }
430 return ERR_OK;
431 }
432
OnRecoverFormDone(const int64_t formId,const Want & want)433 int32_t FormSupplyCallback::OnRecoverFormDone(const int64_t formId, const Want &want)
434 {
435 std::string eventId = want.GetStringParam(Constants::FORM_STATUS_EVENT_ID);
436 std::string curTid = FormStatusMgr::GetInstance().GetFormEventId(formId);
437 int32_t event =
438 want.GetIntParam(Constants::FORM_STATUS_EVENT, static_cast<int32_t>(FormFsmEvent::RECOVER_FORM_FAIL));
439 HILOG_INFO("formId:%{public}" PRId64 ", eventId:%{public}s, curTid:%{public}s, event:%{public}d.",
440 formId,
441 eventId.c_str(),
442 curTid.c_str(),
443 event);
444 if (event != static_cast<int32_t>(FormFsmEvent::RECOVER_FORM_FAIL)) {
445 FormEventRetryMgr::GetInstance().DeleteRetryCount(formId);
446 }
447 if (!eventId.empty() && eventId == curTid) {
448 FormStatusMgr::GetInstance().CancelFormEventTimeout(formId, eventId);
449 FormStatusMgr::GetInstance().PostFormEvent(formId, (FormFsmEvent)event);
450 }
451 return ERR_OK;
452 }
453
OnRecycleFormDone(const int64_t formId,const Want & want)454 int32_t FormSupplyCallback::OnRecycleFormDone(const int64_t formId, const Want &want)
455 {
456 std::string eventId = want.GetStringParam(Constants::FORM_STATUS_EVENT_ID);
457 std::string curTid = FormStatusMgr::GetInstance().GetFormEventId(formId);
458 int32_t event =
459 want.GetIntParam(Constants::FORM_STATUS_EVENT, static_cast<int32_t>(FormFsmEvent::RECYCLE_FORM_FAIL));
460 HILOG_INFO("formId:%{public}" PRId64 ", eventId:%{public}s, curTid:%{public}s, event:%{public}d.",
461 formId,
462 eventId.c_str(),
463 curTid.c_str(),
464 event);
465 if (event != static_cast<int32_t>(FormFsmEvent::RECYCLE_FORM_FAIL)) {
466 FormEventRetryMgr::GetInstance().DeleteRetryCount(formId);
467 }
468 if (!eventId.empty() && eventId == curTid) {
469 FormStatusMgr::GetInstance().CancelFormEventTimeout(formId, eventId);
470 FormStatusMgr::GetInstance().PostFormEvent(formId, (FormFsmEvent)event);
471 }
472 return ERR_OK;
473 }
474
OnDeleteFormDone(const int64_t formId,const Want & want)475 int32_t FormSupplyCallback::OnDeleteFormDone(const int64_t formId, const Want &want)
476 {
477 std::string eventId = want.GetStringParam(Constants::FORM_STATUS_EVENT_ID);
478 std::string curTid = FormStatusMgr::GetInstance().GetFormEventId(formId);
479 int32_t event =
480 want.GetIntParam(Constants::FORM_STATUS_EVENT, static_cast<int32_t>(FormFsmEvent::DELETE_FORM_FAIL));
481 HILOG_INFO("formId:%{public}" PRId64 ", eventId:%{public}s, curTid:%{public}s, event:%{public}d.",
482 formId,
483 eventId.c_str(),
484 curTid.c_str(),
485 event);
486 if (event != static_cast<int32_t>(FormFsmEvent::DELETE_FORM_FAIL)) {
487 FormEventRetryMgr::GetInstance().DeleteRetryCount(formId);
488 }
489 if (!eventId.empty() && eventId == curTid) {
490 FormStatusMgr::GetInstance().CancelFormEventTimeout(formId, eventId);
491 FormStatusMgr::GetInstance().PostFormEvent(formId, (FormFsmEvent)event);
492 }
493 return ERR_OK;
494 }
495 } // namespace AppExecFwk
496 } // namespace OHOS
497