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