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