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