1 /*
2  * Copyright (c) 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 "pkg_db_helper.h"
17 #include "bundle_installer_interface.h"
18 #include "hilog_wrapper.h"
19 #include "pkg_database.h"
20 
21 using namespace OHOS::NativeRdb;
22 
23 namespace OHOS {
24 namespace ExternalDeviceManager {
25 std::shared_ptr<PkgDbHelper> PkgDbHelper::instance_;
26 bool g_dbInitSucc = false;
27 
PkgDbHelper()28 PkgDbHelper::PkgDbHelper()
29 {
30     rightDatabase_ = PkgDataBase::GetInstance();
31     g_dbInitSucc = rightDatabase_->InitDB();
32 }
33 
GetInstance()34 std::shared_ptr<PkgDbHelper> PkgDbHelper::GetInstance()
35 {
36     static std::mutex instanceMutex;
37     std::lock_guard<std::mutex> guard(instanceMutex);
38     if (instance_ == nullptr || !g_dbInitSucc) {
39         EDM_LOGE(MODULE_PKG_MGR, "PkgDbHelper reset to new instance");
40         instance_.reset(new PkgDbHelper());
41     }
42     return instance_;
43 }
44 
DeleteAndNoOtherOperation(const std::string & whereClause,const std::vector<std::string> & whereArgs)45 int32_t PkgDbHelper::DeleteAndNoOtherOperation(
46     const std::string &whereClause, const std::vector<std::string> &whereArgs)
47 {
48     int32_t ret = rightDatabase_->BeginTransaction();
49     if (ret < PKG_OK) {
50         EDM_LOGE(MODULE_PKG_MGR, "BeginTransaction error: %{public}d", ret);
51         return ret;
52     }
53     int32_t changedRows = 0;
54     ret = rightDatabase_->Delete(changedRows, whereClause, whereArgs);
55     if (ret < PKG_OK) {
56         EDM_LOGE(MODULE_PKG_MGR, "Delete error: %{public}d", ret);
57         (void)rightDatabase_->RollBack();
58         return ret;
59     }
60     ret = rightDatabase_->Commit();
61     if (ret < PKG_OK) {
62         EDM_LOGE(MODULE_PKG_MGR, "Commit error: %{public}d", ret);
63         (void)rightDatabase_->RollBack();
64     }
65     return ret;
66 }
67 
DeleteRightRecord(const std::string & bundleName)68 int32_t PkgDbHelper::DeleteRightRecord(const std::string &bundleName)
69 {
70     std::lock_guard<std::mutex> guard(databaseMutex_);
71     std::string whereClause = {"bundleName = ?"};
72     std::vector<std::string> whereArgs = {bundleName};
73     int32_t ret = DeleteAndNoOtherOperation(whereClause, whereArgs);
74     if (ret != PKG_OK) {
75         EDM_LOGE(MODULE_PKG_MGR, "failed: detale(uid, dev, app): %{public}d", ret);
76     }
77     return ret;
78 }
79 
AddOrUpdatePkgInfo(const std::vector<PkgInfoTable> & pkgInfos,const std::string & bundleName)80 int32_t PkgDbHelper::AddOrUpdatePkgInfo(const std::vector<PkgInfoTable> &pkgInfos, const std::string &bundleName)
81 {
82     std::lock_guard<std::mutex> guard(databaseMutex_);
83     int32_t ret = rightDatabase_->BeginTransaction();
84     if (ret < PKG_OK) {
85         EDM_LOGE(MODULE_PKG_MGR, "BeginTransaction error: %{public}d", ret);
86         return ret;
87     }
88 
89     int32_t changedRows = 0;
90     std::string whereClause = "";
91     std::vector<std::string> whereArgs;
92     if (!bundleName.empty()) {
93         whereClause.append("bundleName = ?");
94         whereArgs.emplace_back(bundleName);
95     }
96     ret = rightDatabase_->Delete(changedRows, whereClause, whereArgs);
97     if (ret < PKG_OK) {
98         EDM_LOGE(MODULE_PKG_MGR, "delete error: %{public}d", ret);
99         (void)rightDatabase_->RollBack();
100         return ret;
101     }
102 
103     ValuesBucket values;
104     for (const auto &pkgInfo: pkgInfos) {
105         values.Clear();
106         values.PutString("driverUid", pkgInfo.driverUid);
107         values.PutLong("userId", pkgInfo.userId);
108         values.PutLong("appIndex", pkgInfo.appIndex);
109         values.PutString("bundleAbility", pkgInfo.bundleAbility);
110         values.PutString("bundleName", pkgInfo.bundleName);
111         values.PutString("driverName", pkgInfo.driverName);
112         values.PutString("driverInfo", pkgInfo.driverInfo);
113         ret = rightDatabase_->Insert(values);
114         if (ret < PKG_OK) {
115             EDM_LOGE(MODULE_PKG_MGR, "Insert error: %{public}d", ret);
116             (void)rightDatabase_->RollBack();
117             return ret;
118         }
119     }
120     ret = rightDatabase_->Commit();
121     if (ret < PKG_OK) {
122         EDM_LOGE(MODULE_PKG_MGR, "Commit error: %{public}d", ret);
123         (void)rightDatabase_->RollBack();
124     }
125     return ret;
126 }
127 
AddOrUpdateRightRecord(const std::string & bundleName,const std::string & bundleAbility,const std::string & driverInfo)128 int32_t PkgDbHelper::AddOrUpdateRightRecord(
129     const std::string & bundleName, const std::string & bundleAbility, const std::string &driverInfo)
130 {
131     std::lock_guard<std::mutex> guard(databaseMutex_);
132     int32_t ret = rightDatabase_->BeginTransaction();
133     if (ret < PKG_OK) {
134         EDM_LOGE(MODULE_PKG_MGR, "BeginTransaction error: %{public}d", ret);
135         return ret;
136     }
137     bool isUpdate = false;
138     ret = CheckIfNeedUpdateEx(isUpdate, bundleAbility);
139     if (ret < PKG_OK) {
140         EDM_LOGE(MODULE_PKG_MGR, "check if need update error: %{public}d", ret);
141         return ret;
142     }
143     ret = AddOrUpdateRightRecordEx(isUpdate, bundleName, bundleAbility, driverInfo);
144     if (ret < PKG_OK) {
145         EDM_LOGE(MODULE_PKG_MGR, "add or update error: %{public}d", ret);
146         return ret;
147     }
148     ret = rightDatabase_->Commit();
149     if (ret < PKG_OK) {
150         EDM_LOGE(MODULE_PKG_MGR, "Commit error: %{public}d", ret);
151         (void)rightDatabase_->RollBack();
152     }
153     return ret;
154 }
155 
CheckIfNeedUpdateEx(bool & isUpdate,const std::string & bundleAbility)156 int32_t PkgDbHelper::CheckIfNeedUpdateEx(
157     bool &isUpdate, const std::string &bundleAbility)
158 {
159     std::vector<std::string> columns;
160     RdbPredicates rdbPredicates(PKG_TABLE_NAME);
161     rdbPredicates.BeginWrap()
162         ->EqualTo("bundleAbility", bundleAbility)
163         ->EndWrap();
164     auto resultSet = rightDatabase_->Query(rdbPredicates, columns);
165     if (resultSet == nullptr) {
166         EDM_LOGE(MODULE_PKG_MGR, "Query error");
167         (void)rightDatabase_->RollBack();
168         return PKG_RDB_EXECUTE_FAILTURE;
169     }
170     int32_t rowCount = 0;
171     if (resultSet->GetRowCount(rowCount) != E_OK) {
172         EDM_LOGE(MODULE_PKG_MGR, "GetRowCount error");
173         (void)rightDatabase_->RollBack();
174         return PKG_RDB_EXECUTE_FAILTURE;
175     }
176     isUpdate = (rowCount > 0 ? true : false);
177 
178     return PKG_OK;
179 }
180 
AddOrUpdateRightRecordEx(bool isUpdate,const std::string & bundleName,const std::string & bundleAbility,const std::string & driverInfo)181 int32_t PkgDbHelper::AddOrUpdateRightRecordEx(bool isUpdate,
182     const std::string & bundleName, const std::string & bundleAbility, const std::string &driverInfo)
183 {
184     int32_t ret = 0;
185     ValuesBucket values;
186     values.Clear();
187     values.PutString("bundleName", bundleName);
188     values.PutString("bundleAbility", bundleAbility);
189     values.PutString("driverInfo", driverInfo);
190     EDM_LOGI(MODULE_PKG_MGR, "bundleName: %{public}s driverInfo: %{public}s",
191         bundleName.c_str(), driverInfo.c_str());
192     if (isUpdate) {
193         int32_t changedRows = 0;
194         ret = rightDatabase_->Update(changedRows, values, "bundleAbility = ?",
195             std::vector<std::string> {bundleAbility});
196     } else {
197         ret = rightDatabase_->Insert(values);
198     }
199     if (ret < PKG_OK) {
200         EDM_LOGE(MODULE_PKG_MGR, "Insert or Update error: %{public}d", ret);
201         (void)rightDatabase_->RollBack();
202     }
203     return ret;
204 }
205 
QueryAllDriverInfos(std::vector<std::string> & driverInfos)206 int32_t PkgDbHelper::QueryAllDriverInfos(std::vector<std::string> &driverInfos)
207 {
208     std::lock_guard<std::mutex> guard(databaseMutex_);
209     std::vector<std::string> columns = {"driverInfo"};
210     RdbPredicates rdbPredicates(PKG_TABLE_NAME);
211     return QueryAndGetResultColumnValues(rdbPredicates, columns, "driverInfo", driverInfos);
212 }
213 
QueryAllBundleAbilityNames(const std::string & bundleName,std::vector<std::string> & bundleAbilityNames)214 int32_t PkgDbHelper::QueryAllBundleAbilityNames(const std::string &bundleName,
215     std::vector<std::string> &bundleAbilityNames)
216 {
217     std::lock_guard<std::mutex> guard(databaseMutex_);
218     std::vector<std::string> columns = {"bundleAbility"};
219     RdbPredicates rdbPredicates(PKG_TABLE_NAME);
220     rdbPredicates.EqualTo("bundleName", bundleName)->Distinct();
221     return QueryAndGetResultColumnValues(rdbPredicates, columns, "bundleAbility", bundleAbilityNames);
222 }
223 
ParseToPkgInfos(const std::shared_ptr<ResultSet> & resultSet,std::vector<PkgInfoTable> & pkgInfos)224 static bool ParseToPkgInfos(const std::shared_ptr<ResultSet> &resultSet, std::vector<PkgInfoTable> &pkgInfos)
225 {
226     if (resultSet == nullptr) {
227         EDM_LOGE(MODULE_PKG_MGR, "resultSet is nullptr");
228         return false;
229     }
230     int32_t rowCount = 0;
231     int32_t driverUidIndex = 0;
232     int32_t bundleNameIndex = 0;
233     int32_t driverNameIndex = 0;
234     int32_t driverInfoIndex = 0;
235     if (resultSet->GetRowCount(rowCount) != E_OK
236         || resultSet->GetColumnIndex("driverUid", driverUidIndex) != E_OK
237         || resultSet->GetColumnIndex("bundleName", bundleNameIndex) != E_OK
238         || resultSet->GetColumnIndex("driverName", driverNameIndex) != E_OK
239         || resultSet->GetColumnIndex("driverInfo", driverInfoIndex) != E_OK) {
240         EDM_LOGE(MODULE_PKG_MGR, "get table info failed");
241         return false;
242     }
243     EDM_LOGD(MODULE_PKG_MGR, "rowCount=%{public}d", rowCount);
244     bool endFlag = false;
245     for (int32_t i = 0; i < rowCount && !endFlag; i++, resultSet->IsEnded(endFlag)) {
246         if (resultSet->GoToRow(i) != E_OK) {
247             EDM_LOGE(MODULE_PKG_MGR, "GoToRow %{public}d", i);
248             return false;
249         }
250 
251         PkgInfoTable pkgInfo;
252         if (resultSet->GetString(driverUidIndex, pkgInfo.driverUid) != E_OK
253             || resultSet->GetString(bundleNameIndex, pkgInfo.bundleName) != E_OK
254             || resultSet->GetString(driverNameIndex, pkgInfo.driverName) != E_OK
255             || resultSet->GetString(driverInfoIndex, pkgInfo.driverInfo) != E_OK) {
256             EDM_LOGE(MODULE_PKG_MGR, "GetString failed");
257             return false;
258         }
259         pkgInfos.push_back(pkgInfo);
260     }
261     return true;
262 }
263 
QueryPkgInfos(std::vector<PkgInfoTable> & pkgInfos,bool isByDriverUid,const std::string & driverUid)264 int32_t PkgDbHelper::QueryPkgInfos(std::vector<PkgInfoTable> &pkgInfos,
265     bool isByDriverUid, const std::string &driverUid)
266 {
267     std::lock_guard<std::mutex> guard(databaseMutex_);
268     std::vector<std::string> columns = { "driverUid", "bundleName", "driverName", "driverInfo" };
269     RdbPredicates rdbPredicates(PKG_TABLE_NAME);
270     if (isByDriverUid) {
271         rdbPredicates.EqualTo("driverUid", driverUid);
272     }
273     int32_t ret = rightDatabase_->BeginTransaction();
274     if (ret < PKG_OK) {
275         EDM_LOGE(MODULE_PKG_MGR, "BeginTransaction error: %{public}d", ret);
276         return ret;
277     }
278     auto resultSet = rightDatabase_->Query(rdbPredicates, columns);
279     if (resultSet == nullptr) {
280         EDM_LOGE(MODULE_PKG_MGR, "Query error");
281         (void)rightDatabase_->RollBack();
282         return PKG_RDB_EXECUTE_FAILTURE;
283     }
284     ret = rightDatabase_->Commit();
285     if (ret < PKG_OK) {
286         EDM_LOGE(MODULE_PKG_MGR, "Commit error: %{public}d", ret);
287         (void)rightDatabase_->RollBack();
288         return ret;
289     }
290     if (!ParseToPkgInfos(resultSet, pkgInfos)) {
291         EDM_LOGE(MODULE_PKG_MGR, "ParseToPkgInfos failed");
292         return PKG_FAILURE;
293     }
294 
295     return static_cast<int32_t>(pkgInfos.size());
296 }
297 
QueryAllSize(std::vector<std::string> & allBundleAbility)298 int32_t PkgDbHelper::QueryAllSize(std::vector<std::string> &allBundleAbility)
299 {
300     std::lock_guard<std::mutex> guard(databaseMutex_);
301     std::vector<std::string> columns = {"bundleAbility"};
302     RdbPredicates rdbPredicates(PKG_TABLE_NAME);
303     return QueryAndGetResultColumnValues(rdbPredicates, columns, "bundleAbility", allBundleAbility);
304 }
305 
QueryAndGetResultColumnValues(const RdbPredicates & rdbPredicates,const std::vector<std::string> & columns,const std::string & columnName,std::vector<std::string> & columnValues)306 int32_t PkgDbHelper::QueryAndGetResultColumnValues(const RdbPredicates &rdbPredicates,
307     const std::vector<std::string> &columns, const std::string &columnName, std::vector<std::string> &columnValues)
308 {
309     int32_t ret = rightDatabase_->BeginTransaction();
310     if (ret < PKG_OK) {
311         EDM_LOGE(MODULE_PKG_MGR, "BeginTransaction error: %{public}d", ret);
312         return ret;
313     }
314     auto resultSet = rightDatabase_->Query(rdbPredicates, columns);
315     if (resultSet == nullptr) {
316         EDM_LOGE(MODULE_PKG_MGR, "Query error");
317         (void)rightDatabase_->RollBack();
318         return PKG_RDB_EXECUTE_FAILTURE;
319     }
320     ret = rightDatabase_->Commit();
321     if (ret < PKG_OK) {
322         EDM_LOGE(MODULE_PKG_MGR, "Commit error: %{public}d", ret);
323         (void)rightDatabase_->RollBack();
324         return ret;
325     }
326     int32_t rowCount = 0;
327     int32_t columnIndex = 0;
328     if (resultSet->GetRowCount(rowCount) != E_OK || resultSet->GetColumnIndex(columnName, columnIndex) != E_OK) {
329         EDM_LOGE(MODULE_PKG_MGR, "get table info failed");
330         return PKG_RDB_EXECUTE_FAILTURE;
331     }
332     bool endFlag = false;
333     for (int32_t i = 0; (i < rowCount) && !endFlag; i++) {
334         if (resultSet->GoToRow(i) != E_OK) {
335             EDM_LOGE(MODULE_PKG_MGR, "GoToRow %{public}d", i);
336             return PKG_RDB_EXECUTE_FAILTURE;
337         }
338         std::string tempStr;
339         if (resultSet->GetString(columnIndex, tempStr) == E_OK) {
340             columnValues.push_back(tempStr);
341         }
342         resultSet->IsEnded(endFlag);
343     }
344     int32_t position = 0;
345     resultSet->GetRowIndex(position);
346     resultSet->IsEnded(endFlag);
347     EDM_LOGI(MODULE_PKG_MGR, "idx=%{public}d rows=%{public}d pos=%{public}d ret=%{public}zu end=%{public}s",
348         columnIndex, rowCount, position, columnValues.size(), (endFlag ? "yes" : "no"));
349     return columnValues.size();
350 }
351 
QueryBundleInfoNames(const std::string & driverInfo)352 std::string PkgDbHelper::QueryBundleInfoNames(const std::string &driverInfo)
353 {
354     std::lock_guard<std::mutex> guard(databaseMutex_);
355     std::vector<std::string> columns = {"bundleAbility"};
356     RdbPredicates rdbPredicates(PKG_TABLE_NAME);
357     rdbPredicates.EqualTo("driverInfo", driverInfo)->Distinct();
358     int32_t ret = rightDatabase_->BeginTransaction();
359     if (ret < PKG_OK) {
360         EDM_LOGE(MODULE_PKG_MGR, "BeginTransaction error: %{public}d", ret);
361         return "";
362     }
363     auto resultSet = rightDatabase_->Query(rdbPredicates, columns);
364     if (resultSet == nullptr) {
365         EDM_LOGE(MODULE_PKG_MGR, "Query error");
366         (void)rightDatabase_->RollBack();
367         return "";
368     }
369     ret = rightDatabase_->Commit();
370     if (ret < PKG_OK) {
371         EDM_LOGE(MODULE_PKG_MGR, "Commit error: %{public}d", ret);
372         (void)rightDatabase_->RollBack();
373         return "";
374     }
375     int32_t rowCount = 0;
376     ret = resultSet->GetRowCount(rowCount);
377     if (ret != E_OK || rowCount == 0) {
378         EDM_LOGE(MODULE_PKG_MGR, "Query data error: %{public}d, count: %{public}d", ret, rowCount);
379         return "";
380     }
381     ret = resultSet->GoToRow(0);
382     if (ret != E_OK) {
383         EDM_LOGE(MODULE_PKG_MGR, "GoToRow 0 error: %{public}d", ret);
384         return "";
385     }
386     std::string s;
387     ret = resultSet->GetString(0, s);
388     if (ret != E_OK) {
389         EDM_LOGE(MODULE_PKG_MGR, "get value error: %{public}d", ret);
390         return "";
391     }
392     return s;
393 }
394 } // namespace USB
395 } // namespace OHOS
396