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