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_LOGI(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 userIdIndex = 0;
233 int32_t bundleNameIndex = 0;
234 int32_t driverNameIndex = 0;
235 int32_t driverInfoIndex = 0;
236 if (resultSet->GetRowCount(rowCount) != E_OK
237 || resultSet->GetColumnIndex("driverUid", driverUidIndex) != E_OK
238 || resultSet->GetColumnIndex("userId", userIdIndex) != E_OK
239 || resultSet->GetColumnIndex("bundleName", bundleNameIndex) != E_OK
240 || resultSet->GetColumnIndex("driverName", driverNameIndex) != E_OK
241 || resultSet->GetColumnIndex("driverInfo", driverInfoIndex) != E_OK) {
242 EDM_LOGE(MODULE_PKG_MGR, "get table info failed");
243 return false;
244 }
245 EDM_LOGD(MODULE_PKG_MGR, "rowCount=%{public}d", rowCount);
246 bool endFlag = false;
247 for (int32_t i = 0; i < rowCount && !endFlag; i++, resultSet->IsEnded(endFlag)) {
248 if (resultSet->GoToRow(i) != E_OK) {
249 EDM_LOGE(MODULE_PKG_MGR, "GoToRow %{public}d", i);
250 return false;
251 }
252
253 PkgInfoTable pkgInfo;
254 if (resultSet->GetString(driverUidIndex, pkgInfo.driverUid) != E_OK
255 || resultSet->GetLong(userIdIndex, pkgInfo.userId) != E_OK
256 || resultSet->GetString(bundleNameIndex, pkgInfo.bundleName) != E_OK
257 || resultSet->GetString(driverNameIndex, pkgInfo.driverName) != E_OK
258 || resultSet->GetString(driverInfoIndex, pkgInfo.driverInfo) != E_OK) {
259 EDM_LOGE(MODULE_PKG_MGR, "GetString failed");
260 return false;
261 }
262 pkgInfos.push_back(pkgInfo);
263 }
264 return true;
265 }
266
QueryPkgInfos(const std::string & whereKey,const std::string & whereValue,std::vector<PkgInfoTable> & pkgInfos)267 int32_t PkgDbHelper::QueryPkgInfos(const std::string &whereKey, const std::string &whereValue,
268 std::vector<PkgInfoTable> &pkgInfos)
269 {
270 std::lock_guard<std::mutex> guard(databaseMutex_);
271 std::vector<std::string> columns = { "driverUid", "userId", "bundleName", "driverName", "driverInfo" };
272 RdbPredicates rdbPredicates(PKG_TABLE_NAME);
273 if (!whereKey.empty()) {
274 rdbPredicates.EqualTo(whereKey, whereValue);
275 }
276 int32_t ret = rightDatabase_->BeginTransaction();
277 if (ret < PKG_OK) {
278 EDM_LOGE(MODULE_PKG_MGR, "BeginTransaction error: %{public}d", ret);
279 return ret;
280 }
281 auto resultSet = rightDatabase_->Query(rdbPredicates, columns);
282 if (resultSet == nullptr) {
283 EDM_LOGE(MODULE_PKG_MGR, "Query error");
284 (void)rightDatabase_->RollBack();
285 return PKG_RDB_EXECUTE_FAILTURE;
286 }
287 ret = rightDatabase_->Commit();
288 if (ret < PKG_OK) {
289 EDM_LOGE(MODULE_PKG_MGR, "Commit error: %{public}d", ret);
290 (void)rightDatabase_->RollBack();
291 return ret;
292 }
293 if (!ParseToPkgInfos(resultSet, pkgInfos)) {
294 EDM_LOGE(MODULE_PKG_MGR, "ParseToPkgInfos failed");
295 return PKG_FAILURE;
296 }
297
298 return static_cast<int32_t>(pkgInfos.size());
299 }
300
QueryPkgInfos(std::vector<PkgInfoTable> & pkgInfos,bool isByDriverUid,const std::string & driverUid)301 int32_t PkgDbHelper::QueryPkgInfos(std::vector<PkgInfoTable> &pkgInfos,
302 bool isByDriverUid, const std::string &driverUid)
303 {
304 return QueryPkgInfos(isByDriverUid ? "driverUid" : "", driverUid, pkgInfos);
305 }
306
QueryPkgInfos(const std::string & bundleName,std::vector<PkgInfoTable> & pkgInfos)307 int32_t PkgDbHelper::QueryPkgInfos(const std::string &bundleName, std::vector<PkgInfoTable> &pkgInfos)
308 {
309 return QueryPkgInfos(bundleName.empty() ? "" : "bundleName", bundleName, pkgInfos);
310 }
311
QueryAllSize(std::vector<std::string> & allBundleAbility)312 int32_t PkgDbHelper::QueryAllSize(std::vector<std::string> &allBundleAbility)
313 {
314 std::lock_guard<std::mutex> guard(databaseMutex_);
315 std::vector<std::string> columns = {"bundleAbility"};
316 RdbPredicates rdbPredicates(PKG_TABLE_NAME);
317 return QueryAndGetResultColumnValues(rdbPredicates, columns, "bundleAbility", allBundleAbility);
318 }
319
QueryAndGetResultColumnValues(const RdbPredicates & rdbPredicates,const std::vector<std::string> & columns,const std::string & columnName,std::vector<std::string> & columnValues)320 int32_t PkgDbHelper::QueryAndGetResultColumnValues(const RdbPredicates &rdbPredicates,
321 const std::vector<std::string> &columns, const std::string &columnName, std::vector<std::string> &columnValues)
322 {
323 int32_t ret = rightDatabase_->BeginTransaction();
324 if (ret < PKG_OK) {
325 EDM_LOGE(MODULE_PKG_MGR, "BeginTransaction error: %{public}d", ret);
326 return ret;
327 }
328 auto resultSet = rightDatabase_->Query(rdbPredicates, columns);
329 if (resultSet == nullptr) {
330 EDM_LOGE(MODULE_PKG_MGR, "Query error");
331 (void)rightDatabase_->RollBack();
332 return PKG_RDB_EXECUTE_FAILTURE;
333 }
334 ret = rightDatabase_->Commit();
335 if (ret < PKG_OK) {
336 EDM_LOGE(MODULE_PKG_MGR, "Commit error: %{public}d", ret);
337 (void)rightDatabase_->RollBack();
338 return ret;
339 }
340 int32_t rowCount = 0;
341 int32_t columnIndex = 0;
342 if (resultSet->GetRowCount(rowCount) != E_OK || resultSet->GetColumnIndex(columnName, columnIndex) != E_OK) {
343 EDM_LOGE(MODULE_PKG_MGR, "get table info failed");
344 return PKG_RDB_EXECUTE_FAILTURE;
345 }
346 bool endFlag = false;
347 for (int32_t i = 0; (i < rowCount) && !endFlag; i++) {
348 if (resultSet->GoToRow(i) != E_OK) {
349 EDM_LOGE(MODULE_PKG_MGR, "GoToRow %{public}d", i);
350 return PKG_RDB_EXECUTE_FAILTURE;
351 }
352 std::string tempStr;
353 if (resultSet->GetString(columnIndex, tempStr) == E_OK) {
354 columnValues.push_back(tempStr);
355 }
356 resultSet->IsEnded(endFlag);
357 }
358 int32_t position = 0;
359 resultSet->GetRowIndex(position);
360 resultSet->IsEnded(endFlag);
361 EDM_LOGI(MODULE_PKG_MGR, "idx=%{public}d rows=%{public}d pos=%{public}d ret=%{public}zu end=%{public}s",
362 columnIndex, rowCount, position, columnValues.size(), (endFlag ? "yes" : "no"));
363 return columnValues.size();
364 }
365
QueryBundleInfoNames(const std::string & driverInfo)366 std::string PkgDbHelper::QueryBundleInfoNames(const std::string &driverInfo)
367 {
368 std::lock_guard<std::mutex> guard(databaseMutex_);
369 std::vector<std::string> columns = {"bundleAbility"};
370 RdbPredicates rdbPredicates(PKG_TABLE_NAME);
371 rdbPredicates.EqualTo("driverInfo", driverInfo)->Distinct();
372 int32_t ret = rightDatabase_->BeginTransaction();
373 if (ret < PKG_OK) {
374 EDM_LOGE(MODULE_PKG_MGR, "BeginTransaction error: %{public}d", ret);
375 return "";
376 }
377 auto resultSet = rightDatabase_->Query(rdbPredicates, columns);
378 if (resultSet == nullptr) {
379 EDM_LOGE(MODULE_PKG_MGR, "Query error");
380 (void)rightDatabase_->RollBack();
381 return "";
382 }
383 ret = rightDatabase_->Commit();
384 if (ret < PKG_OK) {
385 EDM_LOGE(MODULE_PKG_MGR, "Commit error: %{public}d", ret);
386 (void)rightDatabase_->RollBack();
387 return "";
388 }
389 int32_t rowCount = 0;
390 ret = resultSet->GetRowCount(rowCount);
391 if (ret != E_OK || rowCount == 0) {
392 EDM_LOGE(MODULE_PKG_MGR, "Query data error: %{public}d, count: %{public}d", ret, rowCount);
393 return "";
394 }
395 ret = resultSet->GoToRow(0);
396 if (ret != E_OK) {
397 EDM_LOGE(MODULE_PKG_MGR, "GoToRow 0 error: %{public}d", ret);
398 return "";
399 }
400 std::string s;
401 ret = resultSet->GetString(0, s);
402 if (ret != E_OK) {
403 EDM_LOGE(MODULE_PKG_MGR, "get value error: %{public}d", ret);
404 return "";
405 }
406 return s;
407 }
408 } // namespace USB
409 } // namespace OHOS
410