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