1 /*
2 * Copyright (c) 2021-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_db_cache.h"
17
18 #include <cinttypes>
19
20 #include "form_bms_helper.h"
21 #include "form_data_mgr.h"
22 #include "form_db_info.h"
23 #include "form_mgr_errors.h"
24 #include "form_provider_mgr.h"
25 #include "hilog_wrapper.h"
26
27 namespace OHOS {
28 namespace AppExecFwk {
FormDbCache()29 FormDbCache::FormDbCache()
30 {
31 HILOG_INFO("FormDbCache is created");
32 }
33
~FormDbCache()34 FormDbCache::~FormDbCache()
35 {
36 HILOG_INFO("FormDbCache is destroyed");
37 }
38
39 /**
40 * @brief Load form data from DB to DbCache when starting.
41 * @return Void.
42 */
Start()43 void FormDbCache::Start()
44 {
45 HILOG_INFO("%{public}s called.", __func__);
46 std::lock_guard<std::mutex> lock(formDBInfosMutex_);
47 std::vector<InnerFormInfo> innerFormInfos;
48 innerFormInfos.clear();
49 if (FormInfoRdbStorageMgr::GetInstance().LoadFormData(innerFormInfos) != ERR_OK) {
50 HILOG_ERROR("%{public}s, LoadFormData failed.", __func__);
51 return;
52 }
53
54 for (unsigned int i = 0; i < innerFormInfos.size(); i++) {
55 FormDBInfo formDBInfo = innerFormInfos.at(i).GetFormDBInfo();
56 formDBInfos_.emplace_back(formDBInfo);
57 }
58 }
59
60 /**
61 * @brief Save or update form data to DbCache and DB.
62 * @param formDBInfo Form data.
63 * @return Returns ERR_OK on success, others on failure.
64 */
SaveFormInfo(const FormDBInfo & formDBInfo)65 ErrCode FormDbCache::SaveFormInfo(const FormDBInfo &formDBInfo)
66 {
67 HILOG_INFO("%{public}s called, formId:%{public}" PRId64 "", __func__, formDBInfo.formId);
68 std::lock_guard<std::mutex> lock(formDBInfosMutex_);
69 auto iter = find(formDBInfos_.begin(), formDBInfos_.end(), formDBInfo);
70 if (iter != formDBInfos_.end()) {
71 if (iter->Compare(formDBInfo) == false) {
72 HILOG_WARN("%{public}s, need update, formId[%{public}" PRId64 "].", __func__, formDBInfo.formId);
73 *iter = formDBInfo;
74 InnerFormInfo innerFormInfo(formDBInfo);
75 return FormInfoRdbStorageMgr::GetInstance().ModifyStorageFormData(innerFormInfo);
76 } else {
77 HILOG_WARN("%{public}s, already exist, formId[%{public}" PRId64 "].", __func__, formDBInfo.formId);
78 return ERR_OK;
79 }
80 } else {
81 formDBInfos_.emplace_back(formDBInfo);
82 InnerFormInfo innerFormInfo(formDBInfo);
83 return FormInfoRdbStorageMgr::GetInstance().SaveStorageFormData(innerFormInfo);
84 }
85 }
86
87 /**
88 * @brief Save or update form data to DbCache and DB.
89 * @param formDBInfo Form data.
90 * @return Returns ERR_OK on success, others on failure.(NoLock)
91 */
SaveFormInfoNolock(const FormDBInfo & formDBInfo)92 ErrCode FormDbCache::SaveFormInfoNolock(const FormDBInfo &formDBInfo)
93 {
94 HILOG_INFO("%{public}s called, formId:%{public}" PRId64 "", __func__, formDBInfo.formId);
95 auto iter = find(formDBInfos_.begin(), formDBInfos_.end(), formDBInfo);
96 if (iter != formDBInfos_.end()) {
97 if (iter->Compare(formDBInfo) == false) {
98 HILOG_WARN("%{public}s, need update, formId[%{public}" PRId64 "].", __func__, formDBInfo.formId);
99 *iter = formDBInfo;
100 InnerFormInfo innerFormInfo(formDBInfo);
101 return FormInfoRdbStorageMgr::GetInstance().ModifyStorageFormData(innerFormInfo);
102 } else {
103 HILOG_WARN("%{public}s, already exist, formId[%{public}" PRId64 "].", __func__, formDBInfo.formId);
104 return ERR_OK;
105 }
106 } else {
107 formDBInfos_.emplace_back(formDBInfo);
108 InnerFormInfo innerFormInfo(formDBInfo);
109 return FormInfoRdbStorageMgr::GetInstance().SaveStorageFormData(innerFormInfo);
110 }
111 }
112
113 /**
114 * @brief Delete form data in DbCache and DB with formId.
115 * @param formId form data Id.
116 * @return Returns ERR_OK on success, others on failure.
117 */
DeleteFormInfo(int64_t formId)118 ErrCode FormDbCache::DeleteFormInfo(int64_t formId)
119 {
120 std::lock_guard<std::mutex> lock(formDBInfosMutex_);
121 FormDBInfo tmpForm;
122 tmpForm.formId = formId;
123 auto iter = find(formDBInfos_.begin(), formDBInfos_.end(), tmpForm);
124 if (iter == formDBInfos_.end()) {
125 HILOG_WARN("%{public}s, not find formId[%{public}" PRId64 "]", __func__, formId);
126 } else {
127 formDBInfos_.erase(iter);
128 }
129 if (FormInfoRdbStorageMgr::GetInstance().DeleteStorageFormData(std::to_string(formId)) == ERR_OK) {
130 return ERR_OK;
131 } else {
132 return ERR_APPEXECFWK_FORM_COMMON_CODE;
133 }
134 }
135 /**
136 * @brief Delete form data in DbCache and DB with formId.
137 * @param formId form data Id.
138 * @param removedDBForms Removed db form infos
139 * @return Returns ERR_OK on success, others on failure.
140 */
DeleteFormInfoByBundleName(const std::string & bundleName,const int32_t userId,std::vector<FormDBInfo> & removedDBForms)141 ErrCode FormDbCache::DeleteFormInfoByBundleName(const std::string &bundleName, const int32_t userId,
142 std::vector<FormDBInfo> &removedDBForms)
143 {
144 std::lock_guard<std::mutex> lock(formDBInfosMutex_);
145 std::vector<FormDBInfo>::iterator itRecord;
146 for (itRecord = formDBInfos_.begin(); itRecord != formDBInfos_.end();) {
147 if ((bundleName == itRecord->bundleName) && (userId == itRecord->userId)) {
148 int64_t formId = itRecord->formId;
149 if (FormInfoRdbStorageMgr::GetInstance().DeleteStorageFormData(std::to_string(formId)) == ERR_OK) {
150 removedDBForms.emplace_back(*itRecord);
151 itRecord = formDBInfos_.erase(itRecord);
152 } else {
153 itRecord++;
154 }
155 } else {
156 itRecord++;
157 }
158 }
159 return ERR_OK;
160 }
161
162 /**
163 * @brief Get all form data from DbCache.
164 * @param formDBInfos Storage all DbCache.
165 * @return Void.
166 */
GetAllFormInfo(std::vector<FormDBInfo> & formDBInfos)167 void FormDbCache::GetAllFormInfo(std::vector<FormDBInfo> &formDBInfos)
168 {
169 HILOG_INFO("%{public}s called.", __func__);
170 std::lock_guard<std::mutex> lock(formDBInfosMutex_);
171 formDBInfos = formDBInfos_;
172 }
173
174 /**
175 * @brief Get record from DB cache with formId
176 * @param formId Form data Id
177 * @param record Form data
178 * @return Returns ERR_OK on success, others on failure.
179 */
GetDBRecord(const int64_t formId,FormRecord & record) const180 ErrCode FormDbCache::GetDBRecord(const int64_t formId, FormRecord &record) const
181 {
182 std::lock_guard<std::mutex> lock(formDBInfosMutex_);
183 for (const FormDBInfo &dbInfo : formDBInfos_) {
184 if (dbInfo.formId == formId) {
185 record.userId = dbInfo.userId;
186 record.formName = dbInfo.formName;
187 record.bundleName = dbInfo.bundleName;
188 record.moduleName = dbInfo.moduleName;
189 record.abilityName = dbInfo.abilityName;
190 record.formUserUids = dbInfo.formUserUids;
191 return ERR_OK;
192 }
193 }
194 HILOG_ERROR("%{public}s, not find formId[%{public}" PRId64 "]", __func__, formId);
195 return ERR_APPEXECFWK_FORM_NOT_EXIST_ID;
196 }
197 /**
198 * @brief Get record from DB cache with formId
199 * @param formId Form data Id
200 * @param record Form db data
201 * @return Returns ERR_OK on success, others on failure.
202 */
GetDBRecord(const int64_t formId,FormDBInfo & record) const203 ErrCode FormDbCache::GetDBRecord(const int64_t formId, FormDBInfo &record) const
204 {
205 std::lock_guard<std::mutex> lock(formDBInfosMutex_);
206 for (const FormDBInfo &dbInfo : formDBInfos_) {
207 if (dbInfo.formId == formId) {
208 record = dbInfo;
209 return ERR_OK;
210 }
211 }
212 HILOG_ERROR("%{public}s, not find formId[%{public}" PRId64 "]", __func__, formId);
213 return ERR_APPEXECFWK_FORM_NOT_EXIST_ID;
214 }
215 /**
216 * @brief Use record save or update DB data and DB cache with formId
217 * @param formId Form data Id
218 * @param record Form data
219 * @return Returns ERR_OK on success, others on failure.
220 */
UpdateDBRecord(const int64_t formId,const FormRecord & record) const221 ErrCode FormDbCache::UpdateDBRecord(const int64_t formId, const FormRecord &record) const
222 {
223 FormDBInfo formDBInfo(formId, record);
224 return FormDbCache::GetInstance().SaveFormInfo(formDBInfo);
225 }
226 /**
227 * @brief Get no host db record.
228 * @param uid The caller uid.
229 * @param noHostFormDBList no host db record list.
230 * @param foundFormsMap Form Id list.
231 * @return Returns ERR_OK on success, others on failure.
232 */
GetNoHostDBForms(const int uid,std::map<FormIdKey,std::set<int64_t>> & noHostFormDBList,std::map<int64_t,bool> & foundFormsMap)233 ErrCode FormDbCache::GetNoHostDBForms(const int uid, std::map<FormIdKey,
234 std::set<int64_t>> &noHostFormDBList, std::map<int64_t, bool> &foundFormsMap)
235 {
236 std::lock_guard<std::mutex> lock(formDBInfosMutex_);
237 for (FormDBInfo& dbInfo : formDBInfos_) {
238 if (dbInfo.Contains(uid)) {
239 dbInfo.Remove(uid);
240 if (dbInfo.formUserUids.empty()) {
241 FormIdKey formIdKey(dbInfo.bundleName, dbInfo.abilityName);
242 auto itIdsSet = noHostFormDBList.find(formIdKey);
243 if (itIdsSet == noHostFormDBList.end()) {
244 std::set<int64_t> formIdsSet;
245 formIdsSet.emplace(dbInfo.formId);
246 noHostFormDBList.emplace(formIdKey, formIdsSet);
247 } else {
248 itIdsSet->second.emplace(dbInfo.formId);
249 }
250 } else {
251 foundFormsMap.emplace(dbInfo.formId, false);
252 SaveFormInfoNolock(dbInfo);
253 FormBmsHelper::GetInstance().NotifyModuleNotRemovable(dbInfo.bundleName, dbInfo.moduleName);
254 }
255 }
256 }
257 return ERR_OK;
258 }
259 /**
260 * @brief Get match count by bundleName and moduleName.
261 * @param bundleName BundleName.
262 * @param moduleName ModuleName.
263 * @return Returns match count.
264 */
GetMatchCount(const std::string & bundleName,const std::string & moduleName)265 int FormDbCache::GetMatchCount(const std::string &bundleName, const std::string &moduleName)
266 {
267 int32_t matchCount = 0;
268 std::vector<FormDBInfo> formDBInfos;
269 std::lock_guard<std::mutex> lock(formDBInfosMutex_);
270 for (const FormDBInfo &dbInfo : formDBInfos_) {
271 if (dbInfo.bundleName == bundleName && dbInfo.moduleName == moduleName) {
272 ++matchCount;
273 }
274 }
275 return matchCount;
276 }
277 /**
278 * @brief delete forms bu userId.
279 *
280 * @param userId user ID.
281 */
DeleteDBFormsByUserId(const int32_t userId)282 void FormDbCache::DeleteDBFormsByUserId(const int32_t userId)
283 {
284 std::lock_guard<std::mutex> lock(formDBInfosMutex_);
285 std::vector<FormDBInfo>::iterator itRecord;
286 for (itRecord = formDBInfos_.begin(); itRecord != formDBInfos_.end();) {
287 if (userId == itRecord->userId) {
288 int64_t formId = itRecord->formId;
289 if (FormInfoRdbStorageMgr::GetInstance().DeleteStorageFormData(std::to_string(formId)) == ERR_OK) {
290 itRecord = formDBInfos_.erase(itRecord);
291 } else {
292 HILOG_ERROR("%{public}s, failed to delete form, formId[%{public}" PRId64 "]", __func__, formId);
293 itRecord++;
294 }
295 } else {
296 itRecord++;
297 }
298 }
299 }
300
301 /**
302 * @brief handle get no host invalid DB forms.
303 * @param userId User ID.
304 * @param callingUid The UID of the proxy.
305 * @param matchedFormIds The set of the valid forms.
306 * @param noHostDBFormsMap The map of the no host forms.
307 * @param foundFormsMap The map of the found forms.
308 */
GetNoHostInvalidDBForms(int32_t userId,int32_t callingUid,std::set<int64_t> & matchedFormIds,std::map<FormIdKey,std::set<int64_t>> & noHostDBFormsMap,std::map<int64_t,bool> & foundFormsMap)309 void FormDbCache::GetNoHostInvalidDBForms(int32_t userId, int32_t callingUid, std::set<int64_t> &matchedFormIds,
310 std::map<FormIdKey, std::set<int64_t>> &noHostDBFormsMap,
311 std::map<int64_t, bool> &foundFormsMap)
312 {
313 std::lock_guard<std::mutex> lock(formDBInfosMutex_);
314 for (auto &formRecord: formDBInfos_) {
315 int64_t formId = formRecord.formId;
316
317 // check userID
318 if (userId != formRecord.userId) {
319 continue;
320 }
321 // check UID
322 auto iter = std::find(formRecord.formUserUids.begin(), formRecord.formUserUids.end(), callingUid);
323 if (iter == formRecord.formUserUids.end()) {
324 continue;
325 }
326 // check valid form set
327 if (matchedFormIds.find(formId) != matchedFormIds.end()) {
328 continue;
329 }
330
331 HILOG_DEBUG("found invalid form: %{public}" PRId64 "", formId);
332 formRecord.formUserUids.erase(iter);
333 if (formRecord.formUserUids.empty()) {
334 FormIdKey formIdKey(formRecord.bundleName, formRecord.abilityName);
335 auto itIdsSet = noHostDBFormsMap.find(formIdKey);
336 if (itIdsSet == noHostDBFormsMap.end()) {
337 std::set<int64_t> formIdsSet;
338 formIdsSet.emplace(formId);
339 noHostDBFormsMap.emplace(formIdKey, formIdsSet);
340 } else {
341 itIdsSet->second.emplace(formId);
342 }
343 } else {
344 foundFormsMap.emplace(formId, false);
345 SaveFormInfoNolock(formRecord);
346 FormBmsHelper::GetInstance().NotifyModuleNotRemovable(formRecord.bundleName, formRecord.moduleName);
347 }
348 }
349 }
350
351 /**
352 * @brief handle delete no host DB forms.
353 * @param callingUid The UID of the proxy.
354 * @param noHostFormDbMap The map of the no host forms.
355 * @param foundFormsMap The map of the found forms.
356 */
BatchDeleteNoHostDBForms(int32_t callingUid,std::map<FormIdKey,std::set<int64_t>> & noHostDBFormsMap,std::map<int64_t,bool> & foundFormsMap)357 void FormDbCache::BatchDeleteNoHostDBForms(int32_t callingUid, std::map<FormIdKey, std::set<int64_t>> &noHostDBFormsMap,
358 std::map<int64_t, bool> &foundFormsMap)
359 {
360 std::set<FormIdKey> removableModuleSet;
361 for (auto &element : noHostDBFormsMap) {
362 std::set<int64_t> &formIds = element.second;
363 FormIdKey formIdKey = element.first;
364 std::string bundleName = formIdKey.bundleName;
365 std::string abilityName = formIdKey.abilityName;
366 FormProviderMgr::GetInstance().NotifyProviderFormsBatchDelete(bundleName, abilityName, formIds);
367 for (const int64_t formId : formIds) {
368 foundFormsMap.emplace(formId, true);
369 FormDBInfo dbInfo;
370 int errCode = GetDBRecord(formId, dbInfo);
371 if (errCode == ERR_OK) {
372 FormIdKey removableModuleFormIdKey(dbInfo.bundleName, dbInfo.moduleName);
373 removableModuleSet.emplace(removableModuleFormIdKey);
374 DeleteFormInfo(formId);
375 }
376 FormDataMgr::GetInstance().StopRenderingForm(formId);
377 FormDataMgr::GetInstance().DeleteFormRecord(formId);
378 }
379 }
380
381 for (const FormIdKey &item : removableModuleSet) {
382 int32_t matchCount = GetMatchCount(item.bundleName, item.moduleName);
383 if (matchCount == 0) {
384 FormBmsHelper::GetInstance().NotifyModuleRemovable(item.bundleName, item.moduleName);
385 }
386 }
387 }
388
389 /**
390 * @brief handle delete invalid DB forms.
391 * @param userId User ID.
392 * @param callingUid The UID of the proxy.
393 * @param matchedFormIds The set of the valid forms.
394 * @param removedFormsMap The map of the removed invalid forms.
395 * @return Returns ERR_OK on success, others on failure.
396 */
DeleteInvalidDBForms(int32_t userId,int32_t callingUid,std::set<int64_t> & matchedFormIds,std::map<int64_t,bool> & removedFormsMap)397 ErrCode FormDbCache::DeleteInvalidDBForms(int32_t userId, int32_t callingUid, std::set<int64_t> &matchedFormIds,
398 std::map<int64_t, bool> &removedFormsMap)
399 {
400 HILOG_INFO("DeleteInvalidDBForms start, userId = %{public}d, callingUid = %{public}d", userId, callingUid);
401 std::map<int64_t, bool> foundFormsMap {};
402 std::map<FormIdKey, std::set<int64_t>> noHostDBFormsMap {};
403
404 GetNoHostInvalidDBForms(userId, callingUid, matchedFormIds, noHostDBFormsMap, foundFormsMap);
405
406 if (!foundFormsMap.empty()) {
407 for (const auto &element : foundFormsMap) {
408 FormDataMgr::GetInstance().DeleteFormUserUid(element.first, callingUid);
409 }
410 }
411
412 BatchDeleteNoHostDBForms(callingUid, noHostDBFormsMap, foundFormsMap);
413 HILOG_DEBUG("foundFormsMap size: %{public}zu", foundFormsMap.size());
414 HILOG_DEBUG("noHostDBFormsMap size: %{public}zu", noHostDBFormsMap.size());
415
416 if (!foundFormsMap.empty()) {
417 removedFormsMap.insert(foundFormsMap.begin(), foundFormsMap.end());
418 }
419
420 HILOG_INFO("DeleteInvalidDBForms done");
421 return ERR_OK;
422 }
423
IsHostOwner(int64_t formId,int32_t hostUid)424 bool FormDbCache::IsHostOwner(int64_t formId, int32_t hostUid)
425 {
426 FormDBInfo dbInfo;
427 if (GetDBRecord(formId, dbInfo) != ERR_OK) {
428 HILOG_ERROR("get db record failed. formId: %{public}s", std::to_string(formId).c_str());
429 return false;
430 }
431
432 auto iter = std::find(dbInfo.formUserUids.begin(), dbInfo.formUserUids.end(), hostUid);
433 if (iter != dbInfo.formUserUids.end()) {
434 return true;
435 }
436
437 return false;
438 }
439 } // namespace AppExecFwk
440 } // namespace OHOS
441