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_ERROR("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, etsFormIds_ size:%{public}zu",
347 errorCode,
348 errorMsg.c_str(),
349 etsFormIds_.size());
350 std::lock_guard<std::mutex> lock(callbackMutex_);
351 for (auto formIdIter = etsFormIds_.begin(); formIdIter != etsFormIds_.end();) {
352 int64_t formId = *formIdIter;
353 auto callbackMapIter = formCallbackMap_.find(formId);
354 if (callbackMapIter == formCallbackMap_.end()) {
355 HILOG_ERROR("Can't find form:%{public}" PRId64 " remove it", formId);
356 formIdIter = etsFormIds_.erase(formIdIter);
357 continue;
358 }
359 ++formIdIter;
360
361 const std::set<std::shared_ptr<FormCallbackInterface>> &callbackSet = callbackMapIter->second;
362 HILOG_INFO("callbackSet.size:%{public}zu", callbackSet.size());
363 for (const auto &callback : callbackSet) {
364 if (callback == nullptr) {
365 HILOG_ERROR("null FormCallback");
366 continue;
367 }
368 callback->OnError(errorCode, errorMsg);
369 }
370 }
371 }
372
OnError(int32_t errorCode,const std::string & errorMsg,std::vector<int64_t> & formIds)373 void FormHostClient::OnError(int32_t errorCode, const std::string &errorMsg, std::vector<int64_t> &formIds)
374 {
375 HILOG_INFO("call");
376 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
377 std::lock_guard<std::mutex> lock(callbackMutex_);
378 for (auto formId : formIds) {
379 if (etsFormIds_.find(formId) == etsFormIds_.end()) {
380 continue;
381 }
382 auto callbackMapIter = formCallbackMap_.find(formId);
383 if (callbackMapIter == formCallbackMap_.end()) {
384 HILOG_ERROR("Can't find form:%{public}" PRId64 " remove it", formId);
385 etsFormIds_.erase(formId);
386 continue;
387 }
388 HILOG_ERROR("Receive error form FMS formId:%{public}s", std::to_string(formId).c_str());
389 const std::set<std::shared_ptr<FormCallbackInterface>> &callbackSet = callbackMapIter->second;
390 HILOG_DEBUG("callbackSet.size:%{public}zu", callbackSet.size());
391 for (const auto &callback : callbackSet) {
392 if (callback == nullptr) {
393 HILOG_ERROR("null FormCallback");
394 continue;
395 }
396 callback->OnError(errorCode, errorMsg);
397 }
398 }
399 }
400
RemoveShareFormCallback(int64_t requestCode)401 void FormHostClient::RemoveShareFormCallback(int64_t requestCode)
402 {
403 HILOG_DEBUG("call");
404 std::lock_guard<std::mutex> lock(shareFormCallbackMutex_);
405 auto iter = shareFormCallbackMap_.find(requestCode);
406 if (iter != shareFormCallbackMap_.end()) {
407 shareFormCallbackMap_.erase(requestCode);
408 }
409 HILOG_INFO("end");
410 }
411
RemoveAcquireDataCallback(int64_t requestCode)412 void FormHostClient::RemoveAcquireDataCallback(int64_t requestCode)
413 {
414 HILOG_DEBUG("call");
415 std::lock_guard<std::mutex> lock(AcquireDataCallbackMutex_);
416 auto iter = acquireDataCallbackMap_.find(requestCode);
417 if (iter != acquireDataCallbackMap_.end()) {
418 acquireDataCallbackMap_.erase(requestCode);
419 }
420 HILOG_INFO("end");
421 }
422
UpdateForm(const FormJsInfo & formJsInfo)423 void FormHostClient::UpdateForm(const FormJsInfo &formJsInfo)
424 {
425 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
426 HILOG_DEBUG("call,image number is %{public}zu", formJsInfo.imageDataMap.size());
427 int64_t formId = formJsInfo.formId;
428 if (formId < 0) {
429 HILOG_ERROR("the passed form id can't be negative");
430 return;
431 }
432 std::lock_guard<std::mutex> lock(callbackMutex_);
433 auto iter = formCallbackMap_.find(formId);
434 if (iter == formCallbackMap_.end()) {
435 HILOG_ERROR("not find formId:%{public}s", std::to_string(formId).c_str());
436 return;
437 }
438 for (const auto &callback : iter->second) {
439 HILOG_DEBUG("formId:%{public}" PRId64 ", jspath:%{public}s, data: %{private}s",
440 formId, formJsInfo.jsFormCodePath.c_str(), formJsInfo.formData.c_str());
441 callback->ProcessFormUpdate(formJsInfo);
442 }
443 }
444
OnRecycleForm(const int64_t & formId)445 void FormHostClient::OnRecycleForm(const int64_t &formId)
446 {
447 HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
448 HILOG_DEBUG("formId:%{public}s", std::to_string(formId).c_str());
449
450 if (formId < 0) {
451 HILOG_ERROR("the passed form id can't be negative");
452 return;
453 }
454 std::lock_guard<std::mutex> lock(callbackMutex_);
455 auto iter = formCallbackMap_.find(formId);
456 if (iter == formCallbackMap_.end()) {
457 HILOG_ERROR("can't find formId:%{public}s", std::to_string(formId).c_str());
458 return;
459 }
460 for (const auto &callback : iter->second) {
461 callback->ProcessRecycleForm();
462 }
463 }
464
OnEnableForm(const std::vector<int64_t> & formIds,const bool enable)465 void FormHostClient::OnEnableForm(const std::vector<int64_t> &formIds, const bool enable)
466 {
467 HILOG_INFO("size:%{public}zu", formIds.size());
468 for (auto &formId : formIds) {
469 if (formId < 0) {
470 HILOG_ERROR("the passed form id can't be negative");
471 continue;
472 }
473 std::lock_guard<std::mutex> lock(callbackMutex_);
474 auto iter = formCallbackMap_.find(formId);
475 if (iter == formCallbackMap_.end()) {
476 HILOG_ERROR("not find formId:%{public}s", std::to_string(formId).c_str());
477 continue;
478 }
479 for (const auto& callback : iter->second) {
480 if (!callback) {
481 HILOG_ERROR("null callback");
482 continue;
483 }
484 callback->ProcessEnableForm(enable);
485 }
486 }
487 }
488
OnLockForm(const std::vector<int64_t> & formIds,const bool lock)489 void FormHostClient::OnLockForm(const std::vector<int64_t> &formIds, const bool lock)
490 {
491 HILOG_INFO("OnLockForm size:%{public}zu", formIds.size());
492 for (auto &formId : formIds) {
493 if (formId < 0) {
494 HILOG_ERROR("the passed form id can't be negative");
495 continue;
496 }
497 std::lock_guard<std::mutex> lockMutex(callbackMutex_);
498 auto iter = formCallbackMap_.find(formId);
499 if (iter == formCallbackMap_.end()) {
500 HILOG_ERROR("not find formId:%{public}s", std::to_string(formId).c_str());
501 continue;
502 }
503 for (const auto& callback : iter->second) {
504 if (!callback) {
505 HILOG_ERROR("null callback");
506 continue;
507 }
508 callback->ProcessLockForm(lock);
509 }
510 }
511 }
512 } // namespace AppExecFwk
513 } // namespace OHOS
514