• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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