• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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