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