• 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_host_client.h"
17 
18 #include <cinttypes>
19 
20 #include "hilog_wrapper.h"
21 #include "hitrace_meter.h"
22 #include "form_constants.h"
23 #include "form_caller_mgr.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("%{public}s error, failed to create FormHostClient.", __func__);
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("%{public}s called, formId: %{public}" PRId64 ".", __func__, formId);
68     if (formId <= 0 || formCallback == nullptr) {
69         HILOG_ERROR("%{public}s error, invalid formId or formCallback.", __func__);
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("%{public}s called, formId: %{public}" PRId64 ".", __func__, formId);
97     if (formId <= 0 || formCallback == nullptr) {
98         HILOG_ERROR("%{public}s, invalid formId or formCallback.", __func__);
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("%{public}s, not find formId:%{public}s.", __func__, 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, remove formId");
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("%{public}s called.", __func__);
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("%{public}s called.", __func__);
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("%{public}s done.", __func__);
157     return true;
158 }
159 
RemoveFormState(const AAFwk::Want & want)160 void FormHostClient::RemoveFormState(const AAFwk::Want &want)
161 {
162     HILOG_INFO("%{public}s called.", __func__);
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("%{public}s end.", __func__);
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     HILOG_DEBUG("%{public}s called.",  __func__);
189     if (token != nullptr) {
190         HILOG_DEBUG("save token to form remote mgr.");
191         FormCallerMgr::GetInstance().AddFormHostCaller(formJsInfo, token);
192     }
193     UpdateForm(formJsInfo);
194 }
195 
196 /**
197  * @brief Update form.
198  *
199  * @param formJsInfo Form js info.
200  * @return none.
201  */
OnUpdate(const FormJsInfo & formJsInfo)202 void FormHostClient::OnUpdate(const FormJsInfo &formJsInfo)
203 {
204     HILOG_DEBUG("%{public}s called.",  __func__);
205     UpdateForm(formJsInfo);
206 }
207 
208 /**
209  * @brief UnInstall the forms.
210  *
211  * @param formIds The Id of the forms.
212  * @return none.
213  */
OnUninstall(const std::vector<int64_t> & formIds)214 void FormHostClient::OnUninstall(const std::vector<int64_t> &formIds)
215 {
216     HILOG_INFO("%{public}s called.", __func__);
217     if (formIds.empty()) {
218         HILOG_ERROR("%{public}s error, formIds is empty.", __func__);
219         return;
220     }
221     {
222         std::lock_guard<std::mutex> lock(uninstallCallbackMutex_);
223         if (uninstallCallback_ != nullptr) {
224             uninstallCallback_(formIds);
225         }
226     }
227     for (auto &formId : formIds) {
228         if (formId < 0) {
229             HILOG_ERROR("%{public}s error, the passed form id can't be negative.", __func__);
230             continue;
231         }
232         std::lock_guard<std::mutex> lock(callbackMutex_);
233         auto iter = formCallbackMap_.find(formId);
234         if (iter == formCallbackMap_.end()) {
235             HILOG_ERROR("%{public}s error, not find formId:%{public}s.", __func__, std::to_string(formId).c_str());
236             continue;
237         }
238         for (const auto& callback : iter->second) {
239             HILOG_ERROR("%{public}s uninstall formId:%{public}s.", __func__, std::to_string(formId).c_str());
240             callback->ProcessFormUninstall(formId);
241         }
242     }
243 }
244 
245 /**
246  * @brief Form provider is acquire state
247  * @param state The form state.
248  * @param want The form want.
249  */
OnAcquireState(FormState state,const AAFwk::Want & want)250 void FormHostClient::OnAcquireState(FormState state, const AAFwk::Want &want)
251 {
252     HILOG_INFO("%{public}s state:%{public}d.", __func__, state);
253     std::string bundleName = want.GetElement().GetBundleName();
254     std::string abilityName = want.GetElement().GetAbilityName();
255     const std::string doubleColon = "::";
256     std::string key;
257     key.append(bundleName).append(doubleColon).append(abilityName).append(doubleColon)
258         .append(want.GetStringParam(AppExecFwk::Constants::PARAM_MODULE_NAME_KEY)).append(doubleColon)
259         .append(want.GetStringParam(AppExecFwk::Constants::PARAM_FORM_NAME_KEY)).append(doubleColon)
260         .append(std::to_string(want.GetIntParam(AppExecFwk::Constants::PARAM_FORM_DIMENSION_KEY, 1)));
261 
262     std::lock_guard<std::mutex> lock(formStateCallbackMutex_);
263     auto iter = formStateCallbackMap_.find(key);
264     if (iter == formStateCallbackMap_.end()) {
265         HILOG_INFO("form state callback not found");
266     } else {
267         std::set<std::shared_ptr<FormStateCallbackInterface>> &callbackSet = iter->second;
268         for (auto &callback: callbackSet) {
269             callback->ProcessAcquireState(state);
270         }
271         formStateCallbackMap_.erase(iter);
272     }
273     HILOG_INFO("%{public}s done", __func__);
274 }
275 
AddShareFormCallback(const std::shared_ptr<ShareFormCallBack> & shareFormCallback,int64_t requestCode)276 bool FormHostClient::AddShareFormCallback(const std::shared_ptr<ShareFormCallBack> &shareFormCallback,
277     int64_t requestCode)
278 {
279     HILOG_DEBUG("%{public}s called.", __func__);
280     std::lock_guard<std::mutex> lock(shareFormCallbackMutex_);
281     auto iter = shareFormCallbackMap_.find(requestCode);
282     if (iter == shareFormCallbackMap_.end()) {
283         shareFormCallbackMap_.emplace(requestCode, shareFormCallback);
284     }
285     HILOG_DEBUG("%{public}s done.", __func__);
286     return true;
287 }
288 
OnShareFormResponse(int64_t requestCode,int32_t result)289 void FormHostClient::OnShareFormResponse(int64_t requestCode, int32_t result)
290 {
291     HILOG_DEBUG("%{public}s result:%{public}d.", __func__, result);
292     std::lock_guard<std::mutex> lock(shareFormCallbackMutex_);
293     auto iter = shareFormCallbackMap_.find(requestCode);
294     if (iter == shareFormCallbackMap_.end()) {
295         HILOG_DEBUG("share form callback not found");
296         return;
297     }
298 
299     if (iter->second) {
300         iter->second->ProcessShareFormResponse(result);
301     }
302     shareFormCallbackMap_.erase(requestCode);
303     HILOG_DEBUG("%{public}s done", __func__);
304 }
305 
OnError(int32_t errorCode,const std::string & errorMsg)306 void FormHostClient::OnError(int32_t errorCode, const std::string &errorMsg)
307 {
308     HITRACE_METER_NAME(HITRACE_TAG_ABILITY_MANAGER, __PRETTY_FUNCTION__);
309     HILOG_ERROR("Receive error form FMS, errorCode: %{public}d, errorMsg: %{public}s.", errorCode, errorMsg.c_str());
310     std::lock_guard<std::mutex> lock(callbackMutex_);
311     for (auto formIdIter = etsFormIds_.begin(); formIdIter != etsFormIds_.end();) {
312         int64_t formId = *formIdIter;
313         auto callbackMapIter = formCallbackMap_.find(formId);
314         if (callbackMapIter == formCallbackMap_.end()) {
315             HILOG_ERROR("Can not find form: %{public}" PRId64 " in formCallbackMap, remove it.", formId);
316             formIdIter = etsFormIds_.erase(formIdIter);
317             continue;
318         }
319         ++formIdIter;
320 
321         const std::set<std::shared_ptr<FormCallbackInterface>> &callbackSet = callbackMapIter->second;
322         HILOG_DEBUG("callbackSet.size: %{public}zu", callbackSet.size());
323         for (const auto &callback : callbackSet) {
324             if (callback == nullptr) {
325                 HILOG_ERROR("FormCallback is nullptr.");
326                 continue;
327             }
328             callback->OnError(errorCode, errorMsg);
329         }
330     }
331 }
332 
RemoveShareFormCallback(int64_t requestCode)333 void FormHostClient::RemoveShareFormCallback(int64_t requestCode)
334 {
335     HILOG_DEBUG("%{public}s called", __func__);
336     std::lock_guard<std::mutex> lock(shareFormCallbackMutex_);
337     auto iter = shareFormCallbackMap_.find(requestCode);
338     if (iter != shareFormCallbackMap_.end()) {
339         shareFormCallbackMap_.erase(requestCode);
340     }
341     HILOG_INFO("%{public}s end.", __func__);
342 }
343 
UpdateForm(const FormJsInfo & formJsInfo)344 void FormHostClient::UpdateForm(const FormJsInfo &formJsInfo)
345 {
346     HILOG_DEBUG("%{public}s called, image number is %{public}zu.",  __func__, formJsInfo.imageDataMap.size());
347     int64_t formId = formJsInfo.formId;
348     if (formId < 0) {
349         HILOG_ERROR("%{public}s error, the passed form id can't be negative.", __func__);
350         return;
351     }
352     std::lock_guard<std::mutex> lock(callbackMutex_);
353     auto iter = formCallbackMap_.find(formId);
354     if (iter == formCallbackMap_.end()) {
355         HILOG_ERROR("%{public}s error, not find formId:%{public}s.", __func__, std::to_string(formId).c_str());
356         return;
357     }
358     for (const auto &callback : iter->second) {
359         HILOG_DEBUG("%{public}s, formId: %{public}" PRId64 ", jspath: %{public}s, data: %{private}s",
360             __func__, formId, formJsInfo.jsFormCodePath.c_str(), formJsInfo.formData.c_str());
361         callback->ProcessFormUpdate(formJsInfo);
362     }
363 }
364 } // namespace AppExecFwk
365 } // namespace OHOS
366