• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 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 "common/event/form_event_util.h"
17 
18 #include <regex>
19 #include <dirent.h>
20 #include "directory_ex.h"
21 
22 #include "fms_log_wrapper.h"
23 #include "bms_mgr/form_bms_helper.h"
24 #include "data_center/form_cache_mgr.h"
25 #include "data_center/form_data_mgr.h"
26 #include "data_center/form_data_proxy_mgr.h"
27 #include "data_center/database/form_db_cache.h"
28 #include "data_center/form_info/form_info_mgr.h"
29 #include "form_mgr/form_mgr_adapter.h"
30 #include "form_render/form_render_mgr.h"
31 #include "common/timer_mgr/form_timer_mgr.h"
32 #include "common/util/form_trust_mgr.h"
33 #include "common/util/form_util.h"
34 #include "form_provider/form_provider_mgr.h"
35 #include "want.h"
36 #include "feature/bundle_distributed/form_distributed_mgr.h"
37 
38 namespace OHOS {
39 namespace AppExecFwk {
40 namespace {
41 constexpr int NORMAL_BUNDLE_MODULE_LENGTH = 1;
42 
UpdateRecordByBundleInfo(const BundleInfo & bundleInfo,FormRecord & formRecord)43 void UpdateRecordByBundleInfo(const BundleInfo &bundleInfo, FormRecord &formRecord)
44 {
45     formRecord.modulePkgNameMap.clear();
46     if (!bundleInfo.hapModuleInfos.empty()) {
47         for (auto hapModuleInfo : bundleInfo.hapModuleInfos) {
48             auto hapPath = hapModuleInfo.hapPath;
49             auto moduleName = hapModuleInfo.moduleName;
50             HILOG_INFO("update record %{public}" PRId64 ". packageName is %{public}s, hap path is %{public}s, "
51                 "jsFormCodePath:%{public}s", formRecord.formId, hapModuleInfo.packageName.c_str(), hapPath.c_str(),
52                 formRecord.jsFormCodePath.c_str());
53             if (hapPath.find(Constants::ABS_CODE_PATH) != std::string::npos) {
54                 hapPath = std::regex_replace(hapPath, std::regex(Constants::ABS_CODE_PATH), Constants::LOCAL_BUNDLES);
55             }
56             nlohmann::json moduleInfos = {
57                 {Constants::MODULE_PKG_NAME_KEY, hapModuleInfo.packageName},
58                 {Constants::MODULE_HAP_PATH_KEY, hapPath}
59             };
60             formRecord.modulePkgNameMap.emplace(std::make_pair(moduleName, moduleInfos.dump()));
61             if ((formRecord.isDistributedForm && moduleName == formRecord.uiModule) ||
62                 (!formRecord.isDistributedForm && moduleName == formRecord.moduleName)) {
63                 HILOG_INFO("update jsFormCodePath, isDistributedForm:%{public}d", formRecord.isDistributedForm);
64                 formRecord.jsFormCodePath = hapPath;
65             }
66         }
67     }
68 
69     formRecord.hapSourceDirs.clear();
70     for (const auto &item : bundleInfo.applicationInfo.moduleInfos) {
71         if (formRecord.moduleName == item.moduleName) {
72             formRecord.hapSourceDirs.emplace_back(item.moduleSourceDir);
73         }
74     }
75 }
76 }
HandleBundleFormInfoChanged(const std::string & bundleName,int32_t userId)77 void FormEventUtil::HandleBundleFormInfoChanged(const std::string &bundleName, int32_t userId)
78 {
79     FormTrustMgr::GetInstance().MarkTrustFlag(bundleName, true);
80     FormInfoMgr::GetInstance().UpdateStaticFormInfos(bundleName, userId);
81 }
82 
HandleUpdateFormCloud(const std::string & bundleName)83 void FormEventUtil::HandleUpdateFormCloud(const std::string &bundleName)
84 {
85     FormMgrAdapter::GetInstance().UpdateFormCloudUpdateDuration(bundleName);
86 }
87 
HandleProviderUpdated(const std::string & bundleName,const int userId)88 void FormEventUtil::HandleProviderUpdated(const std::string &bundleName, const int userId)
89 {
90     HILOG_WARN("bundleName:%{public}s, userId:%{public}d", bundleName.c_str(), userId);
91     std::vector<FormRecord> formInfos;
92     if (!FormDataMgr::GetInstance().GetFormRecord(bundleName, formInfos, userId)) {
93         return;
94     }
95 
96     std::vector<FormInfo> targetForms;
97     if (FormInfoMgr::GetInstance().GetFormsInfoByBundle(bundleName, targetForms, userId) != ERR_OK) {
98         return;
99     }
100 
101     BundlePackInfo bundlePackInfo;
102     bool hasPackInfo = FormBmsHelper::GetInstance().GetBundlePackInfo(bundleName, userId, bundlePackInfo);
103     HILOG_INFO("bundleName:%{public}s, hasPackInfo:%{public}d", bundleName.c_str(), hasPackInfo);
104     BundleInfo bundleInfo;
105     if (FormBmsHelper::GetInstance().GetBundleInfoV9(bundleName, userId, bundleInfo) != ERR_OK) {
106         HILOG_ERROR("get bundleInfo failed");
107         return;
108     }
109     std::vector<int64_t> removedForms;
110     std::vector<FormRecord> updatedForms;
111     bool isBundleDistributed = FormDistributedMgr::GetInstance().IsBundleDistributed(bundleInfo.name, userId);
112     for (FormRecord& formRecord : formInfos) {
113         int64_t formId = formRecord.formId;
114         HILOG_INFO("bundle update, formName:%{public}s, moduleName:%{public}s, isDistributedForm:%{public}d, "
115             "isBundleDistributed:%{public}d, formId:%{public}" PRId64, formRecord.formName.c_str(),
116             formRecord.moduleName.c_str(), formRecord.isDistributedForm, isBundleDistributed, formId);
117         if (bundleInfo.versionCode == formRecord.versionCode && formRecord.isDistributedForm == isBundleDistributed) {
118             HILOG_WARN("form: %{public}s, versionCode is same and no package format change. formId:%{public}" PRId64,
119                        formRecord.formName.c_str(), formId);
120             continue;
121         }
122 
123         formRecord.versionCode = bundleInfo.versionCode;
124         if (ProviderFormUpdated(formId, formRecord, targetForms, bundleInfo)) {
125             updatedForms.emplace_back(formRecord);
126             continue;
127         }
128         if (hasPackInfo && ProviderFormUpdated(formId, formRecord, bundlePackInfo, bundleInfo)) {
129             updatedForms.emplace_back(formRecord);
130             continue;
131         }
132 
133         if (formRecord.formTempFlag) {
134             FormDataMgr::GetInstance().DeleteTempForm(formId);
135         } else {
136             FormDbCache::GetInstance().DeleteFormInfo(formId);
137         }
138         HILOG_WARN(
139             "delete form record, formName:%{public}s, formId:%{public}" PRId64, formRecord.formName.c_str(), formId);
140         removedForms.emplace_back(formId);
141         FormDataMgr::GetInstance().DeleteFormRecord(formId);
142         FormRenderMgr::GetInstance().StopRenderingForm(formId, formRecord);
143         FormDataProxyMgr::GetInstance().UnsubscribeFormData(formId);
144     }
145 
146     if (!removedForms.empty()) {
147         HILOG_INFO("clean removed forms and timer");
148         FormDataMgr::GetInstance().CleanHostRemovedForms(removedForms);
149         for (const int64_t id : removedForms) {
150             FormTimerMgr::GetInstance().RemoveFormTimer(id);
151         }
152     }
153 
154     Want want;
155     want.SetParam(Constants::PARAM_FORM_USER_ID, userId);
156     want.SetParam(Constants::FORM_ENABLE_UPDATE_REFRESH_KEY, true);
157     want.SetParam(Constants::FORM_DATA_UPDATE_TYPE, Constants::FULL_UPDATE);
158     FormMgrAdapter::GetInstance().DelayRefreshForms(updatedForms, want);
159     FormRenderMgr::GetInstance().ReloadForm(std::move(updatedForms), bundleName, userId);
160 }
161 
HandleOnUnlock(int32_t userId)162 void FormEventUtil::HandleOnUnlock(int32_t userId)
163 {
164     FormRenderMgr::GetInstance().OnUnlock(userId);
165 }
166 
HandleBundleFormInfoRemoved(const std::string & bundleName,int32_t userId)167 void FormEventUtil::HandleBundleFormInfoRemoved(const std::string &bundleName, int32_t userId)
168 {
169     FormTrustMgr::GetInstance().MarkTrustFlag(bundleName, true);
170     FormInfoMgr::GetInstance().Remove(bundleName, userId);
171     FormDataMgr::GetInstance().RemoveFormCloudUpdateDuration(bundleName);
172 }
173 
HandleProviderRemoved(const std::string & bundleName,const int32_t userId)174 void FormEventUtil::HandleProviderRemoved(const std::string &bundleName, const int32_t userId)
175 {
176     HILOG_INFO("bundleName:%{public}s, userId:%{public}d", bundleName.c_str(), userId);
177     // clean removed form in DB
178     std::set<int64_t> removedForms;
179     std::vector<FormDBInfo> removedDBForm;
180     FormDbCache::GetInstance().DeleteFormInfoByBundleName(bundleName, userId, removedDBForm);
181     for (const auto &dbForm : removedDBForm) {
182         removedForms.emplace(dbForm.formId);
183         int32_t matchCount = FormDbCache::GetInstance().GetMatchCount(dbForm.bundleName, dbForm.moduleName);
184         if (matchCount == 0) {
185             FormBmsHelper::GetInstance().NotifyModuleRemovable(dbForm.bundleName, dbForm.moduleName);
186         }
187     }
188     // clean removed form in FormRecords
189     FormDataMgr::GetInstance().CleanRemovedFormRecords(bundleName, removedForms);
190     // clean removed temp form in FormRecords
191     FormDataMgr::GetInstance().CleanRemovedTempFormRecords(bundleName, userId, removedForms);
192     // clean removed forms in FormHostRecords
193     std::vector<int64_t> vRemovedForms;
194     vRemovedForms.assign(removedForms.begin(), removedForms.end());
195     FormDataMgr::GetInstance().CleanHostRemovedForms(vRemovedForms);
196     // clean removed form timers
197     for (auto &formId : removedForms) {
198         FormTimerMgr::GetInstance().RemoveFormTimer(formId);
199         FormDataProxyMgr::GetInstance().UnsubscribeFormData(formId);
200     }
201 
202     FormRenderMgr::GetInstance().DeleteAcquireForbiddenTasksByBundleName(bundleName);
203 }
204 
HandleBundleDataCleared(const std::string & bundleName,int32_t userId)205 void FormEventUtil::HandleBundleDataCleared(const std::string &bundleName, int32_t userId)
206 {
207     HILOG_WARN("bundleName:%{public}s, userId:%{public}d", bundleName.c_str(), userId);
208     // clear dynamic form info
209     FormInfoMgr::GetInstance().RemoveAllDynamicFormsInfo(bundleName, userId);
210 
211     // as provider data is cleared
212     std::set<int64_t> reCreateForms;
213     FormDataMgr::GetInstance().GetReCreateFormRecordsByBundleName(bundleName, reCreateForms);
214     if (!reCreateForms.empty()) {
215         for (int64_t formId : reCreateForms) {
216             ReCreateForm(formId);
217         }
218     }
219 
220     int32_t uid = FormBmsHelper::GetInstance().GetUidByBundleName(bundleName, userId);
221     if (uid == FormBmsHelper::INVALID_UID) {
222         HILOG_ERROR("invalid uid");
223         return;
224     }
225     // as form host data is cleared
226     HandleFormHostDataCleared(uid);
227 }
228 
HandleFormHostDataCleared(const int uid)229 void FormEventUtil::HandleFormHostDataCleared(const int uid)
230 {
231     HILOG_DEBUG("uid:%{public}d", uid);
232     std::map<int64_t, bool> removedFormsMap;
233     // clear formDBRecord
234     ClearFormDBRecordData(uid, removedFormsMap);
235 
236     // clear temp form
237     ClearTempFormRecordData(uid, removedFormsMap);
238 
239     // clear host data
240     FormDataMgr::GetInstance().ClearHostDataByUId(uid);
241 
242     // delete forms timer
243     for (const auto &removedForm : removedFormsMap) {
244         if (removedForm.second) {
245             FormTimerMgr::GetInstance().RemoveFormTimer(removedForm.first);
246         }
247     }
248 }
249 
ProviderFormUpdated(const int64_t formId,FormRecord & formRecord,const std::vector<FormInfo> & targetForms,const BundleInfo & bundleInfo)250 bool FormEventUtil::ProviderFormUpdated(const int64_t formId, FormRecord &formRecord,
251     const std::vector<FormInfo> &targetForms, const BundleInfo &bundleInfo)
252 {
253     HILOG_INFO("start");
254     if (targetForms.empty()) {
255         HILOG_ERROR("empty targetForms");
256         return false;
257     }
258 
259     bool isBundleDistributed =
260         FormDistributedMgr::GetInstance().IsBundleDistributed(bundleInfo.name, formRecord.providerUserId);
261     HILOG_INFO("bundleName: %{public}s, isBundleDistributed: %{public}d, formId:%{public}" PRId64,
262         bundleInfo.name.c_str(), isBundleDistributed, formId);
263     if (formRecord.isDistributedForm != isBundleDistributed) {
264         // The format of the installation package has changed.
265         if (!isBundleDistributed || bundleInfo.hapModuleInfos.size() > NORMAL_BUNDLE_MODULE_LENGTH) {
266             // whole package install finished
267             formRecord.isDistributedForm = isBundleDistributed;
268             formRecord.uiModule =
269                 FormDistributedMgr::GetInstance().GetUiModuleName(bundleInfo.name, formRecord.providerUserId);
270             HILOG_INFO("form pack format change, uiModule:%{public}s", formRecord.uiModule.c_str());
271         }
272     }
273 
274     FormInfo updatedForm;
275     bool bGetForm = FormDataMgr::GetInstance().GetUpdatedForm(formRecord, targetForms, updatedForm);
276     if (!bGetForm) {
277         HILOG_INFO("no updated form");
278         return false;
279     }
280     HILOG_INFO("form is still exist, form:%{public}s, formId:%{public}" PRId64 ", isDataProxy: %{public}d",
281         formRecord.formName.c_str(), formId, formRecord.isDataProxy);
282 
283     // update resource
284     if (!formRecord.isDataProxy) {
285         FormCacheMgr::GetInstance().DeleteData(formId);
286     }
287     FormDataMgr::GetInstance().SetNeedRefresh(formId, true);
288     FormBmsHelper::GetInstance().NotifyModuleNotRemovable(formRecord.bundleName, formRecord.moduleName);
289     FormTimerCfg timerCfg;
290     GetTimerCfg(updatedForm.updateEnabled, updatedForm.updateDuration, updatedForm.scheduledUpdateTime, timerCfg);
291     SetTimerCfgByMultUpdate(updatedForm.multiScheduledUpdateTime, timerCfg);
292     HandleTimerUpdate(formId, formRecord, timerCfg);
293     UpdateRecordByBundleInfo(bundleInfo, formRecord);
294     UpdateFormRecord(updatedForm, formRecord);
295     FormDataMgr::GetInstance().SetVersionUpgrade(formId, true);
296     return true;
297 }
298 
ProviderFormUpdated(const int64_t formId,FormRecord & formRecord,const BundlePackInfo & bundlePackInfo,const BundleInfo & bundleInfo)299 bool FormEventUtil::ProviderFormUpdated(const int64_t formId, FormRecord &formRecord,
300     const BundlePackInfo &bundlePackInfo, const BundleInfo &bundleInfo)
301 {
302     HILOG_INFO("start");
303     AbilityFormInfo packForm;
304     if (!FormDataMgr::GetInstance().GetPackageForm(formRecord, bundlePackInfo, packForm)) {
305         HILOG_INFO("no updated form");
306         return false;
307     }
308 
309     HILOG_INFO("form is still in package info, form:%{public}s", formRecord.formName.c_str());
310     FormDataMgr::GetInstance().SetRecordNeedFreeInstall(formId, true);
311     FormTimerCfg timerCfg;
312     GetTimerCfg(packForm.updateEnabled, packForm.updateDuration, packForm.scheduledUpdateTime, timerCfg);
313     SetTimerCfgByMultUpdate(packForm.multiScheduledUpdateTime, timerCfg);
314     HandleTimerUpdate(formId, formRecord, timerCfg);
315     UpdateRecordByBundleInfo(bundleInfo, formRecord);
316     UpdateFormRecord(packForm, formRecord);
317     FormDataMgr::GetInstance().SetVersionUpgrade(formId, true);
318     return true;
319 }
320 
ClearFormDBRecordData(const int uid,std::map<int64_t,bool> & removedFormsMap)321 void FormEventUtil::ClearFormDBRecordData(const int uid, std::map<int64_t, bool> &removedFormsMap)
322 {
323     std::map<int64_t, bool> foundFormsMap;
324     std::map<FormIdKey, std::set<int64_t>> noHostFormDbMap;
325     FormDbCache::GetInstance().GetNoHostDBForms(uid, noHostFormDbMap, foundFormsMap);
326     if (!foundFormsMap.empty()) {
327         for (const auto &element : foundFormsMap) {
328             FormDataMgr::GetInstance().DeleteFormUserUid(element.first, uid);
329         }
330     }
331 
332     HILOG_DEBUG("noHostFormDbMap size:%{public}zu", noHostFormDbMap.size());
333     if (!noHostFormDbMap.empty()) {
334         BatchDeleteNoHostDBForms(uid, noHostFormDbMap, foundFormsMap);
335     }
336 
337     if (!foundFormsMap.empty()) {
338         removedFormsMap.insert(foundFormsMap.begin(), foundFormsMap.end());
339     }
340 }
341 
ClearTempFormRecordData(const int uid,std::map<int64_t,bool> & removedFormsMap)342 void FormEventUtil::ClearTempFormRecordData(const int uid, std::map<int64_t, bool> &removedFormsMap)
343 {
344     std::map<int64_t, bool> foundFormsMap;
345     std::map<FormIdKey, std::set<int64_t>> noHostTempFormsMap;
346     FormDataMgr::GetInstance().GetNoHostTempForms(uid, noHostTempFormsMap, foundFormsMap);
347     HILOG_DEBUG("noHostTempFormsMap size:%{public}zu", noHostTempFormsMap.size());
348     if (!noHostTempFormsMap.empty()) {
349         BatchDeleteNoHostTempForms(uid, noHostTempFormsMap, foundFormsMap);
350     }
351     if (!foundFormsMap.empty()) {
352         removedFormsMap.insert(foundFormsMap.begin(), foundFormsMap.end());
353     }
354 }
355 
BatchDeleteNoHostTempForms(const int uid,std::map<FormIdKey,std::set<int64_t>> & noHostTempFormsMap,std::map<int64_t,bool> & foundFormsMap)356 void FormEventUtil::BatchDeleteNoHostTempForms(const int uid, std::map<FormIdKey,
357     std::set<int64_t>> &noHostTempFormsMap, std::map<int64_t, bool> &foundFormsMap)
358 {
359     for (const auto &element : noHostTempFormsMap) {
360         std::set<int64_t> formIds = element.second;
361         FormIdKey formIdKey = element.first;
362         std::string bundleName = formIdKey.bundleName;
363         std::string abilityName = formIdKey.abilityName;
364         int result = FormProviderMgr::GetInstance().NotifyProviderFormsBatchDelete(bundleName, abilityName, formIds);
365         if (result != ERR_OK) {
366             HILOG_ERROR("NotifyProviderFormsBatchDelete fail bundle:%{public}s ability:%{public}s",
367                 bundleName.c_str(), abilityName.c_str());
368             for (int64_t formId : formIds) {
369                 FormDataMgr::GetInstance().AddFormUserUid(formId, uid);
370             }
371         } else {
372             for (int64_t formId : formIds) {
373                 foundFormsMap.emplace(formId, true);
374                 FormDataMgr::GetInstance().DeleteFormRecord(formId);
375                 FormDataMgr::GetInstance().DeleteTempForm(formId);
376             }
377         }
378     }
379 }
380 
GetTimerCfg(const bool updateEnabled,const int updateDuration,const std::string & configUpdateAt,FormTimerCfg & cfg)381 void FormEventUtil::GetTimerCfg(const bool updateEnabled,
382     const int updateDuration, const std::string &configUpdateAt, FormTimerCfg& cfg)
383 {
384     HILOG_INFO("start");
385     if (!updateEnabled) {
386         HILOG_INFO("update disable");
387         return;
388     }
389 
390     if (updateDuration > 0) {
391         // interval timer
392         HILOG_INFO("interval timer updateDuration:%{public}d", updateDuration);
393         if (updateDuration <= Constants::MIN_CONFIG_DURATION) {
394             cfg.updateDuration = Constants::MIN_PERIOD;
395         } else if (updateDuration >= Constants::MAX_CONFIG_DURATION) {
396             cfg.updateDuration = Constants::MAX_PERIOD;
397         } else {
398             cfg.updateDuration = updateDuration * Constants::TIME_CONVERSION;
399         }
400         cfg.enableUpdate = true;
401         return;
402     } else {
403         // updateAtTimer
404         if (configUpdateAt.empty()) {
405             HILOG_INFO("empty configUpdateAt");
406             return;
407         }
408         HILOG_INFO("update at timer:%{public}s", configUpdateAt.c_str());
409         std::vector<std::string> temp = FormUtil::StringSplit(configUpdateAt, Constants::TIME_DELIMETER);
410         if (temp.size() != Constants::UPDATE_AT_CONFIG_COUNT) {
411             HILOG_ERROR("invalid config");
412             return;
413         }
414         int hour = FormUtil::ConvertStringToInt(temp[0]);
415         int min = FormUtil::ConvertStringToInt(temp[1]);
416         if (hour < Constants::MIN_TIME || hour > Constants::MAX_HOUR || min < Constants::MIN_TIME || min >
417             Constants::MAX_MINUTE) {
418             HILOG_ERROR("invalid time");
419             return;
420         }
421 
422         cfg.updateAtHour = hour;
423         cfg.updateAtMin = min;
424         cfg.enableUpdate = true;
425         return;
426     }
427 }
428 
SetTimerCfgByMultUpdate(const std::string & configMultUpdateAt,FormTimerCfg & cfg)429 void FormEventUtil::SetTimerCfgByMultUpdate(const std::string &configMultUpdateAt, FormTimerCfg& cfg)
430 {
431     if (configMultUpdateAt.empty()) {
432         return;
433     }
434     std::vector<std::string> timeList = FormUtil::StringSplit(configMultUpdateAt, Constants::TIMES_DELIMETER);
435     if (timeList.size() > Constants::UPDATE_AT_CONFIG_MAX_COUNT) {
436         HILOG_ERROR("invalid config");
437         return;
438     }
439     std::vector<std::vector<int>> updateAtTimes;
440     for (const auto &time: timeList) {
441         std::vector<std::string> temp = FormUtil::StringSplit(time, Constants::TIME_DELIMETER);
442         if (temp.size() != Constants::UPDATE_AT_CONFIG_COUNT) {
443             HILOG_ERROR("invalid config");
444             continue;
445         }
446         int hour = FormUtil::ConvertStringToInt(temp[0]);
447         int min = FormUtil::ConvertStringToInt(temp[1]);
448         if (hour < Constants::MIN_TIME || hour > Constants::MAX_HOUR || min < Constants::MIN_TIME || min >
449             Constants::MAX_MINUTE) {
450             HILOG_ERROR("invalid time");
451             continue;
452         }
453         std::vector<int> newElement = {hour, min};
454         updateAtTimes.push_back(newElement);
455     }
456     if (updateAtTimes.size() > 0) {
457         cfg.updateAtTimes = updateAtTimes;
458         cfg.enableUpdate = true;
459     }
460 }
461 
HandleAddMultiUpdateTimes(const int64_t formId,const FormRecord & record,const FormTimerCfg & timerCfg)462 void FormEventUtil::HandleAddMultiUpdateTimes(const int64_t formId,
463     const FormRecord &record, const FormTimerCfg &timerCfg)
464 {
465     std::vector<std::vector<int>> updateAtTimes = timerCfg.updateAtTimes;
466     if (updateAtTimes.size() > 0) {
467         for (const auto &time: updateAtTimes) {
468             HILOG_INFO("add at timer:%{public}d,%{public}d", time[0], time[1]);
469             FormTimerMgr::GetInstance().AddFormTimer(formId,
470                 time[0], time[1], record.providerUserId);
471         }
472     } else {
473         HILOG_INFO("add at timer:%{public}d,%{public}d", timerCfg.updateAtHour, timerCfg.updateAtMin);
474         FormTimerMgr::GetInstance().AddFormTimer(formId, timerCfg.updateAtHour,
475             timerCfg.updateAtMin, record.providerUserId);
476     }
477 }
478 
HandleTimerUpdate(const int64_t formId,const FormRecord & record,const FormTimerCfg & timerCfg)479 void FormEventUtil::HandleTimerUpdate(const int64_t formId,
480     const FormRecord &record, const FormTimerCfg &timerCfg)
481 {
482     // both disable
483     if (!record.isEnableUpdate && !timerCfg.enableUpdate) {
484         return;
485     }
486 
487     // enable to disable
488     if (record.isEnableUpdate && !timerCfg.enableUpdate) {
489         FormDataMgr::GetInstance().SetEnableUpdate(formId, false);
490         FormTimerMgr::GetInstance().RemoveFormTimer(formId);
491         return;
492     }
493 
494     // disable to enable
495     if (!record.isEnableUpdate && timerCfg.enableUpdate) {
496         FormDataMgr::GetInstance().SetUpdateInfo(formId, true,
497             timerCfg.updateDuration, timerCfg.updateAtHour, timerCfg.updateAtMin, timerCfg.updateAtTimes);
498         if (timerCfg.updateDuration > 0) {
499             HILOG_INFO("add interval timer:%{public}" PRId64, timerCfg.updateDuration);
500             int64_t updateDuration = timerCfg.updateDuration;
501             if (!FormMgrAdapter::GetInstance().GetValidFormUpdateDuration(formId, updateDuration)) {
502                 HILOG_WARN("Get updateDuration failed, uses local configuration");
503             }
504             FormTimerMgr::GetInstance().AddFormTimer(formId, updateDuration, record.providerUserId);
505         } else {
506             HandleAddMultiUpdateTimes(formId, record, timerCfg);
507         }
508         return;
509     }
510 
511     // both enable
512     UpdateType type = GetUpdateType(record, timerCfg);
513     if (type == TYPE_NO_CHANGE) {
514         return;
515     }
516 
517     FormDataMgr::GetInstance().SetUpdateInfo(formId, true,
518         timerCfg.updateDuration, timerCfg.updateAtHour, timerCfg.updateAtMin, timerCfg.updateAtTimes);
519     auto newTimerCfg = timerCfg;
520     if (type == TYPE_INTERVAL_CHANGE || type == TYPE_ATTIME_TO_INTERVAL) {
521         int64_t updateDuration = timerCfg.updateDuration;
522         if (!FormMgrAdapter::GetInstance().GetValidFormUpdateDuration(formId, updateDuration)) {
523             HILOG_WARN("Get updateDuration failed, uses local configuration");
524         }
525         newTimerCfg.updateDuration = updateDuration;
526     }
527     FormTimerMgr::GetInstance().UpdateFormTimer(formId, type, newTimerCfg);
528 }
529 
GetUpdateType(const FormRecord & record,const FormTimerCfg & timerCfg)530 UpdateType FormEventUtil::GetUpdateType(const FormRecord &record, const FormTimerCfg &timerCfg)
531 {
532     HILOG_DEBUG("call");
533     if (record.updateDuration > 0) {
534         if (timerCfg.updateDuration > 0) {
535             // no change
536             if (record.updateDuration == timerCfg.updateDuration) {
537                 return TYPE_NO_CHANGE;
538             }
539             // interval change
540             return TYPE_INTERVAL_CHANGE;
541         } else {
542             // interval to update at time
543             return TYPE_INTERVAL_TO_ATTIME;
544         }
545     } else {
546         if (timerCfg.updateDuration > 0) {
547             // update at time to interval
548             return TYPE_ATTIME_TO_INTERVAL;
549         } else {
550             if (record.updateAtHour == timerCfg.updateAtHour && record.updateAtMin == timerCfg.updateAtMin
551                 && record.updateAtTimes == timerCfg.updateAtTimes) {
552                 return TYPE_NO_CHANGE;
553             }
554             // update at time change
555             return TYPE_ATTIME_CHANGE;
556         }
557     }
558 }
559 
ReCreateForm(const int64_t formId)560 void FormEventUtil::ReCreateForm(const int64_t formId)
561 {
562     HILOG_INFO("formId:%{public}" PRId64, formId);
563     FormRecord record;
564     bool isGetForm = FormDataMgr::GetInstance().GetFormRecord(formId, record);
565     if (!isGetForm) {
566         HILOG_ERROR("not exist such form:%{public}" PRId64 "", formId);
567         return;
568     }
569     FormCacheMgr::GetInstance().DeleteData(formId);
570     FormRecord reCreateRecord;
571     reCreateRecord.bundleName = record.bundleName;
572     reCreateRecord.abilityName = record.abilityName;
573     reCreateRecord.formName = record.formName;
574     reCreateRecord.specification = record.specification;
575     reCreateRecord.formTempFlag = record.formTempFlag;
576     reCreateRecord.isInited = record.isInited;
577     reCreateRecord.versionUpgrade = record.versionUpgrade;
578     reCreateRecord.isCountTimerRefresh = false;
579     reCreateRecord.formId = record.formId;
580     reCreateRecord.providerUserId = record.providerUserId;
581 
582     Want want;
583     want.SetParam(Constants::PARAM_FORM_NAME_KEY, reCreateRecord.formName);
584     want.SetParam(Constants::PARAM_FORM_DIMENSION_KEY, reCreateRecord.specification);
585     want.SetParam(Constants::PARAM_FORM_TEMPORARY_KEY, reCreateRecord.formTempFlag);
586     want.SetParam(Constants::RECREATE_FORM_KEY, true);
587     want.SetParam(Constants::PARAM_FORM_RENDERINGMODE_KEY, (int)record.renderingMode);
588     want.SetParam(Constants::PARAM_FORM_IDENTITY_KEY, reCreateRecord.formId);
589     want.SetParam(Constants::PARAM_FORM_WIDTH_KEY, reCreateRecord.wantCacheMap[formId].
590         GetDoubleParam(Constants::PARAM_FORM_WIDTH_KEY, 0));
591     want.SetParam(Constants::PARAM_FORM_HEIGHT_KEY, reCreateRecord.wantCacheMap[formId].
592         GetDoubleParam(Constants::PARAM_FORM_HEIGHT_KEY, 0));
593 
594     FormProviderMgr::GetInstance().ConnectAmsForRefresh(formId, reCreateRecord, want);
595 }
596 
BatchDeleteNoHostDBForms(const int uid,std::map<FormIdKey,std::set<int64_t>> & noHostFormDbMap,std::map<int64_t,bool> & removedFormsMap)597 void FormEventUtil::BatchDeleteNoHostDBForms(const int uid, std::map<FormIdKey, std::set<int64_t>> &noHostFormDbMap,
598     std::map<int64_t, bool> &removedFormsMap)
599 {
600     std::set<FormIdKey> removableModuleSet;
601     for (const auto &element: noHostFormDbMap) {
602         std::set<int64_t> formIds = element.second;
603         FormIdKey formIdKey = element.first;
604         std::string bundleName = formIdKey.bundleName;
605         std::string abilityName = formIdKey.abilityName;
606         int result = FormProviderMgr::GetInstance().NotifyProviderFormsBatchDelete(bundleName, abilityName, formIds);
607         if (result != ERR_OK) {
608             HILOG_ERROR("NotifyProviderFormsBatchDelete fail bundle:%{public}s ability:%{public}s",
609                 bundleName.c_str(), abilityName.c_str());
610             for (int64_t formId : formIds) {
611                 FormDBInfo dbInfo;
612                 int errCode = FormDbCache::GetInstance().GetDBRecord(formId, dbInfo);
613                 if (errCode == ERR_OK) {
614                     dbInfo.formUserUids.emplace_back(uid);
615                     FormDbCache::GetInstance().SaveFormInfo(dbInfo);
616                 }
617             }
618         } else {
619             for (const int64_t formId : formIds) {
620                 removedFormsMap.emplace(formId, true);
621                 FormDBInfo dbInfo;
622                 int errCode = FormDbCache::GetInstance().GetDBRecord(formId, dbInfo);
623                 if (errCode == ERR_OK) {
624                     FormIdKey removableModuleFormIdKey(dbInfo.bundleName, dbInfo.moduleName);
625                     removableModuleSet.emplace(removableModuleFormIdKey);
626                     FormDbCache::GetInstance().DeleteFormInfo(formId);
627                 }
628                 FormDataMgr::GetInstance().DeleteFormRecord(formId);
629             }
630         }
631     }
632 
633     for (const FormIdKey &item : removableModuleSet) {
634         int32_t matchCount = FormDbCache::GetInstance().GetMatchCount(item.bundleName, item.moduleName);
635         if (matchCount == 0) {
636             FormBmsHelper::GetInstance().NotifyModuleRemovable(item.bundleName, item.moduleName);
637         }
638     }
639 }
640 
HandleAdditionalInfoChanged(const std::string & bundleName)641 bool FormEventUtil::HandleAdditionalInfoChanged(const std::string &bundleName)
642 {
643     HILOG_DEBUG("Call, bundleName:%{public}s", bundleName.c_str());
644     FormMgrAdapter::GetInstance().UpdateFormCloudUpdateDuration(bundleName);
645     std::vector<FormRecord> formInfos;
646     if (!FormDataMgr::GetInstance().GetFormRecord(bundleName, formInfos)) {
647         HILOG_DEBUG("No form info");
648         return false;
649     }
650 
651     for (const auto& formRecord : formInfos) {
652         if (!formRecord.isEnableUpdate || (formRecord.updateDuration <= 0)) {
653             continue;
654         }
655         int64_t updateDuration = formRecord.updateDuration;
656         if (!FormMgrAdapter::GetInstance().GetValidFormUpdateDuration(formRecord.formId, updateDuration)) {
657             HILOG_WARN("Get updateDuration failed, uses local configuration");
658         }
659 
660         FormTimerCfg timerCfg;
661         timerCfg.enableUpdate = true;
662         timerCfg.updateDuration = updateDuration;
663         FormTimerMgr::GetInstance().UpdateFormTimer(formRecord.formId, UpdateType::TYPE_INTERVAL_CHANGE, timerCfg);
664     }
665     return true;
666 }
667 
668 
UpdateMultiUpdateTime(std::string multiScheduledUpdateTime,FormRecord & formRecord)669 void FormEventUtil::UpdateMultiUpdateTime(std::string multiScheduledUpdateTime, FormRecord &formRecord)
670 {
671     std::vector<std::string> timeList = FormUtil::StringSplit(multiScheduledUpdateTime,
672         Constants::TIMES_DELIMETER);
673     if (timeList.size() > Constants::UPDATE_AT_CONFIG_MAX_COUNT) {
674         HILOG_ERROR("invalid config");
675         return;
676     }
677 
678     std::vector<std::vector<int>> updateAtTimes;
679     for (const auto &time: timeList) {
680         HILOG_INFO("UpdateFormRecord add  updateAtTimes");
681         std::vector<std::string> temp = FormUtil::StringSplit(time, Constants::TIME_DELIMETER);
682         if (temp.size() != Constants::UPDATE_AT_CONFIG_COUNT) {
683             HILOG_ERROR("invalid config");
684             continue;
685         }
686         int hour = FormUtil::ConvertStringToInt(temp[0]);
687         int min = FormUtil::ConvertStringToInt(temp[1]);
688         if (hour < Constants::MIN_TIME || hour > Constants::MAX_HOUR || min < Constants::MIN_TIME || min >
689             Constants::MAX_MINUTE) {
690             HILOG_ERROR("invalid time");
691             continue;
692         }
693         std::vector<int> newElement = {hour, min};
694         updateAtTimes.push_back(newElement);
695     }
696     if (updateAtTimes.size() > 0) {
697         formRecord.updateAtTimes = updateAtTimes;
698     }
699 }
700 
UpdateFormRecord(const FormInfo & formInfo,FormRecord & formRecord)701 void FormEventUtil::UpdateFormRecord(const FormInfo &formInfo, FormRecord &formRecord)
702 {
703     formRecord.formSrc = formInfo.src;
704     formRecord.uiSyntax = formInfo.uiSyntax;
705     formRecord.isDynamic = formInfo.isDynamic;
706     formRecord.transparencyEnabled = formInfo.transparencyEnabled;
707     formRecord.privacyLevel = formInfo.privacyLevel;
708     formRecord.isEnableUpdate = formInfo.updateEnabled;
709     formRecord.updateDuration = formInfo.updateDuration * Constants::TIME_CONVERSION;
710     std::vector<std::string> time = FormUtil::StringSplit(formInfo.scheduledUpdateTime, Constants::TIME_DELIMETER);
711     if (time.size() == Constants::UPDATE_AT_CONFIG_COUNT) {
712         formRecord.updateAtHour = FormUtil::ConvertStringToInt(time[0]);
713         formRecord.updateAtMin = FormUtil::ConvertStringToInt(time[1]);
714     }
715     std::string multiScheduledUpdateTime_ = formInfo.multiScheduledUpdateTime;
716     if (!multiScheduledUpdateTime_.empty()) {
717         UpdateMultiUpdateTime(multiScheduledUpdateTime_, formRecord);
718     }
719     HILOG_DEBUG("formId:%{public}" PRId64 "", formRecord.formId);
720     FormDataMgr::GetInstance().UpdateFormRecord(formRecord.formId, formRecord);
721 }
722 
UpdateFormRecord(const AbilityFormInfo & formInfo,FormRecord & formRecord)723 void FormEventUtil::UpdateFormRecord(const AbilityFormInfo &formInfo, FormRecord &formRecord)
724 {
725     formRecord.uiSyntax = (formInfo.type.compare("arkts") == 0 ? FormType::ETS : FormType::JS);
726     formRecord.isEnableUpdate = formInfo.updateEnabled;
727     formRecord.updateDuration = formInfo.updateDuration * Constants::TIME_CONVERSION;
728     std::vector<std::string> time = FormUtil::StringSplit(formInfo.scheduledUpdateTime, Constants::TIME_DELIMETER);
729     if (time.size() == Constants::UPDATE_AT_CONFIG_COUNT) {
730         formRecord.updateAtHour = FormUtil::ConvertStringToInt(time[0]);
731         formRecord.updateAtMin = FormUtil::ConvertStringToInt(time[1]);
732     }
733     std::string multiScheduledUpdateTime_ = formInfo.multiScheduledUpdateTime;
734     if (!multiScheduledUpdateTime_.empty()) {
735         UpdateMultiUpdateTime(multiScheduledUpdateTime_, formRecord);
736     }
737     HILOG_DEBUG("formId:%{public}" PRId64 "", formRecord.formId);
738     FormDataMgr::GetInstance().UpdateFormRecord(formRecord.formId, formRecord);
739 }
740 
GetDirFiles(const std::string & path,std::vector<std::string> & files)741 void FormEventUtil::GetDirFiles(const std::string &path, std::vector<std::string> &files)
742 {
743     DIR *dir = opendir(path.c_str());
744     if (dir == nullptr) {
745         HILOG_ERROR("failed to open file: %{public}s, error: %{public}d", path.c_str(), errno);
746         return;
747     }
748 
749     std::string pathStringWithDelimiter;
750     while (true) {
751         struct dirent *ptr = readdir(dir);
752         if (ptr == nullptr) {
753             HILOG_INFO("The file has been traversed");
754             break;
755         }
756 
757         // current dir OR parent dir
758         if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0)) {
759             continue;
760         } else if (ptr->d_type == DT_DIR) {
761             pathStringWithDelimiter = IncludeTrailingPathDelimiter(path) + std::string(ptr->d_name);
762             GetDirFiles(pathStringWithDelimiter, files);
763         } else {
764             files.push_back(IncludeTrailingPathDelimiter(path) + std::string(ptr->d_name));
765         }
766     }
767     closedir(dir);
768 }
769 
GetFilesSize(std::vector<std::string> & files,std::vector<std::uint64_t> & filesSize)770 void FormEventUtil::GetFilesSize(std::vector<std::string> &files, std::vector<std::uint64_t> &filesSize)
771 {
772     struct stat statbuf = {0};
773     uint64_t totalSize = 0;
774     for (auto &file : files) {
775         if (stat(file.c_str(), &statbuf) == 0) {
776             filesSize.emplace_back(static_cast<uint64_t>(statbuf.st_size));
777             totalSize += static_cast<uint64_t>(statbuf.st_size);
778         }
779     }
780     filesSize.emplace_back(totalSize);
781 }
782 } // namespace AppExecFwk
783 } // namespace OHOS
784