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