• 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 "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