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