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