• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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_event_util.h"
17 
18 #include "form_bms_helper.h"
19 #include "form_cache_mgr.h"
20 #include "form_data_mgr.h"
21 #include "form_db_cache.h"
22 #include "form_info_mgr.h"
23 #include "form_timer_mgr.h"
24 #include "form_util.h"
25 #include "form_provider_mgr.h"
26 #include "hilog_wrapper.h"
27 #include "in_process_call_wrapper.h"
28 #include "want.h"
29 
30 namespace OHOS {
31 namespace AppExecFwk {
32 
33 
HandleBundleFormInfoChanged(const std::string & bundleName,int32_t userId)34 void FormEventUtil::HandleBundleFormInfoChanged(const std::string &bundleName, int32_t userId)
35 {
36     FormInfoMgr::GetInstance().Update(bundleName, userId);
37 }
38 
39 
HandleProviderUpdated(const std::string & bundleName,const int userId)40 void FormEventUtil::HandleProviderUpdated(const std::string &bundleName, const int userId)
41 {
42     HILOG_INFO("%{public}s, bundleName:%{public}s, userId:%{public}d.", __func__, bundleName.c_str(), userId);
43     std::vector<FormRecord> formInfos;
44     if (!FormDataMgr::GetInstance().GetFormRecord(bundleName, formInfos)) {
45         HILOG_INFO("%{public}s, no form info.", __func__);
46         return;
47     }
48 
49     sptr<IBundleMgr> iBundleMgr = FormBmsHelper::GetInstance().GetBundleMgr();
50     if (iBundleMgr == nullptr) {
51         // GetBundleMgr() has error log
52         return;
53     }
54 
55     std::vector<FormInfo> targetForms;
56     if (!IN_PROCESS_CALL(iBundleMgr->GetFormsInfoByApp(bundleName, targetForms))) {
57         HILOG_ERROR("%{public}s error, failed to get forms info.", __func__);
58         return;
59     }
60 
61     std::vector<int64_t> removedForms;
62     std::vector<int64_t> updatedForms;
63     for (FormRecord& formRecord : formInfos) {
64         HILOG_INFO("%{public}s, provider update, formName:%{public}s", __func__, formRecord.formName.c_str());
65         int64_t formId = formRecord.formId;
66         if (ProviderFormUpdated(formId, formRecord, targetForms)) {
67             updatedForms.emplace_back(formId);
68             continue;
69         }
70 
71         HILOG_INFO("%{public}s, no such form anymore, delete it:%{public}s", __func__, formRecord.formName.c_str());
72         (!formRecord.formTempFlg) ? FormDbCache::GetInstance().DeleteFormInfo(formId) :
73             FormDataMgr::GetInstance().DeleteTempForm(formId);
74         removedForms.emplace_back(formId);
75         FormDataMgr::GetInstance().DeleteFormRecord(formId);
76     }
77 
78     if (!removedForms.empty()) {
79         HILOG_INFO("%{public}s, clean removed forms", __func__);
80         FormDataMgr::GetInstance().CleanHostRemovedForms(removedForms);
81     }
82 
83     HILOG_INFO("%{public}s, remove form timer", __func__);
84     for (const int64_t id : removedForms) {
85         FormTimerMgr::GetInstance().RemoveFormTimer(id);
86     }
87 
88     HILOG_INFO("%{public}s, refresh form", __func__);
89     Want want;
90     want.SetParam(Constants::PARAM_FORM_USER_ID, userId);
91     for (const int64_t id : updatedForms) {
92         FormProviderMgr::GetInstance().RefreshForm(id, want, true);
93     }
94 }
95 
HandleBundleFormInfoRemoved(const std::string & bundleName,int32_t userId)96 void FormEventUtil::HandleBundleFormInfoRemoved(const std::string &bundleName, int32_t userId)
97 {
98     FormInfoMgr::GetInstance().Remove(bundleName, userId);
99 }
100 
HandleProviderRemoved(const std::string & bundleName,const int32_t userId)101 void FormEventUtil::HandleProviderRemoved(const std::string &bundleName, const int32_t userId)
102 {
103     HILOG_INFO("GET into HandleProviderRemoved with bundleName : %{public}s, userId : %{public}d",
104         bundleName.c_str(), userId);
105     // clean removed form in DB
106     std::set<int64_t> removedForms;
107     {
108         std::vector<FormDBInfo> removedDBForm;
109         FormDbCache::GetInstance().DeleteFormInfoByBundleName(bundleName, userId, removedDBForm);
110         for (const auto &dbForm : removedDBForm) {
111             removedForms.emplace(dbForm.formId);
112             int32_t matchCount = FormDbCache::GetInstance().GetMatchCount(dbForm.bundleName, dbForm.moduleName);
113             if (matchCount == 0) {
114                 FormBmsHelper::GetInstance().NotifyModuleRemovable(dbForm.bundleName, dbForm.moduleName);
115             }
116         }
117     }
118     // clean removed form in FormRecords
119     FormDataMgr::GetInstance().CleanRemovedFormRecords(bundleName, removedForms);
120     // clean removed temp form in FormRecords
121     FormDataMgr::GetInstance().CleanRemovedTempFormRecords(bundleName, userId, removedForms);
122     // clean removed forms in FormHostRecords
123     std::vector<int64_t> vRemovedForms;
124     vRemovedForms.assign(removedForms.begin(), removedForms.end());
125     FormDataMgr::GetInstance().CleanHostRemovedForms(vRemovedForms);
126 
127     // clean removed form timers
128     for (auto &formId : removedForms) {
129         FormTimerMgr::GetInstance().RemoveFormTimer(formId);
130     }
131 }
132 
HandleBundleDataCleared(const std::string & bundleName,const int uid)133 void FormEventUtil::HandleBundleDataCleared(const std::string &bundleName, const int uid)
134 {
135     HILOG_DEBUG("%{public}s, bundleName:%{public}s, uid:%{public}d", __func__, bundleName.c_str(), uid);
136     // as provider data is cleared
137     std::set<int64_t> reCreateForms;
138     FormDataMgr::GetInstance().GetReCreateFormRecordsByBundleName(bundleName, reCreateForms);
139     if (!reCreateForms.empty()) {
140         for (int64_t formId : reCreateForms) {
141             ReCreateForm(formId);
142         }
143     }
144 
145     // as form host data is cleared
146     HandleFormHostDataCleared(uid);
147 }
148 
HandleFormHostDataCleared(const int uid)149 void FormEventUtil::HandleFormHostDataCleared(const int uid)
150 {
151     HILOG_DEBUG("%{public}s, uid:%{public}d", __func__, uid);
152     std::map<int64_t, bool> removedFormsMap;
153     // clear formDBRecord
154     ClearFormDBRecordData(uid, removedFormsMap);
155 
156     // clear temp form
157     ClearTempFormRecordData(uid, removedFormsMap);
158 
159     // clear host data
160     FormDataMgr::GetInstance().ClearHostDataByUId(uid);
161 
162     // delete forms timer
163     for (const auto &removedForm : removedFormsMap) {
164         if (removedForm.second) {
165             FormTimerMgr::GetInstance().RemoveFormTimer(removedForm.first);
166         }
167     }
168 }
169 
ProviderFormUpdated(const int64_t formId,const FormRecord & formRecord,const std::vector<FormInfo> & targetForms)170 bool FormEventUtil::ProviderFormUpdated(const int64_t formId,
171     const FormRecord &formRecord, const std::vector<FormInfo> &targetForms)
172 {
173     HILOG_INFO("%{public}s start", __func__);
174     if (targetForms.empty()) {
175         HILOG_ERROR("%{public}s error, targetForms is empty", __func__);
176         return false;
177     }
178 
179     FormInfo updatedForm;
180     bool bGetForm = FormDataMgr::GetInstance().GetUpdatedForm(formRecord, targetForms, updatedForm);
181     if (bGetForm) {
182         HILOG_INFO("%{public}s, form is still exist,form:%{public}s", __func__, formRecord.formName.c_str());
183         // update resource
184         FormDataMgr::GetInstance().SetNeedRefresh(formId, true);
185         FormCacheMgr::GetInstance().DeleteData(formId);
186 
187         FormBmsHelper::GetInstance().NotifyModuleNotRemovable(formRecord.bundleName, formRecord.moduleName);
188         FormTimerCfg timerCfg;
189         GetTimerCfg(updatedForm.updateEnabled, updatedForm.updateDuration,
190             updatedForm.scheduledUpdateTime, timerCfg);
191         HandleTimerUpdate(formId, formRecord, timerCfg);
192         FormDataMgr::GetInstance().SetVersionUpgrade(formId, true);
193         return true;
194     }
195     HILOG_INFO("%{public}s, no updated form.", __func__);
196     return false;
197 }
198 
ClearFormDBRecordData(const int uid,std::map<int64_t,bool> & removedFormsMap)199 void FormEventUtil::ClearFormDBRecordData(const int uid, std::map<int64_t, bool> &removedFormsMap)
200 {
201     std::map<int64_t, bool> foundFormsMap;
202     std::map<FormIdKey, std::set<int64_t>> noHostFormDbMap;
203     FormDbCache::GetInstance().GetNoHostDBForms(uid, noHostFormDbMap, foundFormsMap);
204     if (foundFormsMap.size() > 0) {
205         for (const auto &element : foundFormsMap) {
206             FormDataMgr::GetInstance().DeleteFormUserUid(element.first, uid);
207         }
208     }
209 
210     HILOG_DEBUG("%{public}s, noHostFormDbMap size:%{public}zu", __func__, noHostFormDbMap.size());
211     if (noHostFormDbMap.size() > 0) {
212         BatchDeleteNoHostDBForms(uid, noHostFormDbMap, foundFormsMap);
213     }
214 
215     if (!foundFormsMap.empty()) {
216         removedFormsMap.insert(foundFormsMap.begin(), foundFormsMap.end());
217     }
218 }
219 
ClearTempFormRecordData(const int uid,std::map<int64_t,bool> & removedFormsMap)220 void FormEventUtil::ClearTempFormRecordData(const int uid, std::map<int64_t, bool> &removedFormsMap)
221 {
222     std::map<int64_t, bool> foundFormsMap;
223     std::map<FormIdKey, std::set<int64_t>> noHostTempFormsMap;
224     FormDataMgr::GetInstance().GetNoHostTempForms(uid, noHostTempFormsMap, foundFormsMap);
225     HILOG_DEBUG("%{public}s, noHostTempFormsMap size:%{public}zu", __func__, noHostTempFormsMap.size());
226     if (noHostTempFormsMap.size() > 0) {
227         BatchDeleteNoHostTempForms(uid, noHostTempFormsMap, foundFormsMap);
228     }
229     if (!foundFormsMap.empty()) {
230         removedFormsMap.insert(foundFormsMap.begin(), foundFormsMap.end());
231     }
232 }
233 
BatchDeleteNoHostTempForms(const int uid,std::map<FormIdKey,std::set<int64_t>> & noHostTempFormsMap,std::map<int64_t,bool> & foundFormsMap)234 void FormEventUtil::BatchDeleteNoHostTempForms(const int uid, std::map<FormIdKey,
235     std::set<int64_t>> &noHostTempFormsMap, std::map<int64_t, bool> &foundFormsMap)
236 {
237     for (const auto &element : noHostTempFormsMap) {
238         std::set<int64_t> formIds = element.second;
239         FormIdKey formIdKey = element.first;
240         std::string bundleName = formIdKey.bundleName;
241         std::string abilityName = formIdKey.abilityName;
242         int result = FormProviderMgr::GetInstance().NotifyProviderFormsBatchDelete(bundleName, abilityName, formIds);
243         if (result != ERR_OK) {
244             HILOG_ERROR("%{public}s error, NotifyProviderFormsBatchDelete failed! bundleName:%{public}s,\
245             abilityName:%{public}s",
246                 __func__, bundleName.c_str(), abilityName.c_str());
247             for (int64_t formId : formIds) {
248                 FormDataMgr::GetInstance().AddFormUserUid(formId, uid);
249             }
250         } else {
251             for (int64_t formId : formIds) {
252                 foundFormsMap.emplace(formId, true);
253                 FormDataMgr::GetInstance().DeleteFormRecord(formId);
254                 FormDataMgr::GetInstance().DeleteTempForm(formId);
255             }
256         }
257     }
258 }
259 
GetTimerCfg(const bool updateEnabled,const int updateDuration,const std::string & configUpdateAt,FormTimerCfg & cfg)260 void FormEventUtil::GetTimerCfg(const bool updateEnabled,
261     const int updateDuration, const std::string &configUpdateAt, FormTimerCfg& cfg)
262 {
263     HILOG_INFO("%{public}s start", __func__);
264     if (!updateEnabled) {
265         HILOG_INFO("%{public}s, update disable", __func__);
266         return;
267     }
268 
269     if (updateDuration > 0) {
270         // interval timer
271         HILOG_INFO("%{public}s,interval timer updateDuration:%{public}d", __func__, updateDuration);
272         if (updateDuration <= Constants::MIN_CONFIG_DURATION) {
273             cfg.updateDuration = Constants::MIN_PERIOD;
274         } else if (updateDuration >= Constants::MAX_CONFIG_DURATION) {
275             cfg.updateDuration = Constants::MAX_PERIOD;
276         } else {
277             cfg.updateDuration = updateDuration * Constants::TIME_CONVERSION;
278         }
279         cfg.enableUpdate = true;
280         return;
281     } else {
282         // updateAtTimer
283         if (configUpdateAt.empty()) {
284             HILOG_INFO("%{public}s, configUpdateAt is empty", __func__);
285             return;
286         }
287         HILOG_INFO("%{public}s,update at timer updateAt:%{public}s", __func__, configUpdateAt.c_str());
288         std::vector<std::string> temp = FormUtil::StringSplit(configUpdateAt, Constants::TIME_DELIMETER);
289         if (temp.size() != Constants::UPDATE_AT_CONFIG_COUNT) {
290             HILOG_ERROR("%{public}s, invalid config", __func__);
291             return;
292         }
293         int hour = std::stoi(temp[0]);
294         int min = std::stoi(temp[1]);
295         if (hour < Constants::MIN_TIME || hour > Constants::MAX_HOUR || min < Constants::MIN_TIME || min >
296             Constants::MAX_MINUTE) {
297             HILOG_ERROR("%{public}s, time is invalid", __func__);
298             return;
299         }
300 
301         cfg.updateAtHour = hour;
302         cfg.updateAtMin = min;
303         cfg.enableUpdate = true;
304         return;
305     }
306 }
307 
HandleTimerUpdate(const int64_t formId,const FormRecord & record,const FormTimerCfg & timerCfg)308 void FormEventUtil::HandleTimerUpdate(const int64_t formId,
309     const FormRecord &record, const FormTimerCfg &timerCfg)
310 {
311     // both disable
312     if (!record.isEnableUpdate && !timerCfg.enableUpdate) {
313         return;
314     }
315 
316     // enable to disable
317     if (record.isEnableUpdate && !timerCfg.enableUpdate) {
318         FormDataMgr::GetInstance().SetEnableUpdate(formId, false);
319         FormTimerMgr::GetInstance().RemoveFormTimer(formId);
320         return;
321     }
322 
323     // disable to enable
324     if (!record.isEnableUpdate && timerCfg.enableUpdate) {
325         FormDataMgr::GetInstance().SetUpdateInfo(formId, true,
326             timerCfg.updateDuration, timerCfg.updateAtHour, timerCfg.updateAtMin);
327         if (timerCfg.updateDuration > 0) {
328             HILOG_INFO("%{public}s, add interval timer:%{public}" PRId64 "", __func__, timerCfg.updateDuration);
329             FormTimerMgr::GetInstance().AddFormTimer(formId, timerCfg.updateDuration, record.userId);
330         } else {
331             HILOG_INFO("%{public}s, add at timer:%{public}d, %{public}d", __func__,
332                 timerCfg.updateAtHour, timerCfg.updateAtMin);
333             FormTimerMgr::GetInstance().AddFormTimer(formId, timerCfg.updateAtHour,
334                                                      timerCfg.updateAtMin, record.userId);
335         }
336         return;
337     }
338 
339     // both enable
340     UpdateType type;
341     if (record.updateDuration > 0) {
342         if (timerCfg.updateDuration > 0) {
343             // no change
344             if (record.updateDuration == timerCfg.updateDuration) {
345                 return;
346             }
347             // interval change
348             type = TYPE_INTERVAL_CHANGE;
349         } else {
350             // interval to updateat
351             type = TYPE_INTERVAL_TO_ATTIME;
352         }
353     } else {
354         if (timerCfg.updateDuration > 0) {
355             // updateat to interval
356             type = TYPE_ATTIME_TO_INTERVAL;
357         } else {
358             // no change;
359             if (record.updateAtHour == timerCfg.updateAtHour && record.updateAtMin == timerCfg.updateAtMin) {
360                 return;
361             }
362             // updateat change
363             type = TYPE_ATTIME_CHANGE;
364         }
365     }
366 
367     FormDataMgr::GetInstance().SetUpdateInfo(formId, true,
368         timerCfg.updateDuration, timerCfg.updateAtHour, timerCfg.updateAtMin);
369     FormTimerMgr::GetInstance().UpdateFormTimer(formId, type, timerCfg);
370 }
371 
ReCreateForm(const int64_t formId)372 void FormEventUtil::ReCreateForm(const int64_t formId)
373 {
374     HILOG_INFO("%{public}s start, formId:%{public}" PRId64 "", __func__, formId);
375     FormRecord reCreateRecord;
376     FormRecord record;
377     bool isGetForm = FormDataMgr::GetInstance().GetFormRecord(formId, record);
378     if (!isGetForm) {
379         HILOG_ERROR("%{public}s error, not exist such form:%{public}" PRId64 "", __func__, formId);
380         return;
381     }
382     FormCacheMgr::GetInstance().DeleteData(formId);
383     reCreateRecord.bundleName = record.bundleName;
384     reCreateRecord.abilityName = record.abilityName;
385     reCreateRecord.formName = record.formName;
386     reCreateRecord.specification = record.specification;
387     reCreateRecord.formTempFlg = record.formTempFlg;
388     reCreateRecord.isInited = record.isInited;
389     reCreateRecord.versionUpgrade = record.versionUpgrade;
390 
391     Want want;
392     FormUtil::CreateFormWant(reCreateRecord.formName, reCreateRecord.specification, reCreateRecord.formTempFlg, want);
393     want.SetParam(Constants::RECREATE_FORM_KEY, true);
394     FormProviderMgr::GetInstance().ConnectAmsForRefresh(formId, reCreateRecord, want, false);
395 }
396 
BatchDeleteNoHostDBForms(const int uid,std::map<FormIdKey,std::set<int64_t>> & noHostFormDbMap,std::map<int64_t,bool> & removedFormsMap)397 void FormEventUtil::BatchDeleteNoHostDBForms(const int uid, std::map<FormIdKey,
398     std::set<int64_t>> &noHostFormDbMap, std::map<int64_t, bool> &removedFormsMap)
399 {
400     std::set<FormIdKey> removableModuleSet;
401     for (const auto &element: noHostFormDbMap) {
402         std::set<int64_t> formIds = element.second;
403         FormIdKey formIdKey = element.first;
404         std::string bundleName = formIdKey.bundleName;
405         std::string abilityName = formIdKey.abilityName;
406         int result = FormProviderMgr::GetInstance().NotifyProviderFormsBatchDelete(bundleName, abilityName, formIds);
407         if (result != ERR_OK) {
408             HILOG_ERROR("%{public}s error, NotifyProviderFormsBatchDelete failed! bundleName:%{public}s,\
409             abilityName:%{public}s",
410                 __func__, bundleName.c_str(), abilityName.c_str());
411             for (int64_t formId : formIds) {
412                 FormDBInfo dbInfo;
413                 int errCode = FormDbCache::GetInstance().GetDBRecord(formId, dbInfo);
414                 if (errCode == ERR_OK) {
415                     dbInfo.formUserUids.emplace_back(uid);
416                     FormDbCache::GetInstance().SaveFormInfo(dbInfo);
417                 }
418             }
419         } else {
420             for (const int64_t formId : formIds) {
421                 removedFormsMap.emplace(formId, true);
422                 FormDBInfo dbInfo;
423                 int errCode = FormDbCache::GetInstance().GetDBRecord(formId, dbInfo);
424                 if (errCode == ERR_OK) {
425                     FormIdKey removableModuleFormIdKey(dbInfo.bundleName, dbInfo.moduleName);
426                     removableModuleSet.emplace(removableModuleFormIdKey);
427                     FormDbCache::GetInstance().DeleteFormInfo(formId);
428                 }
429                 FormDataMgr::GetInstance().DeleteFormRecord(formId);
430             }
431         }
432     }
433 
434     for (const FormIdKey &item : removableModuleSet) {
435         int32_t matchCount = FormDbCache::GetInstance().GetMatchCount(item.bundleName, item.moduleName);
436         if (matchCount == 0) {
437             FormBmsHelper::GetInstance().NotifyModuleRemovable(item.bundleName, item.moduleName);
438         }
439     }
440 }
441 
442 } // namespace AppExecFwk
443 } // namespace OHOS