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