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_host_client.h"
17
18 #include <cinttypes>
19
20 #include "fms_log_wrapper.h"
21 #include "form_constants.h"
22 #include "form_caller_mgr.h"
23 #include "hitrace_meter.h"
24
25 namespace OHOS {
26 namespace AppExecFwk {
27 sptr<FormHostClient> FormHostClient::instance_ = nullptr;
28 std::mutex FormHostClient::instanceMutex_;
29
FormHostClient()30 FormHostClient::FormHostClient()
31 {
32 }
33
~FormHostClient()34 FormHostClient::~FormHostClient()
35 {
36 }
37
38 /**
39 * @brief Get FormHostClient instance.
40 *
41 * @return FormHostClient instance.
42 */
GetInstance()43 sptr<FormHostClient> FormHostClient::GetInstance()
44 {
45 if (instance_ == nullptr) {
46 std::lock_guard<std::mutex> lock_l(instanceMutex_);
47 if (instance_ == nullptr) {
48 instance_ = new (std::nothrow) FormHostClient();
49 if (instance_ == nullptr) {
50 HILOG_ERROR("create FormHostClient failed");
51 }
52 }
53 }
54 return instance_;
55 }
56
57 /**
58 * @brief Add form callback.
59 *
60 * @param formCallback the host's form callback.
61 * @param formId The Id of the form.
62 * @return none.
63 */
AddForm(std::shared_ptr<FormCallbackInterface> formCallback,const FormJsInfo & formJsInfo)64 void FormHostClient::AddForm(std::shared_ptr<FormCallbackInterface> formCallback, const FormJsInfo &formJsInfo)
65 {
66 auto formId = formJsInfo.formId;
67 HILOG_INFO("formId:%{public}" PRId64, formId);
68 if (formId <= 0 || formCallback == nullptr) {
69 HILOG_ERROR("invalid formId or formCallback");
70 return;
71 }
72 std::lock_guard<std::mutex> lock(callbackMutex_);
73 auto iter = formCallbackMap_.find(formId);
74 if (iter == formCallbackMap_.end()) {
75 std::set<std::shared_ptr<FormCallbackInterface>> callbacks;
76 callbacks.emplace(formCallback);
77 formCallbackMap_.emplace(formId, callbacks);
78 } else {
79 iter->second.emplace(formCallback);
80 }
81
82 if (formJsInfo.uiSyntax == FormType::ETS) {
83 etsFormIds_.emplace(formId);
84 }
85 }
86
87 /**
88 * @brief Remove form callback.
89 *
90 * @param formCallback the host's form callback.
91 * @param formId The Id of the form.
92 * @return none.
93 */
RemoveForm(std::shared_ptr<FormCallbackInterface> formCallback,const int64_t formId)94 void FormHostClient::RemoveForm(std::shared_ptr<FormCallbackInterface> formCallback, const int64_t formId)
95 {
96 HILOG_INFO("formId:%{public}" PRId64, formId);
97 if (formId <= 0 || formCallback == nullptr) {
98 HILOG_ERROR("invalid formId or formCallback");
99 return;
100 }
101 std::lock_guard<std::mutex> lock(callbackMutex_);
102 auto iter = formCallbackMap_.find(formId);
103 if (iter == formCallbackMap_.end()) {
104 HILOG_ERROR("not find formId:%{public}s", std::to_string(formId).c_str());
105 return;
106 }
107 iter->second.erase(formCallback);
108 if (iter->second.empty()) {
109 HILOG_INFO("All callbacks have been removed");
110 formCallbackMap_.erase(iter);
111 etsFormIds_.erase(formId);
112 }
113 }
114
115 /**
116 * @brief Check whether the form exist in the formhosts.
117 *
118 * @param formId The Id of the form.
119 * @return Returns true if contains form; returns false otherwise.
120 */
ContainsForm(int64_t formId)121 bool FormHostClient::ContainsForm(int64_t formId)
122 {
123 HILOG_INFO("call");
124 std::lock_guard<std::mutex> lock(callbackMutex_);
125 return formCallbackMap_.find(formId) != formCallbackMap_.end();
126 }
127
128 /**
129 * @brief Add form state.
130 *
131 * @param formStateCallback the host's form state callback.
132 * @param want the want of acquiring form state.
133 * @return Returns true if contains form; returns false otherwise.
134 */
AddFormState(const std::shared_ptr<FormStateCallbackInterface> & formStateCallback,const AAFwk::Want & want)135 bool FormHostClient::AddFormState(const std::shared_ptr<FormStateCallbackInterface> &formStateCallback,
136 const AAFwk::Want &want)
137 {
138 HILOG_INFO("call");
139 std::string bundleName = want.GetElement().GetBundleName();
140 std::string abilityName = want.GetElement().GetAbilityName();
141 const std::string doubleColon = "::";
142 std::string key;
143 key.append(bundleName).append(doubleColon).append(abilityName).append(doubleColon)
144 .append(want.GetStringParam(AppExecFwk::Constants::PARAM_MODULE_NAME_KEY)).append(doubleColon)
145 .append(want.GetStringParam(AppExecFwk::Constants::PARAM_FORM_NAME_KEY)).append(doubleColon)
146 .append(std::to_string(want.GetIntParam(AppExecFwk::Constants::PARAM_FORM_DIMENSION_KEY, 1)));
147 std::lock_guard<std::mutex> lock(formStateCallbackMutex_);
148 auto iter = formStateCallbackMap_.find(key);
149 if (iter == formStateCallbackMap_.end()) {
150 std::set<std::shared_ptr<FormStateCallbackInterface>> callbacks;
151 callbacks.emplace(formStateCallback);
152 formStateCallbackMap_.emplace(key, callbacks);
153 } else {
154 iter->second.insert(formStateCallback);
155 }
156 HILOG_INFO("done");
157 return true;
158 }
159
RemoveFormState(const AAFwk::Want & want)160 void FormHostClient::RemoveFormState(const AAFwk::Want &want)
161 {
162 HILOG_INFO("call");
163 std::string bundleName = want.GetElement().GetBundleName();
164 std::string abilityName = want.GetElement().GetAbilityName();
165 const std::string doubleColon = "::";
166 std::string key;
167 key.append(bundleName).append(doubleColon).append(abilityName).append(doubleColon)
168 .append(want.GetStringParam(AppExecFwk::Constants::PARAM_MODULE_NAME_KEY)).append(doubleColon)
169 .append(want.GetStringParam(AppExecFwk::Constants::PARAM_FORM_NAME_KEY)).append(doubleColon)
170 .append(std::to_string(want.GetIntParam(AppExecFwk::Constants::PARAM_FORM_DIMENSION_KEY, 1)));
171 std::lock_guard<std::mutex> lock(formStateCallbackMutex_);
172 auto iter = formStateCallbackMap_.find(key);
173 if (iter != formStateCallbackMap_.end()) {
174 formStateCallbackMap_.erase(key);
175 }
176 HILOG_INFO("end");
177 }
178
RegisterUninstallCallback(UninstallCallback callback)179 bool FormHostClient::RegisterUninstallCallback(UninstallCallback callback)
180 {
181 std::lock_guard<std::mutex> lock(uninstallCallbackMutex_);
182 uninstallCallback_ = callback;
183 return true;
184 }
185
OnAcquired(const FormJsInfo & formJsInfo,const sptr<IRemoteObject> & token)186 void FormHostClient::OnAcquired(const FormJsInfo &formJsInfo, const sptr<IRemoteObject> &token)
187 {
188 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
189 HILOG_DEBUG("call");
190 if (token != nullptr) {
191 HILOG_DEBUG("save token to form remote mgr");
192 FormCallerMgr::GetInstance().AddFormHostCaller(formJsInfo, token);
193 }
194 UpdateForm(formJsInfo);
195 }
196
197 /**
198 * @brief Update form.
199 *
200 * @param formJsInfo Form js info.
201 * @return none.
202 */
OnUpdate(const FormJsInfo & formJsInfo)203 void FormHostClient::OnUpdate(const FormJsInfo &formJsInfo)
204 {
205 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
206 HILOG_DEBUG("call");
207 UpdateForm(formJsInfo);
208 }
209
210 /**
211 * @brief UnInstall the forms.
212 *
213 * @param formIds The Id of the forms.
214 * @return none.
215 */
OnUninstall(const std::vector<int64_t> & formIds)216 void FormHostClient::OnUninstall(const std::vector<int64_t> &formIds)
217 {
218 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
219 HILOG_INFO("call");
220 if (formIds.empty()) {
221 HILOG_ERROR("empty formIds");
222 return;
223 }
224 {
225 std::lock_guard<std::mutex> lock(uninstallCallbackMutex_);
226 if (uninstallCallback_ != nullptr) {
227 uninstallCallback_(formIds);
228 }
229 }
230 for (auto &formId : formIds) {
231 if (formId < 0) {
232 HILOG_ERROR("the passed form id can't be negative");
233 continue;
234 }
235 std::lock_guard<std::mutex> lock(callbackMutex_);
236 auto iter = formCallbackMap_.find(formId);
237 if (iter == formCallbackMap_.end()) {
238 HILOG_ERROR("not find formId:%{public}s", std::to_string(formId).c_str());
239 continue;
240 }
241 for (const auto& callback : iter->second) {
242 HILOG_ERROR("uninstall formId:%{public}s", std::to_string(formId).c_str());
243 callback->ProcessFormUninstall(formId);
244 }
245 }
246 }
247
248 /**
249 * @brief Form provider is acquire state
250 * @param state The form state.
251 * @param want The form want.
252 */
OnAcquireState(FormState state,const AAFwk::Want & want)253 void FormHostClient::OnAcquireState(FormState state, const AAFwk::Want &want)
254 {
255 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
256 HILOG_INFO("state:%{public}d", state);
257 std::string bundleName = want.GetElement().GetBundleName();
258 std::string abilityName = want.GetElement().GetAbilityName();
259 const std::string doubleColon = "::";
260 std::string key;
261 key.append(bundleName).append(doubleColon).append(abilityName).append(doubleColon)
262 .append(want.GetStringParam(AppExecFwk::Constants::PARAM_MODULE_NAME_KEY)).append(doubleColon)
263 .append(want.GetStringParam(AppExecFwk::Constants::PARAM_FORM_NAME_KEY)).append(doubleColon)
264 .append(std::to_string(want.GetIntParam(AppExecFwk::Constants::PARAM_FORM_DIMENSION_KEY, 1)));
265
266 std::lock_guard<std::mutex> lock(formStateCallbackMutex_);
267 auto iter = formStateCallbackMap_.find(key);
268 if (iter == formStateCallbackMap_.end()) {
269 HILOG_INFO("state callback not found");
270 } else {
271 std::set<std::shared_ptr<FormStateCallbackInterface>> &callbackSet = iter->second;
272 for (auto &callback: callbackSet) {
273 callback->ProcessAcquireState(state);
274 }
275 formStateCallbackMap_.erase(iter);
276 }
277 HILOG_INFO("done");
278 }
279
AddShareFormCallback(const std::shared_ptr<ShareFormCallBack> & shareFormCallback,int64_t requestCode)280 bool FormHostClient::AddShareFormCallback(const std::shared_ptr<ShareFormCallBack> &shareFormCallback,
281 int64_t requestCode)
282 {
283 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
284 HILOG_DEBUG("call");
285 std::lock_guard<std::mutex> lock(shareFormCallbackMutex_);
286 auto iter = shareFormCallbackMap_.find(requestCode);
287 if (iter == shareFormCallbackMap_.end()) {
288 shareFormCallbackMap_.emplace(requestCode, shareFormCallback);
289 }
290 HILOG_DEBUG("done");
291 return true;
292 }
293
AddAcqiureFormDataCallback(const std::shared_ptr<FormDataCallbackInterface> & acquireFormDataTask,int64_t requestCode)294 bool FormHostClient::AddAcqiureFormDataCallback(const std::shared_ptr<FormDataCallbackInterface> &acquireFormDataTask,
295 int64_t requestCode)
296 {
297 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
298 HILOG_DEBUG("call");
299 std::lock_guard<std::mutex> lock(AcquireDataCallbackMutex_);
300 auto iter = acquireDataCallbackMap_.find(requestCode);
301 if (iter == acquireDataCallbackMap_.end()) {
302 acquireDataCallbackMap_.emplace(requestCode, acquireFormDataTask);
303 }
304 HILOG_DEBUG("done");
305 return true;
306 }
307
OnAcquireDataResponse(const AAFwk::WantParams & wantParams,int64_t requestCode)308 void FormHostClient::OnAcquireDataResponse(const AAFwk::WantParams &wantParams, int64_t requestCode)
309 {
310 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
311 std::lock_guard<std::mutex> lock(AcquireDataCallbackMutex_);
312 auto iter = acquireDataCallbackMap_.find(requestCode);
313 if (iter == acquireDataCallbackMap_.end()) {
314 HILOG_DEBUG("acquire form data callback not found");
315 return;
316 }
317
318 if (iter->second) {
319 iter->second->ProcessAcquireFormData(wantParams);
320 }
321 acquireDataCallbackMap_.erase(requestCode);
322 HILOG_DEBUG("done");
323 }
324
OnShareFormResponse(int64_t requestCode,int32_t result)325 void FormHostClient::OnShareFormResponse(int64_t requestCode, int32_t result)
326 {
327 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
328 HILOG_DEBUG("result:%{public}d", result);
329 std::lock_guard<std::mutex> lock(shareFormCallbackMutex_);
330 auto iter = shareFormCallbackMap_.find(requestCode);
331 if (iter == shareFormCallbackMap_.end()) {
332 HILOG_DEBUG("invalid shareFormCallback");
333 return;
334 }
335
336 if (iter->second) {
337 iter->second->ProcessShareFormResponse(result);
338 }
339 shareFormCallbackMap_.erase(requestCode);
340 HILOG_DEBUG("done");
341 }
342
OnError(int32_t errorCode,const std::string & errorMsg)343 void FormHostClient::OnError(int32_t errorCode, const std::string &errorMsg)
344 {
345 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
346 HILOG_ERROR("Receive error form FMS, errorCode:%{public}d, errorMsg:%{public}s", errorCode, errorMsg.c_str());
347 std::lock_guard<std::mutex> lock(callbackMutex_);
348 for (auto formIdIter = etsFormIds_.begin(); formIdIter != etsFormIds_.end();) {
349 int64_t formId = *formIdIter;
350 auto callbackMapIter = formCallbackMap_.find(formId);
351 if (callbackMapIter == formCallbackMap_.end()) {
352 HILOG_ERROR("Can't find form:%{public}" PRId64 " remove it", formId);
353 formIdIter = etsFormIds_.erase(formIdIter);
354 continue;
355 }
356 ++formIdIter;
357
358 const std::set<std::shared_ptr<FormCallbackInterface>> &callbackSet = callbackMapIter->second;
359 HILOG_DEBUG("callbackSet.size:%{public}zu", callbackSet.size());
360 for (const auto &callback : callbackSet) {
361 if (callback == nullptr) {
362 HILOG_ERROR("null FormCallback");
363 continue;
364 }
365 callback->OnError(errorCode, errorMsg);
366 }
367 }
368 }
369
OnError(int32_t errorCode,const std::string & errorMsg,std::vector<int64_t> & formIds)370 void FormHostClient::OnError(int32_t errorCode, const std::string &errorMsg, std::vector<int64_t> &formIds)
371 {
372 HILOG_INFO("call");
373 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
374 std::lock_guard<std::mutex> lock(callbackMutex_);
375 for (auto formId : formIds) {
376 if (etsFormIds_.find(formId) == etsFormIds_.end()) {
377 continue;
378 }
379 auto callbackMapIter = formCallbackMap_.find(formId);
380 if (callbackMapIter == formCallbackMap_.end()) {
381 HILOG_ERROR("Can't find form:%{public}" PRId64 " remove it", formId);
382 etsFormIds_.erase(formId);
383 continue;
384 }
385 HILOG_ERROR("Receive error form FMS formId:%{public}s", std::to_string(formId).c_str());
386 const std::set<std::shared_ptr<FormCallbackInterface>> &callbackSet = callbackMapIter->second;
387 HILOG_DEBUG("callbackSet.size:%{public}zu", callbackSet.size());
388 for (const auto &callback : callbackSet) {
389 if (callback == nullptr) {
390 HILOG_ERROR("null FormCallback");
391 continue;
392 }
393 callback->OnError(errorCode, errorMsg);
394 }
395 }
396 }
397
RemoveShareFormCallback(int64_t requestCode)398 void FormHostClient::RemoveShareFormCallback(int64_t requestCode)
399 {
400 HILOG_DEBUG("call");
401 std::lock_guard<std::mutex> lock(shareFormCallbackMutex_);
402 auto iter = shareFormCallbackMap_.find(requestCode);
403 if (iter != shareFormCallbackMap_.end()) {
404 shareFormCallbackMap_.erase(requestCode);
405 }
406 HILOG_INFO("end");
407 }
408
RemoveAcquireDataCallback(int64_t requestCode)409 void FormHostClient::RemoveAcquireDataCallback(int64_t requestCode)
410 {
411 HILOG_DEBUG("call");
412 std::lock_guard<std::mutex> lock(AcquireDataCallbackMutex_);
413 auto iter = acquireDataCallbackMap_.find(requestCode);
414 if (iter != acquireDataCallbackMap_.end()) {
415 acquireDataCallbackMap_.erase(requestCode);
416 }
417 HILOG_INFO("end");
418 }
419
UpdateForm(const FormJsInfo & formJsInfo)420 void FormHostClient::UpdateForm(const FormJsInfo &formJsInfo)
421 {
422 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
423 HILOG_DEBUG("call,image number is %{public}zu", formJsInfo.imageDataMap.size());
424 int64_t formId = formJsInfo.formId;
425 if (formId < 0) {
426 HILOG_ERROR("the passed form id can't be negative");
427 return;
428 }
429 std::lock_guard<std::mutex> lock(callbackMutex_);
430 auto iter = formCallbackMap_.find(formId);
431 if (iter == formCallbackMap_.end()) {
432 HILOG_ERROR("not find formId:%{public}s", std::to_string(formId).c_str());
433 return;
434 }
435 for (const auto &callback : iter->second) {
436 HILOG_DEBUG("formId:%{public}" PRId64 ", jspath:%{public}s, data: %{private}s",
437 formId, formJsInfo.jsFormCodePath.c_str(), formJsInfo.formData.c_str());
438 callback->ProcessFormUpdate(formJsInfo);
439 }
440 }
441
OnRecycleForm(const int64_t & formId)442 void FormHostClient::OnRecycleForm(const int64_t &formId)
443 {
444 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
445 HILOG_DEBUG("formId:%{public}s", std::to_string(formId).c_str());
446
447 if (formId < 0) {
448 HILOG_ERROR("the passed form id can't be negative");
449 return;
450 }
451 std::lock_guard<std::mutex> lock(callbackMutex_);
452 auto iter = formCallbackMap_.find(formId);
453 if (iter == formCallbackMap_.end()) {
454 HILOG_ERROR("can't find formId:%{public}s", std::to_string(formId).c_str());
455 return;
456 }
457 for (const auto &callback : iter->second) {
458 callback->ProcessRecycleForm();
459 }
460 }
461
OnEnableForm(const std::vector<int64_t> & formIds,const bool enable)462 void FormHostClient::OnEnableForm(const std::vector<int64_t> &formIds, const bool enable)
463 {
464 HILOG_INFO("size:%{public}zu", formIds.size());
465 for (auto &formId : formIds) {
466 if (formId < 0) {
467 HILOG_ERROR("the passed form id can't be negative");
468 continue;
469 }
470 std::lock_guard<std::mutex> lock(callbackMutex_);
471 auto iter = formCallbackMap_.find(formId);
472 if (iter == formCallbackMap_.end()) {
473 HILOG_ERROR("not find formId:%{public}s", std::to_string(formId).c_str());
474 continue;
475 }
476 for (const auto& callback : iter->second) {
477 if (!callback) {
478 HILOG_ERROR("null callback");
479 continue;
480 }
481 callback->ProcessEnableForm(enable);
482 }
483 }
484 }
485 } // namespace AppExecFwk
486 } // namespace OHOS
487