• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 <cinttypes>
17 
18 #include "app_log_wrapper.h"
19 #include "form_host_client.h"
20 
21 namespace OHOS {
22 namespace AppExecFwk {
23 sptr<FormHostClient> FormHostClient::instance_ = nullptr;
24 std::mutex FormHostClient::instanceMutex_;
25 
FormHostClient()26 FormHostClient::FormHostClient()
27 {
28 }
29 
~FormHostClient()30 FormHostClient::~FormHostClient()
31 {
32 }
33 
34 /**
35  * @brief Get FormHostClient instance.
36  *
37  * @return FormHostClient instance.
38  */
GetInstance()39 sptr<FormHostClient> FormHostClient::GetInstance()
40 {
41     if (instance_ == nullptr) {
42         std::lock_guard<std::mutex> lock_l(instanceMutex_);
43         if (instance_ == nullptr) {
44             instance_ = new FormHostClient();
45         }
46     }
47     return instance_;
48 }
49 
50 /**
51  * @brief Add form.
52  *
53  * @param formCallback the host's form callback.
54  * @param formId The Id of the form.
55  * @return none.
56  */
AddForm(std::shared_ptr<FormCallbackInterface> formCallback,const int64_t formId)57 void FormHostClient::AddForm(std::shared_ptr<FormCallbackInterface> formCallback, const int64_t formId)
58 {
59     APP_LOGI("%{public}s called.", __func__);
60 
61     if (formId <= 0) {
62         APP_LOGE("%{public}s error, the passed form id can't be negative or zero.", __func__);
63         return;
64     }
65 
66     {
67         std::lock_guard<std::mutex> lock(lockMutex_);
68         int64_t key = FindKeyByCallback(formCallback);
69         if (key == -1) {
70             HostForms hostForms;
71             int64_t tempKey = key_;
72             if (!keyVector_.empty()) {
73                 tempKey = keyVector_.back();
74                 keyVector_.pop_back();
75             }
76             hostForms.AddForm(formId);
77             recordCallback_.insert(std::make_pair(tempKey, formCallback));
78             recordHostForms_.insert(std::make_pair(tempKey, hostForms));
79 
80             if (tempKey == key_) {
81                 key_++;
82             }
83         } else {
84             recordHostForms_[key].AddForm(formId);
85         }
86     }
87 }
88 
89 /**
90  * @brief Remove form.
91  *
92  * @param formCallback the host's form callback.
93  * @param formId The Id of the form.
94  * @return none.
95  */
RemoveForm(std::shared_ptr<FormCallbackInterface> formCallback,const int64_t formId)96 void FormHostClient::RemoveForm(std::shared_ptr<FormCallbackInterface> formCallback, const int64_t formId)
97 {
98     APP_LOGI("%{public}s called.", __func__);
99 
100     if (formId <= 0 || formCallback == nullptr) {
101         APP_LOGE("%{public}s, invalid param.", __func__);
102         return;
103     }
104 
105     {
106         std::lock_guard<std::mutex> lock(lockMutex_);
107         int64_t key = FindKeyByCallback(formCallback);
108         if (key == -1) {
109             APP_LOGE("%{public}s, failed to find callback.", __func__);
110             return;
111         }
112 
113         if (recordHostForms_[key].IsEmpty()) {
114             recordCallback_.erase(key);
115             recordHostForms_.erase(key);
116             keyVector_.push_back(key);
117             APP_LOGI("%{public}s, clear data.", __func__);
118             return;
119         }
120 
121         recordHostForms_[key].DelForm(formId);
122         if (recordHostForms_[key].IsEmpty()) {
123             recordCallback_.erase(key);
124             recordHostForms_.erase(key);
125             keyVector_.push_back(key);
126             APP_LOGI("%{public}s, clear data.", __func__);
127         }
128     }
129     APP_LOGI("%{public}s end.", __func__);
130 }
131 
132 /**
133  * @brief Check whether the form exist in the formhosts.
134  *
135  * @param formId The Id of the form.
136  * @return Returns true if contains form; returns false otherwise.
137  */
ContainsForm(int64_t formId)138 bool FormHostClient::ContainsForm(int64_t formId)
139 {
140     APP_LOGI("%{public}s called.", __func__);
141 
142     std::lock_guard<std::mutex> lock(lockMutex_);
143     for (auto recordHostForm : recordHostForms_) {
144         if (recordHostForm.second.Contains(formId)) {
145             return true;
146         }
147     }
148     return false;
149 }
150 
151 /**
152  * @brief Request to give back a form.
153  *
154  * @param formJsInfo Form js info.
155  * @return none.
156  */
OnAcquired(const FormJsInfo & formJsInfo)157 void FormHostClient::OnAcquired(const FormJsInfo &formJsInfo)
158 {
159     APP_LOGI("%{public}s called.", __func__);
160     int64_t formId = formJsInfo.formId;
161     if (formId < 0) {
162         APP_LOGE("%{public}s error, the passed form id can't be negative.", __func__);
163         return;
164     }
165     std::shared_ptr<FormCallbackInterface> targetCallback = FindTargetCallback(formId);
166     if (targetCallback == nullptr) {
167         APP_LOGE("%{public}s error, can't find target callback. formId: %{public}" PRId64 ".", __func__, formId);
168         return;
169     }
170     APP_LOGI("%{public}s, formId: %{public}" PRId64 ", jspath: %{public}s, data: %{public}s", __func__, formId,
171         formJsInfo.jsFormCodePath.c_str(), formJsInfo.formData.c_str());
172     targetCallback->ProcessFormUpdate(formJsInfo);
173 }
174 
175 /**
176  * @brief Update form.
177  *
178  * @param formJsInfo Form js info.
179  * @return none.
180  */
OnUpdate(const FormJsInfo & formJsInfo)181 void FormHostClient::OnUpdate(const FormJsInfo &formJsInfo)
182 {
183     APP_LOGI("%{public}s called.", __func__);
184     int64_t formId = formJsInfo.formId;
185     if (formId < 0) {
186         APP_LOGE("%{public}s error, the passed form id can't be negative.", __func__);
187         return;
188     }
189     std::shared_ptr<FormCallbackInterface> targetCallback = FindTargetCallback(formId);
190     if (targetCallback == nullptr) {
191         APP_LOGE("%{public}s error, can't find target callback. formId: %{public}" PRId64 ".", __func__, formId);
192         return;
193     }
194     targetCallback->ProcessFormUpdate(formJsInfo);
195 }
196 
197 /**
198  * @brief UnInstall the forms.
199  *
200  * @param formIds The Id of the forms.
201  * @return none.
202  */
OnUninstall(const std::vector<int64_t> & formIds)203 void FormHostClient::OnUninstall(const std::vector<int64_t> &formIds)
204 {
205     APP_LOGI("%{public}s called.", __func__);
206     if (formIds.size() <= 0) {
207         APP_LOGE("%{public}s error, formIds is empty.", __func__);
208         return;
209     }
210     for (auto &formId : formIds) {
211         if (formId < 0) {
212             APP_LOGE("%{public}s error, the passed form id can't be negative.", __func__);
213             continue;
214         }
215         std::shared_ptr<FormCallbackInterface> targetCallback = FindTargetCallback(formId);
216         if (targetCallback == nullptr) {
217             APP_LOGE("%{public}s error, can't find target callback. formId: %{public}" PRId64 ".", __func__, formId);
218             continue;
219         }
220         targetCallback->ProcessFormUninstall(formId);
221     }
222 }
223 
224 /**
225  * @brief Find callback by formId.
226  *
227  * @param formId The Id of the form.
228  * @return target callback
229  */
FindTargetCallback(int64_t formId)230 std::shared_ptr<FormCallbackInterface> FormHostClient::FindTargetCallback(int64_t formId)
231 {
232     std::lock_guard<std::mutex> lock(lockMutex_);
233     for (auto record : recordHostForms_) {
234         if (record.second.Contains(formId)) {
235             return recordCallback_[record.first];
236         }
237     }
238     return nullptr;
239 }
240 
241 /**
242  * @brief Find Key By form callback.
243  *
244  * @param formCallback The form callback.
245  * @return callback's key
246  */
FindKeyByCallback(std::shared_ptr<FormCallbackInterface> formCallback)247 int32_t FormHostClient::FindKeyByCallback(std::shared_ptr<FormCallbackInterface> formCallback)
248 {
249     for (auto recordCallback : recordCallback_) {
250         if (Compare(recordCallback.second, formCallback)) {
251             return recordCallback.first;
252         }
253     }
254     return -1;
255 }
256 
257 /**
258  * @brief Compare form callback.
259  *
260  * @param formCallback1 The form callback.
261  * @param formCallback2 The form callback to be compared with form callback1.
262  * @return Returns true if the two form callback are equal to each other, returns false otherwise.
263  */
Compare(std::shared_ptr<FormCallbackInterface> formCallback1,std::shared_ptr<FormCallbackInterface> formCallback2)264 bool FormHostClient::Compare(std::shared_ptr<FormCallbackInterface> formCallback1,
265     std::shared_ptr<FormCallbackInterface> formCallback2)
266 {
267     return (formCallback1 == formCallback2) ? true : false;
268 }
269 }  // namespace AppExecFwk
270 }  // namespace OHOS
271