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_render_mgr.h"
24 #include "form_timer_mgr.h"
25 #include "form_util.h"
26 #include "form_provider_mgr.h"
27 #include "hilog_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().UpdateStaticFormInfos(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 std::vector<FormInfo> targetForms;
50 if (FormInfoMgr::GetInstance().GetFormsInfoByBundle(bundleName, targetForms) != ERR_OK) {
51 HILOG_ERROR("%{public}s error, failed to get forms info.", __func__);
52 return;
53 }
54
55 BundlePackInfo bundlePackInfo;
56 bool hasPackInfo = FormBmsHelper::GetInstance().GetBundlePackInfo(bundleName, userId, bundlePackInfo);
57 std::vector<int64_t> removedForms;
58 std::vector<int64_t> updatedForms;
59 for (FormRecord& formRecord : formInfos) {
60 HILOG_INFO("%{public}s, provider update, formName:%{public}s", __func__, formRecord.formName.c_str());
61 int64_t formId = formRecord.formId;
62 if (ProviderFormUpdated(formId, formRecord, targetForms)) {
63 updatedForms.emplace_back(formId);
64 continue;
65 }
66 if (hasPackInfo && ProviderFormUpdated(formId, formRecord, bundlePackInfo)) {
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 if (formRecord.formTempFlag) {
73 FormDataMgr::GetInstance().DeleteTempForm(formId);
74 } else {
75 FormDbCache::GetInstance().DeleteFormInfo(formId);
76 }
77 removedForms.emplace_back(formId);
78 FormDataMgr::GetInstance().DeleteFormRecord(formId);
79 FormRenderMgr::GetInstance().StopRenderingForm(formId, formRecord);
80 }
81
82 if (!removedForms.empty()) {
83 HILOG_INFO("%{public}s, clean removed forms and timer", __func__);
84 FormDataMgr::GetInstance().CleanHostRemovedForms(removedForms);
85 for (const int64_t id : removedForms) {
86 FormTimerMgr::GetInstance().RemoveFormTimer(id);
87 }
88 }
89 HILOG_INFO("%{public}s, refresh form", __func__);
90 Want want;
91 want.SetParam(Constants::PARAM_FORM_USER_ID, userId);
92 for (const int64_t id : updatedForms) {
93 FormProviderMgr::GetInstance().RefreshForm(id, want, true);
94 }
95 FormRenderMgr::GetInstance().ReloadForm(std::move(updatedForms), bundleName, userId);
96 }
97
HandleBundleFormInfoRemoved(const std::string & bundleName,int32_t userId)98 void FormEventUtil::HandleBundleFormInfoRemoved(const std::string &bundleName, int32_t userId)
99 {
100 FormInfoMgr::GetInstance().Remove(bundleName, userId);
101 }
102
HandleProviderRemoved(const std::string & bundleName,const int32_t userId)103 void FormEventUtil::HandleProviderRemoved(const std::string &bundleName, const int32_t userId)
104 {
105 HILOG_INFO("GET into HandleProviderRemoved with bundleName : %{public}s, userId : %{public}d",
106 bundleName.c_str(), userId);
107 // clean removed form in DB
108 std::set<int64_t> removedForms;
109 std::vector<FormDBInfo> removedDBForm;
110 FormDbCache::GetInstance().DeleteFormInfoByBundleName(bundleName, userId, removedDBForm);
111 for (const auto &dbForm : removedDBForm) {
112 removedForms.emplace(dbForm.formId);
113 int32_t matchCount = FormDbCache::GetInstance().GetMatchCount(dbForm.bundleName, dbForm.moduleName);
114 if (matchCount == 0) {
115 FormBmsHelper::GetInstance().NotifyModuleRemovable(dbForm.bundleName, dbForm.moduleName);
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,int32_t userId)133 void FormEventUtil::HandleBundleDataCleared(const std::string &bundleName, int32_t userId)
134 {
135 HILOG_DEBUG("%{public}s, bundleName:%{public}s, userId:%{public}d", __func__, bundleName.c_str(), userId);
136 // clear dynamic form info
137 FormInfoMgr::GetInstance().RemoveAllDynamicFormsInfo(bundleName, userId);
138
139 // as provider data is cleared
140 std::set<int64_t> reCreateForms;
141 FormDataMgr::GetInstance().GetReCreateFormRecordsByBundleName(bundleName, reCreateForms);
142 if (!reCreateForms.empty()) {
143 for (int64_t formId : reCreateForms) {
144 ReCreateForm(formId);
145 }
146 }
147
148 int32_t uid = FormBmsHelper::GetInstance().GetUidByBundleName(bundleName, userId);
149 if (uid == FormBmsHelper::INVALID_UID) {
150 HILOG_ERROR("invalid uid");
151 return;
152 }
153 // as form host data is cleared
154 HandleFormHostDataCleared(uid);
155 }
156
HandleFormHostDataCleared(const int uid)157 void FormEventUtil::HandleFormHostDataCleared(const int uid)
158 {
159 HILOG_DEBUG("%{public}s, uid:%{public}d", __func__, uid);
160 std::map<int64_t, bool> removedFormsMap;
161 // clear formDBRecord
162 ClearFormDBRecordData(uid, removedFormsMap);
163
164 // clear temp form
165 ClearTempFormRecordData(uid, removedFormsMap);
166
167 // clear host data
168 FormDataMgr::GetInstance().ClearHostDataByUId(uid);
169
170 // delete forms timer
171 for (const auto &removedForm : removedFormsMap) {
172 if (removedForm.second) {
173 FormTimerMgr::GetInstance().RemoveFormTimer(removedForm.first);
174 }
175 }
176 }
177
ProviderFormUpdated(const int64_t formId,FormRecord & formRecord,const std::vector<FormInfo> & targetForms)178 bool FormEventUtil::ProviderFormUpdated(const int64_t formId, FormRecord &formRecord,
179 const std::vector<FormInfo> &targetForms)
180 {
181 HILOG_INFO("%{public}s start", __func__);
182 if (targetForms.empty()) {
183 HILOG_ERROR("%{public}s error, targetForms is empty", __func__);
184 return false;
185 }
186
187 FormInfo updatedForm;
188 bool bGetForm = FormDataMgr::GetInstance().GetUpdatedForm(formRecord, targetForms, updatedForm);
189 if (!bGetForm) {
190 HILOG_INFO("%{public}s, no updated form.", __func__);
191 return false;
192 }
193 HILOG_INFO("%{public}s, form is still exist,form:%{public}s", __func__, formRecord.formName.c_str());
194
195 // update resource
196 FormDataMgr::GetInstance().SetNeedRefresh(formId, true);
197 FormCacheMgr::GetInstance().DeleteData(formId);
198 FormBmsHelper::GetInstance().NotifyModuleNotRemovable(formRecord.bundleName, formRecord.moduleName);
199 FormTimerCfg timerCfg;
200 GetTimerCfg(updatedForm.updateEnabled, updatedForm.updateDuration, updatedForm.scheduledUpdateTime, timerCfg);
201 HandleTimerUpdate(formId, formRecord, timerCfg);
202 UpateFormRecord(updatedForm, formRecord);
203 FormDataMgr::GetInstance().SetVersionUpgrade(formId, true);
204 return true;
205 }
206
ProviderFormUpdated(const int64_t formId,FormRecord & formRecord,const BundlePackInfo & bundlePackInfo)207 bool FormEventUtil::ProviderFormUpdated(const int64_t formId, FormRecord &formRecord,
208 const BundlePackInfo &bundlePackInfo)
209 {
210 HILOG_INFO("%{public}s start", __func__);
211 AbilityFormInfo packForm;
212 if (!FormDataMgr::GetInstance().GetPackageForm(formRecord, bundlePackInfo, packForm)) {
213 HILOG_INFO("%{public}s, no updated form.", __func__);
214 return false;
215 }
216
217 HILOG_INFO("%{public}s, form is still in package info, form:%{public}s", __func__, formRecord.formName.c_str());
218 FormDataMgr::GetInstance().SetRecordNeedFreeInstall(formId, true);
219 FormTimerCfg timerCfg;
220 GetTimerCfg(packForm.updateEnabled, packForm.updateDuration, packForm.scheduledUpdateTime, timerCfg);
221 HandleTimerUpdate(formId, formRecord, timerCfg);
222 UpateFormRecord(packForm, formRecord);
223 FormDataMgr::GetInstance().SetVersionUpgrade(formId, true);
224 return true;
225 }
226
ClearFormDBRecordData(const int uid,std::map<int64_t,bool> & removedFormsMap)227 void FormEventUtil::ClearFormDBRecordData(const int uid, std::map<int64_t, bool> &removedFormsMap)
228 {
229 std::map<int64_t, bool> foundFormsMap;
230 std::map<FormIdKey, std::set<int64_t>> noHostFormDbMap;
231 FormDbCache::GetInstance().GetNoHostDBForms(uid, noHostFormDbMap, foundFormsMap);
232 if (!foundFormsMap.empty()) {
233 for (const auto &element : foundFormsMap) {
234 FormDataMgr::GetInstance().DeleteFormUserUid(element.first, uid);
235 }
236 }
237
238 HILOG_DEBUG("%{public}s, noHostFormDbMap size:%{public}zu", __func__, noHostFormDbMap.size());
239 if (!noHostFormDbMap.empty()) {
240 BatchDeleteNoHostDBForms(uid, noHostFormDbMap, foundFormsMap);
241 }
242
243 if (!foundFormsMap.empty()) {
244 removedFormsMap.insert(foundFormsMap.begin(), foundFormsMap.end());
245 }
246 }
247
ClearTempFormRecordData(const int uid,std::map<int64_t,bool> & removedFormsMap)248 void FormEventUtil::ClearTempFormRecordData(const int uid, std::map<int64_t, bool> &removedFormsMap)
249 {
250 std::map<int64_t, bool> foundFormsMap;
251 std::map<FormIdKey, std::set<int64_t>> noHostTempFormsMap;
252 FormDataMgr::GetInstance().GetNoHostTempForms(uid, noHostTempFormsMap, foundFormsMap);
253 HILOG_DEBUG("%{public}s, noHostTempFormsMap size:%{public}zu", __func__, noHostTempFormsMap.size());
254 if (!noHostTempFormsMap.empty()) {
255 BatchDeleteNoHostTempForms(uid, noHostTempFormsMap, foundFormsMap);
256 }
257 if (!foundFormsMap.empty()) {
258 removedFormsMap.insert(foundFormsMap.begin(), foundFormsMap.end());
259 }
260 }
261
BatchDeleteNoHostTempForms(const int uid,std::map<FormIdKey,std::set<int64_t>> & noHostTempFormsMap,std::map<int64_t,bool> & foundFormsMap)262 void FormEventUtil::BatchDeleteNoHostTempForms(const int uid, std::map<FormIdKey,
263 std::set<int64_t>> &noHostTempFormsMap, std::map<int64_t, bool> &foundFormsMap)
264 {
265 for (const auto &element : noHostTempFormsMap) {
266 std::set<int64_t> formIds = element.second;
267 FormIdKey formIdKey = element.first;
268 std::string bundleName = formIdKey.bundleName;
269 std::string abilityName = formIdKey.abilityName;
270 int result = FormProviderMgr::GetInstance().NotifyProviderFormsBatchDelete(bundleName, abilityName, formIds);
271 if (result != ERR_OK) {
272 HILOG_ERROR("%{public}s error, NotifyProviderFormsBatchDelete fail bundle:%{public}s ability:%{public}s",
273 __func__, bundleName.c_str(), abilityName.c_str());
274 for (int64_t formId : formIds) {
275 FormDataMgr::GetInstance().AddFormUserUid(formId, uid);
276 }
277 } else {
278 for (int64_t formId : formIds) {
279 foundFormsMap.emplace(formId, true);
280 FormDataMgr::GetInstance().DeleteFormRecord(formId);
281 FormDataMgr::GetInstance().DeleteTempForm(formId);
282 }
283 }
284 }
285 }
286
GetTimerCfg(const bool updateEnabled,const int updateDuration,const std::string & configUpdateAt,FormTimerCfg & cfg)287 void FormEventUtil::GetTimerCfg(const bool updateEnabled,
288 const int updateDuration, const std::string &configUpdateAt, FormTimerCfg& cfg)
289 {
290 HILOG_INFO("%{public}s start", __func__);
291 if (!updateEnabled) {
292 HILOG_INFO("%{public}s, update disable", __func__);
293 return;
294 }
295
296 if (updateDuration > 0) {
297 // interval timer
298 HILOG_INFO("%{public}s,interval timer updateDuration:%{public}d", __func__, updateDuration);
299 if (updateDuration <= Constants::MIN_CONFIG_DURATION) {
300 cfg.updateDuration = Constants::MIN_PERIOD;
301 } else if (updateDuration >= Constants::MAX_CONFIG_DURATION) {
302 cfg.updateDuration = Constants::MAX_PERIOD;
303 } else {
304 cfg.updateDuration = updateDuration * Constants::TIME_CONVERSION;
305 }
306 cfg.enableUpdate = true;
307 return;
308 } else {
309 // updateAtTimer
310 if (configUpdateAt.empty()) {
311 HILOG_INFO("%{public}s, configUpdateAt is empty", __func__);
312 return;
313 }
314 HILOG_INFO("%{public}s,update at timer updateAt:%{public}s", __func__, configUpdateAt.c_str());
315 std::vector<std::string> temp = FormUtil::StringSplit(configUpdateAt, Constants::TIME_DELIMETER);
316 if (temp.size() != Constants::UPDATE_AT_CONFIG_COUNT) {
317 HILOG_ERROR("%{public}s, invalid config", __func__);
318 return;
319 }
320 int hour = std::stoi(temp[0]);
321 int min = std::stoi(temp[1]);
322 if (hour < Constants::MIN_TIME || hour > Constants::MAX_HOUR || min < Constants::MIN_TIME || min >
323 Constants::MAX_MINUTE) {
324 HILOG_ERROR("%{public}s, time is invalid", __func__);
325 return;
326 }
327
328 cfg.updateAtHour = hour;
329 cfg.updateAtMin = min;
330 cfg.enableUpdate = true;
331 return;
332 }
333 }
334
HandleTimerUpdate(const int64_t formId,const FormRecord & record,const FormTimerCfg & timerCfg)335 void FormEventUtil::HandleTimerUpdate(const int64_t formId,
336 const FormRecord &record, const FormTimerCfg &timerCfg)
337 {
338 // both disable
339 if (!record.isEnableUpdate && !timerCfg.enableUpdate) {
340 return;
341 }
342
343 // enable to disable
344 if (record.isEnableUpdate && !timerCfg.enableUpdate) {
345 FormDataMgr::GetInstance().SetEnableUpdate(formId, false);
346 FormTimerMgr::GetInstance().RemoveFormTimer(formId);
347 return;
348 }
349
350 // disable to enable
351 if (!record.isEnableUpdate && timerCfg.enableUpdate) {
352 FormDataMgr::GetInstance().SetUpdateInfo(formId, true,
353 timerCfg.updateDuration, timerCfg.updateAtHour, timerCfg.updateAtMin);
354 if (timerCfg.updateDuration > 0) {
355 HILOG_INFO("%{public}s, add interval timer:%{public}" PRId64 "", __func__, timerCfg.updateDuration);
356 FormTimerMgr::GetInstance().AddFormTimer(formId, timerCfg.updateDuration, record.userId);
357 } else {
358 HILOG_INFO("%{public}s, add at timer:%{public}d, %{public}d", __func__,
359 timerCfg.updateAtHour, timerCfg.updateAtMin);
360 FormTimerMgr::GetInstance().AddFormTimer(formId, timerCfg.updateAtHour,
361 timerCfg.updateAtMin, record.userId);
362 }
363 return;
364 }
365
366 // both enable
367 UpdateType type;
368 if (record.updateDuration > 0) {
369 if (timerCfg.updateDuration > 0) {
370 // no change
371 if (record.updateDuration == timerCfg.updateDuration) {
372 return;
373 }
374 // interval change
375 type = TYPE_INTERVAL_CHANGE;
376 } else {
377 // interval to update at time
378 type = TYPE_INTERVAL_TO_ATTIME;
379 }
380 } else {
381 if (timerCfg.updateDuration > 0) {
382 // update at time to interval
383 type = TYPE_ATTIME_TO_INTERVAL;
384 } else {
385 if (record.updateAtHour == timerCfg.updateAtHour && record.updateAtMin == timerCfg.updateAtMin) {
386 return;
387 }
388 // update at time change
389 type = TYPE_ATTIME_CHANGE;
390 }
391 }
392
393 FormDataMgr::GetInstance().SetUpdateInfo(formId, true,
394 timerCfg.updateDuration, timerCfg.updateAtHour, timerCfg.updateAtMin);
395 FormTimerMgr::GetInstance().UpdateFormTimer(formId, type, timerCfg);
396 }
397
ReCreateForm(const int64_t formId)398 void FormEventUtil::ReCreateForm(const int64_t formId)
399 {
400 HILOG_INFO("%{public}s start, formId:%{public}" PRId64 "", __func__, formId);
401 FormRecord record;
402 bool isGetForm = FormDataMgr::GetInstance().GetFormRecord(formId, record);
403 if (!isGetForm) {
404 HILOG_ERROR("%{public}s error, not exist such form:%{public}" PRId64 "", __func__, formId);
405 return;
406 }
407 FormCacheMgr::GetInstance().DeleteData(formId);
408 FormRecord reCreateRecord;
409 reCreateRecord.bundleName = record.bundleName;
410 reCreateRecord.abilityName = record.abilityName;
411 reCreateRecord.formName = record.formName;
412 reCreateRecord.specification = record.specification;
413 reCreateRecord.formTempFlag = record.formTempFlag;
414 reCreateRecord.isInited = record.isInited;
415 reCreateRecord.versionUpgrade = record.versionUpgrade;
416
417 Want want;
418 FormUtil::CreateFormWant(reCreateRecord.formName, reCreateRecord.specification, reCreateRecord.formTempFlag, want);
419 want.SetParam(Constants::RECREATE_FORM_KEY, true);
420 FormProviderMgr::GetInstance().ConnectAmsForRefresh(formId, reCreateRecord, want, false);
421 }
422
BatchDeleteNoHostDBForms(const int uid,std::map<FormIdKey,std::set<int64_t>> & noHostFormDbMap,std::map<int64_t,bool> & removedFormsMap)423 void FormEventUtil::BatchDeleteNoHostDBForms(const int uid, std::map<FormIdKey, std::set<int64_t>> &noHostFormDbMap,
424 std::map<int64_t, bool> &removedFormsMap)
425 {
426 std::set<FormIdKey> removableModuleSet;
427 for (const auto &element: noHostFormDbMap) {
428 std::set<int64_t> formIds = element.second;
429 FormIdKey formIdKey = element.first;
430 std::string bundleName = formIdKey.bundleName;
431 std::string abilityName = formIdKey.abilityName;
432 int result = FormProviderMgr::GetInstance().NotifyProviderFormsBatchDelete(bundleName, abilityName, formIds);
433 if (result != ERR_OK) {
434 HILOG_ERROR("%{public}s error, NotifyProviderFormsBatchDelete fail bundle:%{public}s ability:%{public}s",
435 __func__, bundleName.c_str(), abilityName.c_str());
436 for (int64_t formId : formIds) {
437 FormDBInfo dbInfo;
438 int errCode = FormDbCache::GetInstance().GetDBRecord(formId, dbInfo);
439 if (errCode == ERR_OK) {
440 dbInfo.formUserUids.emplace_back(uid);
441 FormDbCache::GetInstance().SaveFormInfo(dbInfo);
442 }
443 }
444 } else {
445 for (const int64_t formId : formIds) {
446 removedFormsMap.emplace(formId, true);
447 FormDBInfo dbInfo;
448 int errCode = FormDbCache::GetInstance().GetDBRecord(formId, dbInfo);
449 if (errCode == ERR_OK) {
450 FormIdKey removableModuleFormIdKey(dbInfo.bundleName, dbInfo.moduleName);
451 removableModuleSet.emplace(removableModuleFormIdKey);
452 FormDbCache::GetInstance().DeleteFormInfo(formId);
453 }
454 FormDataMgr::GetInstance().DeleteFormRecord(formId);
455 }
456 }
457 }
458
459 for (const FormIdKey &item : removableModuleSet) {
460 int32_t matchCount = FormDbCache::GetInstance().GetMatchCount(item.bundleName, item.moduleName);
461 if (matchCount == 0) {
462 FormBmsHelper::GetInstance().NotifyModuleRemovable(item.bundleName, item.moduleName);
463 }
464 }
465 }
466
UpateFormRecord(const FormInfo & formInfo,FormRecord & formRecord)467 void FormEventUtil::UpateFormRecord(const FormInfo &formInfo, FormRecord &formRecord)
468 {
469 formRecord.formSrc = formInfo.src;
470 formRecord.uiSyntax = formInfo.uiSyntax;
471 formRecord.isEnableUpdate = formInfo.updateEnabled;
472 formRecord.updateDuration = formInfo.updateDuration;
473 std::vector<std::string> time = FormUtil::StringSplit(formInfo.scheduledUpdateTime, Constants::TIME_DELIMETER);
474 if (time.size() == Constants::UPDATE_AT_CONFIG_COUNT) {
475 formRecord.updateAtHour = std::stoi(time[0]);
476 formRecord.updateAtMin = std::stoi(time[1]);
477 }
478 HILOG_INFO("%{public}s formId:%{public}" PRId64 "", __func__, formRecord.formId);
479 FormDataMgr::GetInstance().UpdateFormRecord(formRecord.formId, formRecord);
480 }
481
UpateFormRecord(const AbilityFormInfo & formInfo,FormRecord & formRecord)482 void FormEventUtil::UpateFormRecord(const AbilityFormInfo &formInfo, FormRecord &formRecord)
483 {
484 formRecord.uiSyntax = (formInfo.type.compare("arkts") == 0 ? FormType::ETS : FormType::JS);
485 formRecord.isEnableUpdate = formInfo.updateEnabled;
486 formRecord.updateDuration = formInfo.updateDuration;
487 std::vector<std::string> time = FormUtil::StringSplit(formInfo.scheduledUpdateTime, Constants::TIME_DELIMETER);
488 if (time.size() == Constants::UPDATE_AT_CONFIG_COUNT) {
489 formRecord.updateAtHour = std::stoi(time[0]);
490 formRecord.updateAtMin = std::stoi(time[1]);
491 }
492 HILOG_INFO("%{public}s formId:%{public}" PRId64 "", __func__, formRecord.formId);
493 FormDataMgr::GetInstance().UpdateFormRecord(formRecord.formId, formRecord);
494 }
495 } // namespace AppExecFwk
496 } // namespace OHOS
497