• 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 
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