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