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