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