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 "appexecfwk_errors.h"
19 #include "form_ams_helper.h"
20 #include "form_batch_delete_connection.h"
21 #include "form_cache_mgr.h"
22 #include "form_constants.h"
23 #include "form_data_mgr.h"
24 #include "form_delete_connection.h"
25 #include "form_msg_event_connection.h"
26 #include "form_provider_mgr.h"
27 #include "form_record.h"
28 #include "form_refresh_connection.h"
29 #include "form_timer_mgr.h"
30 #include "hilog_wrapper.h"
31 #include "power_mgr_client.h"
32
33 namespace OHOS {
34 namespace AppExecFwk {
FormProviderMgr()35 FormProviderMgr::FormProviderMgr(){}
~FormProviderMgr()36 FormProviderMgr::~FormProviderMgr(){}
37 /**
38 * @brief handle for acquire back from ams.
39 * @param formId The id of the form.
40 * @param formProviderInfo provider form info.
41 * @return Returns ERR_OK on success, others on failure.
42 */
AcquireForm(const int64_t formId,const FormProviderInfo & formProviderInfo)43 ErrCode FormProviderMgr::AcquireForm(const int64_t formId, const FormProviderInfo &formProviderInfo)
44 {
45 HILOG_DEBUG("%{public}s start, formId:%{public}" PRId64 "", __func__, formId);
46
47 if (formId <= 0) {
48 HILOG_ERROR("%{public}s fail, formId should be greater than 0", __func__);
49 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
50 }
51
52 FormRecord formRecord;
53 bool isGetFormRecord = FormDataMgr::GetInstance().GetFormRecord(formId, formRecord);
54 if (!isGetFormRecord) {
55 HILOG_ERROR("%{public}s fail, not exist such form, formId:%{public}" PRId64 "", __func__, formId);
56 return ERR_APPEXECFWK_FORM_NOT_EXIST_ID;
57 }
58
59 FormHostRecord clientHost;
60 bool isGetFormHostRecord = FormDataMgr::GetInstance().GetFormHostRecord(formId, clientHost);
61 if (!isGetFormHostRecord) {
62 HILOG_ERROR("%{public}s fail, clientHost is null", __func__);
63 return ERR_APPEXECFWK_FORM_COMMON_CODE;
64 }
65
66 if (formRecord.isInited) {
67 if (IsFormCached(formRecord)) {
68 if (clientHost.Contains(formId)) {
69 formRecord.formProviderInfo = formProviderInfo;
70 clientHost.OnAcquire(formId, formRecord);
71 }
72 } else {
73 Want want;
74 RefreshForm(formId, want, true);
75 }
76 return ERR_OK;
77 }
78 formRecord.isInited = true;
79 formRecord.needRefresh = false;
80 FormDataMgr::GetInstance().SetFormCacheInited(formId, true);
81
82 if (clientHost.Contains(formId)) {
83 formRecord.formProviderInfo = formProviderInfo;
84 clientHost.OnAcquire(formId, formRecord);
85 }
86
87 // we do not cache when data size is over 1k
88 std::string jsonData = formProviderInfo.GetFormDataString(); // get json data
89 HILOG_DEBUG("%{public}s , jsonData is %{public}s.", __func__, jsonData.c_str());
90
91 std::map<std::string, std::pair<sptr<FormAshmem>, int32_t>> imageDataMap = formProviderInfo.GetImageDataMap();
92 if (jsonData.size() <= Constants::MAX_FORM_DATA_SIZE) {
93 HILOG_WARN("%{public}s, acquire js card, cache the card", __func__);
94 FormCacheMgr::GetInstance().AddData(formId, formProviderInfo.GetFormDataString(),
95 formProviderInfo.GetImageDataMap());
96 }
97 return ERR_OK;
98 }
99
100 /**
101 * @brief Refresh form.
102 *
103 * @param formId The form id.
104 * @param want The want of the form to request.
105 * @param isVisibleToFresh The form is visible to fresh.
106 * @return Returns ERR_OK on success, others on failure.
107 */
RefreshForm(const int64_t formId,const Want & want,bool isVisibleToFresh)108 ErrCode FormProviderMgr::RefreshForm(const int64_t formId, const Want &want, bool isVisibleToFresh)
109 {
110 HILOG_INFO("%{public}s called, formId:%{public}" PRId64 ".", __func__, formId);
111 FormRecord record;
112 bool bGetRecord = FormDataMgr::GetInstance().GetFormRecord(formId, record);
113 if (!bGetRecord) {
114 HILOG_ERROR("%{public}s fail, not exist such form:%{public}" PRId64 "", __func__, formId);
115 return ERR_APPEXECFWK_FORM_NOT_EXIST_ID;
116 }
117
118 // get current userId
119 int32_t currentUserId = want.GetIntParam(Constants::PARAM_FORM_USER_ID, DEFAULT_USER_ID);
120 HILOG_INFO("%{public}s, current user, userId:%{public}d", __func__, currentUserId);
121 if (currentUserId != record.userId) {
122 FormDataMgr::GetInstance().SetNeedRefresh(formId, true);
123 HILOG_ERROR("%{public}s, not current user, just set refresh flag, userId:%{public}d", __func__, record.userId);
124 return ERR_APPEXECFWK_FORM_OPERATION_NOT_SELF;
125 }
126
127 bool isTimerRefresh = want.GetBoolParam(Constants::KEY_IS_TIMER, false);
128 Want newWant(want);
129 newWant.RemoveParam(Constants::KEY_IS_TIMER);
130
131 if (isTimerRefresh) {
132 FormDataMgr::GetInstance().SetCountTimerRefresh(formId, true);
133 }
134
135 bool screenOnFlag = PowerMgr::PowerMgrClient::GetInstance().IsScreenOn();
136 if (!screenOnFlag) {
137 FormDataMgr::GetInstance().SetNeedRefresh(formId, true);
138 HILOG_ERROR("%{public}s fail, screen off, set refresh flag, do not refresh now", __func__);
139 return ERR_OK;
140 }
141
142 bool needRefresh = IsNeedToFresh(record, formId, isVisibleToFresh);
143 if (!needRefresh) {
144 FormDataMgr::GetInstance().SetNeedRefresh(formId, true);
145 HILOG_ERROR("%{public}s fail, no one needReresh, set refresh flag, do not refresh now", __func__);
146 return ERR_OK;
147 }
148
149 FormRecord refreshRecord = GetFormAbilityInfo(record);
150 refreshRecord.isInited = record.isInited;
151 refreshRecord.versionUpgrade = record.versionUpgrade;
152 refreshRecord.isCountTimerRefresh = isTimerRefresh;
153 return ConnectAmsForRefresh(formId, refreshRecord, newWant, isTimerRefresh);
154 }
155
156 /**
157 * @brief Connect ams for refresh form
158 *
159 * @param formId The form id.
160 * @param record Form data.
161 * @param want The want of the form.
162 * @param isTimerRefresh The flag of timer refresh.
163 * @return Returns ERR_OK on success, others on failure.
164 */
ConnectAmsForRefresh(const int64_t formId,const FormRecord & record,const Want & want,const bool isTimerRefresh)165 ErrCode FormProviderMgr::ConnectAmsForRefresh(const int64_t formId,
166 const FormRecord &record, const Want &want, const bool isTimerRefresh)
167 {
168 HILOG_DEBUG("%{public}s called, bundleName:%{public}s, abilityName:%{public}s.",
169 __func__, record.bundleName.c_str(), record.abilityName.c_str());
170
171 sptr<IAbilityConnection> formRefreshConnection = new FormRefreshConnection(formId, want,
172 record.bundleName, record.abilityName);
173 Want connectWant;
174 connectWant.AddFlags(Want::FLAG_ABILITY_FORM_ENABLED);
175 connectWant.SetElementName(record.bundleName, record.abilityName);
176
177 if (isTimerRefresh) {
178 if (!FormTimerMgr::GetInstance().IsLimiterEnableRefresh(formId)) {
179 HILOG_ERROR("%{public}s, timer refresh, already limit.", __func__);
180 return ERR_APPEXECFWK_FORM_PROVIDER_DEL_FAIL;
181 }
182 }
183
184 ErrCode errorCode = FormAmsHelper::GetInstance().ConnectServiceAbility(connectWant, formRefreshConnection);
185 if (errorCode != ERR_OK) {
186 HILOG_ERROR("%{public}s, ConnectServiceAbility failed.", __func__);
187 return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED;
188 }
189
190 if (record.isCountTimerRefresh) {
191 IncreaseTimerRefreshCount(formId);
192 }
193
194 return ERR_OK;
195 }
196
197 /**
198 * @brief Notify provider form delete.
199 * @param formId The form id.
200 * @param record Form information.
201 * @return Function result and has other host flag.
202 */
NotifyProviderFormDelete(const int64_t formId,const FormRecord & formRecord)203 ErrCode FormProviderMgr::NotifyProviderFormDelete(const int64_t formId, const FormRecord &formRecord)
204 {
205 if (formRecord.abilityName.empty()) {
206 HILOG_ERROR("%{public}s, formRecord.abilityName is empty.", __func__);
207 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
208 }
209
210 if (formRecord.bundleName.empty()) {
211 HILOG_ERROR("%{public}s, formRecord.bundleName is empty.", __func__);
212 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
213 }
214
215 HILOG_DEBUG("%{public}s, connectAbility,bundleName:%{public}s, abilityName:%{public}s",
216 __func__, formRecord.bundleName.c_str(), formRecord.abilityName.c_str());
217 sptr<IAbilityConnection> formDeleteConnection = new FormDeleteConnection(formId,
218 formRecord.bundleName, formRecord.abilityName);
219 Want want;
220 want.SetElementName(formRecord.bundleName, formRecord.abilityName);
221 want.SetFlags(Want::FLAG_ABILITY_FORM_ENABLED);
222
223 ErrCode errorCode = FormAmsHelper::GetInstance().ConnectServiceAbility(want, formDeleteConnection);
224 if (errorCode != ERR_OK) {
225 HILOG_ERROR("%{public}s, ConnectServiceAbility failed.", __func__);
226 return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED;
227 }
228 return ERR_OK;
229 }
230
231 /**
232 * @brief Notify provider forms batch delete.
233 * @param bundleName BundleName.
234 * @param bundleName AbilityName.
235 * @param formIds form id list.
236 * @return Returns ERR_OK on success, others on failure.
237 */
NotifyProviderFormsBatchDelete(const std::string & bundleName,const std::string & abilityName,const std::set<int64_t> & formIds)238 ErrCode FormProviderMgr::NotifyProviderFormsBatchDelete(const std::string &bundleName,
239 const std::string &abilityName, const std::set<int64_t> &formIds)
240 {
241 if (abilityName.empty()) {
242 HILOG_ERROR("%{public}s error, abilityName is empty.", __func__);
243 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
244 }
245
246 if (bundleName.empty()) {
247 HILOG_ERROR("%{public}s error, bundleName is empty.", __func__);
248 return ERR_APPEXECFWK_FORM_INVALID_PARAM;
249 }
250
251 HILOG_DEBUG("%{public}s, bundleName:%{public}s, abilityName:%{public}s",
252 __func__, bundleName.c_str(), abilityName.c_str());
253 sptr<IAbilityConnection> batchDeleteConnection = new FormBatchDeleteConnection(formIds, bundleName, abilityName);
254 Want want;
255 want.AddFlags(Want::FLAG_ABILITY_FORM_ENABLED);
256 want.SetElementName(bundleName, abilityName);
257
258 ErrCode errorCode = FormAmsHelper::GetInstance().ConnectServiceAbility(want, batchDeleteConnection);
259 if (errorCode != ERR_OK) {
260 HILOG_ERROR("%{public}s, ConnectServiceAbility failed.", __func__);
261 return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED;
262 }
263 return ERR_OK;
264 }
265 /**
266 * @brief Update form.
267 * @param formId The form's id.
268
269 * @param formProviderData form provider data.
270 * @return Returns ERR_OK on success, others on failure.
271 */
UpdateForm(const int64_t formId,const FormProviderInfo & formProviderInfo)272 ErrCode FormProviderMgr::UpdateForm(const int64_t formId, const FormProviderInfo &formProviderInfo)
273 {
274 // check exist and get the formRecord
275 FormRecord formRecord;
276 if (!FormDataMgr::GetInstance().GetFormRecord(formId, formRecord)) {
277 HILOG_ERROR("%{public}s error, not exist such form:%{public}" PRId64 ".", __func__, formId);
278 return ERR_APPEXECFWK_FORM_NOT_EXIST_ID;
279 }
280 return UpdateForm(formId, formRecord, formProviderInfo.GetFormData());
281 }
282 /**
283 * handle for update form event from provider.
284 *
285 * @param formId The id of the form.
286 * @param formRecord The form's record.
287 * @param formProviderData provider form info.
288 * @return Returns ERR_OK on success, others on failure.
289 */
UpdateForm(const int64_t formId,FormRecord & formRecord,const FormProviderData & formProviderData)290 ErrCode FormProviderMgr::UpdateForm(const int64_t formId,
291 FormRecord &formRecord, const FormProviderData &formProviderData)
292 {
293 HILOG_INFO("%{public}s start, imageDateState is %{public}d", __func__, formProviderData.GetImageDataState());
294 if (formRecord.versionUpgrade) {
295 formRecord.formProviderInfo.SetFormData(formProviderData);
296 formRecord.formProviderInfo.SetUpgradeFlg(true);
297 } else {
298 nlohmann::json addJsonData = formProviderData.GetData();
299 formRecord.formProviderInfo.MergeData(addJsonData);
300 // merge image
301 auto formData = formRecord.formProviderInfo.GetFormData();
302 formData.SetImageDataState(formProviderData.GetImageDataState());
303 formData.SetImageDataMap(formProviderData.GetImageDataMap());
304 formRecord.formProviderInfo.SetFormData(formData);
305 }
306
307 // formRecord init
308 formRecord.isInited = true;
309 formRecord.needRefresh = false;
310 FormDataMgr::GetInstance().SetFormCacheInited(formId, true);
311
312 // update form for host clients
313 FormDataMgr::GetInstance().UpdateHostNeedRefresh(formId, true);
314
315 bool screenOnFlag = PowerMgr::PowerMgrClient::GetInstance().IsScreenOn();
316 if (screenOnFlag) {
317 if (FormDataMgr::GetInstance().UpdateHostForm(formId, formRecord)) {
318 FormDataMgr::GetInstance().SetVersionUpgrade(formId, false);
319 formRecord.formProviderInfo.SetUpgradeFlg(false);
320 }
321 }
322 // check if cache data size is less than 1k or not
323 std::string jsonData = formRecord.formProviderInfo.GetFormDataString(); // get json data
324 HILOG_DEBUG("%{public}s screenOn:%{public}d jsonData:%{public}s.", __func__, screenOnFlag, jsonData.c_str());
325
326 std::map<std::string, std::pair<sptr<FormAshmem>, int32_t>> imageDataMap = formProviderData.GetImageDataMap();
327 // check if cache data size is less than 1k or not
328 if (jsonData.size() <= Constants::MAX_FORM_DATA_SIZE) {
329 HILOG_INFO("%{public}s, updateJsForm, data is less than 1k, cache data.", __func__);
330 FormCacheMgr::GetInstance().AddData(formId, jsonData, formProviderData.GetImageDataMap());
331 } else {
332 FormCacheMgr::GetInstance().DeleteData(formId);
333 }
334
335 // the update form is successfully
336 return ERR_OK;
337 }
338 /**
339 * @brief Process js message event.
340 * @param formId Indicates the unique id of form.
341 * @param record Form record.
342 * @param want information passed to supplier.
343 * @return Returns true if execute success, false otherwise.
344 */
MessageEvent(const int64_t formId,const FormRecord & record,const Want & want)345 int FormProviderMgr::MessageEvent(const int64_t formId, const FormRecord &record, const Want &want)
346 {
347 HILOG_INFO("%{public}s called, formId:%{public}" PRId64 ".", __func__, formId);
348
349 bool screenOnFlag = PowerMgr::PowerMgrClient::GetInstance().IsScreenOn();
350 if (!screenOnFlag) {
351 HILOG_WARN("%{public}s fail, screen off now", __func__);
352 return ERR_APPEXECFWK_FORM_COMMON_CODE;
353 }
354
355 sptr<IAbilityConnection> formMsgEventConnection = new FormMsgEventConnection(formId, want,
356 record.bundleName, record.abilityName);
357 Want connectWant;
358 connectWant.AddFlags(Want::FLAG_ABILITY_FORM_ENABLED);
359 connectWant.SetElementName(record.bundleName, record.abilityName);
360
361 ErrCode errorCode = FormAmsHelper::GetInstance().ConnectServiceAbility(connectWant, formMsgEventConnection);
362 if (errorCode != ERR_OK) {
363 HILOG_ERROR("%{public}s, ConnectServiceAbility failed.", __func__);
364 return ERR_APPEXECFWK_FORM_BIND_PROVIDER_FAILED;
365 }
366
367 return ERR_OK;
368 }
369
370 /**
371 * @brief Increase the timer refresh count.
372 *
373 * @param formId The form id.
374 */
IncreaseTimerRefreshCount(const int64_t formId)375 void FormProviderMgr::IncreaseTimerRefreshCount(const int64_t formId)
376 {
377 FormRecord record;
378 if (!FormDataMgr::GetInstance().GetFormRecord(formId, record)) {
379 HILOG_ERROR("%{public}s failed, not exist such form:%{public}" PRId64 ".", __func__, formId);
380 return;
381 }
382
383 if (record.isCountTimerRefresh) {
384 FormDataMgr::GetInstance().SetCountTimerRefresh(formId, false);
385 FormTimerMgr::GetInstance().IncreaseRefreshCount(formId);
386 }
387 }
388
389 /**
390 * @brief Acquire form state.
391 * @param state form state.
392 * @param provider provider info.
393 * @param wantArg The want of onAcquireFormState.
394 * @return Returns ERR_OK on success, others on failure.
395 */
AcquireFormStateBack(FormState state,const std::string & provider,const Want & wantArg)396 ErrCode FormProviderMgr::AcquireFormStateBack(FormState state, const std::string& provider, const Want &wantArg)
397 {
398 HILOG_DEBUG("AcquireFormState start: %{public}d, provider: %{public}s", state, provider.c_str());
399 FormDataMgr::GetInstance().AcquireFormStateBack(state, provider, wantArg);
400 return ERR_OK;
401 }
402
IsNeedToFresh(FormRecord & record,int64_t formId,bool isVisibleToFresh)403 bool FormProviderMgr::IsNeedToFresh(FormRecord &record, int64_t formId, bool isVisibleToFresh)
404 {
405 bool isEnableRefresh = FormDataMgr::GetInstance().IsEnableRefresh(formId);
406 HILOG_DEBUG("isEnableRefresh is %{public}d", isEnableRefresh);
407 if (isEnableRefresh) {
408 return true;
409 }
410
411 HILOG_DEBUG("isVisibleToFresh is %{public}d, record.isVisible is %{public}d", isVisibleToFresh, record.isVisible);
412 if (isVisibleToFresh) {
413 return record.isVisible;
414 }
415
416 bool isEnableUpdate = FormDataMgr::GetInstance().IsEnableUpdate(formId);
417 HILOG_DEBUG("isEnableUpdate is %{public}d", isEnableUpdate);
418 return isEnableUpdate;
419 }
420
GetFormAbilityInfo(const FormRecord & record) const421 FormRecord FormProviderMgr::GetFormAbilityInfo(const FormRecord &record) const
422 {
423 FormRecord newRecord;
424 newRecord.bundleName = record.bundleName;
425 newRecord.abilityName = record.abilityName;
426
427 return newRecord;
428 }
429
IsFormCached(const FormRecord & record)430 bool FormProviderMgr::IsFormCached(const FormRecord &record)
431 {
432 if (record.versionUpgrade) {
433 return false;
434 }
435 return FormCacheMgr::GetInstance().IsExist(record.formId);
436 }
437 } // namespace AppExecFwk
438 } // namespace OHOS