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