1 /*
2 * Copyright (c) 2022-2024 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 <iostream>
17 #include <fstream>
18 #include <sys/stat.h>
19 #include <sys/types.h>
20 #include <unistd.h>
21 #include <sstream>
22 #include <cstdlib>
23 #include <algorithm>
24 #include <map>
25 #include <limits>
26 #include <cmath>
27
28 #include "time_service_client.h"
29
30 #include "bundle_active_constant.h"
31 #include "bundle_active_open_callback.h"
32 #include "bundle_active_log.h"
33 #include "bundle_active_package_stats.h"
34 #include "bundle_active_binary_search.h"
35 #include "bundle_active_period_stats.h"
36 #include "bundle_active_usage_database.h"
37 #include "bundle_active_bundle_mgr_helper.h"
38 #include "bundle_active_account_helper.h"
39
40 namespace OHOS {
41 namespace DeviceUsageStats {
42 using namespace OHOS::NativeRdb;
43 using namespace std;
44 namespace {
45 const int32_t MAX_FILES_EVERY_INTERVAL_TYPE[SORTED_TABLE_ARRAY_NUMBER] = {30, 30, 12, 10};
46 const int32_t MAIN_APP_INDEX = 0;
47 const int32_t FILE_VERSION_LINE_NUM = 50;
48 }
BundleActiveUsageDatabase()49 BundleActiveUsageDatabase::BundleActiveUsageDatabase()
50 {
51 currentVersion_ = BUNDLE_ACTIVE_CURRENT_VERSION;
52 for (uint32_t i = 0; i < sizeof(DATABASE_TYPE)/sizeof(DATABASE_TYPE[0]); i++) {
53 databaseFiles_.push_back(DATABASE_TYPE[i] + SUFFIX_TYPE[0]);
54 }
55 eventTableName_ = UNKNOWN_TABLE_NAME;
56 durationTableName_ = UNKNOWN_TABLE_NAME;
57 bundleHistoryTableName_ = UNKNOWN_TABLE_NAME;
58 moduleRecordsTableName_ = UNKNOWN_TABLE_NAME;
59 formRecordsTableName_ = UNKNOWN_TABLE_NAME;
60 sortedTableArray_ = vector<vector<int64_t>>(SORTED_TABLE_ARRAY_NUMBER);
61 calendar_ = make_shared<BundleActiveCalendar>();
62 eventBeginTime_ = EVENT_BEGIN_TIME_INITIAL_VALUE;
63 debugDatabase_ = false;
64 }
65
~BundleActiveUsageDatabase()66 BundleActiveUsageDatabase::~BundleActiveUsageDatabase()
67 {
68 RdbHelper::ClearCache();
69 }
70
ChangeToDebug()71 void BundleActiveUsageDatabase::ChangeToDebug()
72 {
73 calendar_->ChangeToDebug();
74 debugDatabase_ = true;
75 }
76
InitUsageGroupDatabase(const int32_t databaseType, const bool forModuleRecords)77 void BundleActiveUsageDatabase::InitUsageGroupDatabase(const int32_t databaseType, const bool forModuleRecords)
78 {
79 lock_guard<ffrt::mutex> lock(databaseMutex_);
80 if (CreateDatabasePath() == BUNDLE_ACTIVE_FAIL) {
81 BUNDLE_ACTIVE_LOGE("database path is not exist");
82 return;
83 }
84 if (databaseType != APP_GROUP_DATABASE_INDEX) {
85 BUNDLE_ACTIVE_LOGE("databaseType is invalid, databaseType = %{public}d", databaseType);
86 return;
87 }
88 string queryDatabaseTableNames = "select * from sqlite_master where type = ?";
89 vector<string> queryCondition;
90 queryCondition.push_back(DATABASE_FILE_TABLE_NAME);
91 auto bundleActiveResult = QueryStatsInfoByStep(databaseType,
92 queryDatabaseTableNames, queryCondition);
93 if (bundleActiveResult == nullptr) {
94 BUNDLE_ACTIVE_LOGE("bundleActiveResult is invalid");
95 return;
96 }
97 int32_t tableNumber;
98 bundleActiveResult->GetRowCount(tableNumber);
99 if (tableNumber == TABLE_NOT_EXIST) {
100 BUNDLE_ACTIVE_LOGE("table not exist");
101 return;
102 }
103 int32_t tableNameIndex;
104 bundleActiveResult->GetColumnIndex(SQLITE_MASTER_NAME, tableNameIndex);
105 string tableName;
106 for (int32_t i = 0; i < tableNumber; i++) {
107 bundleActiveResult->GoToRow(i);
108 bundleActiveResult->GetString(tableNameIndex, tableName);
109 if (!forModuleRecords) {
110 if (DURATION_LOG_TABLE == tableName) {
111 durationTableName_ = DURATION_LOG_TABLE;
112 } else if (BUNDLE_HISTORY_LOG_TABLE == tableName) {
113 bundleHistoryTableName_ = BUNDLE_HISTORY_LOG_TABLE;
114 }
115 } else {
116 if (tableName.find(MODULE_RECORD_LOG_TABLE.c_str()) != tableName.npos) {
117 moduleRecordsTableName_ = tableName;
118 } else if (tableName.find(FORM_RECORD_LOG_TABLE.c_str()) != tableName.npos) {
119 formRecordsTableName_ = tableName;
120 }
121 }
122 }
123 }
124
CreateDatabasePath()125 int32_t BundleActiveUsageDatabase::CreateDatabasePath()
126 {
127 if (access(BUNDLE_ACTIVE_DATABASE_DIR.c_str(), F_OK) != 0) {
128 int32_t createDir = mkdir(BUNDLE_ACTIVE_DATABASE_DIR.c_str(), S_IRWXU);
129 if (createDir != 0) {
130 BUNDLE_ACTIVE_LOGE("failed to create directory %{public}s", BUNDLE_ACTIVE_DATABASE_DIR.c_str());
131 return BUNDLE_ACTIVE_FAIL;
132 }
133 }
134 return BUNDLE_ACTIVE_SUCCESS;
135 }
136
InitDatabaseTableInfo(int64_t currentTime)137 void BundleActiveUsageDatabase::InitDatabaseTableInfo(int64_t currentTime)
138 {
139 lock_guard<ffrt::mutex> lock(databaseMutex_);
140 if (CreateDatabasePath() == BUNDLE_ACTIVE_FAIL) {
141 BUNDLE_ACTIVE_LOGE("database path is not exist");
142 return;
143 }
144 CheckDatabaseVersion();
145 for (uint32_t i = 0; i < databaseFiles_.size(); i++) {
146 HandleTableInfo(i);
147 DeleteExcessiveTableData(i);
148 }
149 for (uint32_t i = 0; i < sortedTableArray_.size(); i++) {
150 int32_t startIndex = NearIndexOnOrAfterCurrentTime(currentTime, sortedTableArray_.at(i));
151 if (startIndex < BUNDLE_ACTIVE_SUCCESS) {
152 continue;
153 }
154 int32_t tableNumber = static_cast<int32_t>(sortedTableArray_.at(i).size());
155 for (int32_t j = startIndex; j < tableNumber; j++) {
156 DeleteInvalidTable(i, sortedTableArray_.at(i).at(startIndex));
157 sortedTableArray_.at(i).erase(sortedTableArray_.at(i).begin() + startIndex);
158 }
159 }
160 if (eventTableName_ != UNKNOWN_TABLE_NAME) {
161 int64_t eventTableTime = ParseStartTime(eventTableName_);
162 if (currentTime < eventTableTime) {
163 DeleteInvalidTable(EVENT_DATABASE_INDEX, eventTableTime);
164 }
165 }
166 }
167
NearIndexOnOrAfterCurrentTime(int64_t currentTime, vector<int64_t> &sortedTableArray)168 int32_t BundleActiveUsageDatabase::NearIndexOnOrAfterCurrentTime(int64_t currentTime,
169 vector<int64_t> &sortedTableArray)
170 {
171 int32_t low = 0;
172 int32_t high = static_cast<int32_t>(sortedTableArray.size() - 1);
173 int32_t mid = -1;
174 int64_t tableTime = -1;
175 int32_t divisor = 2;
176 while (low <= high) {
177 mid = (high + low) / divisor;
178 tableTime = sortedTableArray.at(mid);
179 if (currentTime > tableTime) {
180 low = mid + 1;
181 } else if (currentTime < tableTime) {
182 high = mid - 1;
183 } else {
184 return mid;
185 }
186 }
187 if (currentTime < tableTime) {
188 return mid;
189 } else if (currentTime > tableTime && low < static_cast<int32_t>(sortedTableArray.size())) {
190 return low;
191 } else {
192 return BUNDLE_ACTIVE_FAIL;
193 }
194 }
195
NearIndexOnOrBeforeCurrentTime(int64_t currentTime, vector<int64_t> &sortedTableArray)196 int32_t BundleActiveUsageDatabase::NearIndexOnOrBeforeCurrentTime(int64_t currentTime,
197 vector<int64_t> &sortedTableArray)
198 {
199 int32_t index = NearIndexOnOrAfterCurrentTime(currentTime, sortedTableArray);
200 if (index < 0) {
201 return sortedTableArray.size() - 1;
202 }
203 if (sortedTableArray.at(index) == currentTime) {
204 return index;
205 }
206 return index - 1;
207 }
208
QueryStatsInfoByStep(uint32_t databaseType, const string &sql, const vector<string> &selectionArgs)209 shared_ptr<NativeRdb::ResultSet> WEAK_FUNC BundleActiveUsageDatabase::QueryStatsInfoByStep(uint32_t databaseType,
210 const string &sql, const vector<string> &selectionArgs)
211 {
212 shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(databaseType);
213 if (rdbStore == nullptr) {
214 BUNDLE_ACTIVE_LOGE("query stats info by step fail, rdbStore is nullptr");
215 return nullptr;
216 }
217 shared_ptr<NativeRdb::ResultSet> result;
218 if (selectionArgs.empty()) {
219 result = rdbStore->QueryByStep(sql);
220 } else {
221 result = rdbStore->QueryByStep(sql, selectionArgs);
222 }
223 return result;
224 }
225
HandleTableInfo(uint32_t databaseType)226 void BundleActiveUsageDatabase::HandleTableInfo(uint32_t databaseType)
227 {
228 string queryDatabaseTableNames = "select * from sqlite_master where type = ?";
229 vector<string> queryCondition;
230 queryCondition.push_back(DATABASE_FILE_TABLE_NAME);
231 auto bundleActiveResult = QueryStatsInfoByStep(databaseType,
232 queryDatabaseTableNames, queryCondition);
233 if (bundleActiveResult == nullptr) {
234 BUNDLE_ACTIVE_LOGE("bundleActiveResult is invalid");
235 return;
236 }
237 int32_t tableNumber;
238 bundleActiveResult->GetRowCount(tableNumber);
239 if (tableNumber == TABLE_NOT_EXIST) {
240 BUNDLE_ACTIVE_LOGE("table not exist");
241 return;
242 }
243 int32_t tableNameIndex;
244 bundleActiveResult->GetColumnIndex(SQLITE_MASTER_NAME, tableNameIndex);
245 if (databaseType >= 0 && databaseType < sortedTableArray_.size()) {
246 if (!sortedTableArray_.at(databaseType).empty()) {
247 sortedTableArray_.at(databaseType).clear();
248 }
249 for (int32_t i = 0; i < tableNumber; i++) {
250 string tableName;
251 bundleActiveResult->GoToRow(i);
252 bundleActiveResult->GetString(tableNameIndex, tableName);
253 sortedTableArray_.at(databaseType).push_back(ParseStartTime(tableName));
254 }
255 if (!sortedTableArray_.at(databaseType).empty()) {
256 sort(sortedTableArray_.at(databaseType).begin(), sortedTableArray_.at(databaseType).end());
257 }
258 if ((databaseType == DAILY_DATABASE_INDEX) && !sortedTableArray_.at(databaseType).empty()) {
259 size_t lastTableIndex = sortedTableArray_.at(databaseType).size();
260 if (lastTableIndex == 0) {
261 return;
262 }
263 eventBeginTime_ = sortedTableArray_.at(databaseType).at(lastTableIndex -1);
264 }
265 } else if (databaseType == EVENT_DATABASE_INDEX) {
266 if (tableNumber == EVENT_TABLE_NUMBER) {
267 bundleActiveResult->GoToRow(tableNumber - EVENT_TABLE_NUMBER);
268 bundleActiveResult->GetString(tableNameIndex, eventTableName_);
269 }
270 }
271 }
272
HandleAllTableName(const uint32_t databaseType, std::vector<std::vector<std::string>>& allTableName)273 void BundleActiveUsageDatabase::HandleAllTableName(const uint32_t databaseType,
274 std::vector<std::vector<std::string>>& allTableName)
275 {
276 string queryDatabaseTableNames = "select * from sqlite_master where type = ?";
277 vector<string> queryCondition;
278 queryCondition.push_back(DATABASE_FILE_TABLE_NAME);
279 auto bundleActiveResult = QueryStatsInfoByStep(databaseType,
280 queryDatabaseTableNames, queryCondition);
281 if (bundleActiveResult == nullptr) {
282 BUNDLE_ACTIVE_LOGE("bundleActiveResult is invalid");
283 return;
284 }
285 int32_t tableNumber;
286 bundleActiveResult->GetRowCount(tableNumber);
287 if (tableNumber == TABLE_NOT_EXIST) {
288 BUNDLE_ACTIVE_LOGE("table not exist");
289 return;
290 }
291 int32_t tableNameIndex;
292 bundleActiveResult->GetColumnIndex(SQLITE_MASTER_NAME, tableNameIndex);
293 for (int32_t i = 0; i < tableNumber; i++) {
294 string tableName;
295 bundleActiveResult->GoToRow(i);
296 bundleActiveResult->GetString(tableNameIndex, tableName);
297 allTableName.at(databaseType).push_back(tableName);
298 }
299 }
300
DeleteExcessiveTableData(uint32_t databaseType)301 void BundleActiveUsageDatabase::DeleteExcessiveTableData(uint32_t databaseType)
302 {
303 if (databaseType >= 0 && databaseType < SORTED_TABLE_ARRAY_NUMBER) {
304 if (sortedTableArray_.at(databaseType).empty()) {
305 BUNDLE_ACTIVE_LOGE("database table not exist");
306 return;
307 }
308 int32_t existingNumber = static_cast<int32_t>(sortedTableArray_.at(databaseType).size());
309 int32_t deleteNumber = existingNumber - MAX_FILES_EVERY_INTERVAL_TYPE[databaseType];
310 if (deleteNumber > 0) {
311 for (int32_t i = 0; i < deleteNumber; i++) {
312 // 删除多余文件
313 DeleteInvalidTable(databaseType, sortedTableArray_.at(databaseType).at(0));
314 sortedTableArray_.at(databaseType).erase(sortedTableArray_.at(databaseType).begin());
315 }
316 BUNDLE_ACTIVE_LOGD("BundleActiveUsageDatabase DeleteExcessiveTableData Deleted %{public}d tables from "
317 "database type %{public}d", deleteNumber, databaseType);
318 }
319 } else if (databaseType == EVENT_DATABASE_INDEX) {
320 // 删除多余数据
321 if ((eventTableName_ == UNKNOWN_TABLE_NAME) || (eventBeginTime_ == EVENT_BEGIN_TIME_INITIAL_VALUE)) {
322 return;
323 }
324 int64_t eventTableTime = ParseStartTime(eventTableName_);
325 int64_t deleteTimePoint = 0;
326 if (debugDatabase_) {
327 deleteTimePoint = eventBeginTime_ - SIX_DAY_IN_MILLIS_MAX_DEBUG - eventTableTime;
328 } else {
329 deleteTimePoint = eventBeginTime_ - SIX_DAY_IN_MILLIS_MAX - eventTableTime;
330 }
331 if (deleteTimePoint <= 0) {
332 return;
333 }
334 shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(databaseType);
335 if (rdbStore == nullptr) {
336 BUNDLE_ACTIVE_LOGE("delete excessive tableData fail, rdbStore is nullptr");
337 return;
338 }
339 string deleteEventDataSql = "delete from " + eventTableName_ + " where timeStamp <= " +
340 to_string(deleteTimePoint);
341 int32_t deleteResult = rdbStore->ExecuteSql(deleteEventDataSql);
342 if (deleteResult != NativeRdb::E_OK) {
343 BUNDLE_ACTIVE_LOGE("delete event data failed, rdb error number: %{public}d", deleteResult);
344 }
345 } else if (databaseType == APP_GROUP_DATABASE_INDEX) {
346 // 无数据删除
347 } else {
348 BUNDLE_ACTIVE_LOGE("databaseType is invalid, databaseType = %{public}u", databaseType);
349 }
350 }
351
GetOverdueTableCreateTime(uint32_t databaseType, int64_t currentTimeMillis)352 std::unique_ptr<std::vector<int64_t>> BundleActiveUsageDatabase::GetOverdueTableCreateTime(uint32_t databaseType,
353 int64_t currentTimeMillis)
354 {
355 std::unique_ptr<std::vector<int64_t>> overdueTableCreateTime = std::make_unique<std::vector<int64_t>>();
356 if (databaseType >= sortedTableArray_.size()) {
357 BUNDLE_ACTIVE_LOGE("databaseType is invalid, databaseType = %{public}u", databaseType);
358 return nullptr;
359 }
360 string queryDatabaseTableNames = "select * from sqlite_master where type = ?";
361 vector<string> queryCondition;
362 queryCondition.push_back(DATABASE_FILE_TABLE_NAME);
363 auto bundleActiveResult = QueryStatsInfoByStep(databaseType,
364 queryDatabaseTableNames, queryCondition);
365 if (bundleActiveResult == nullptr) {
366 BUNDLE_ACTIVE_LOGE("bundleActiveResult is invalid");
367 return nullptr;
368 }
369 int32_t tableNumber;
370 bundleActiveResult->GetRowCount(tableNumber);
371 if (tableNumber == 0) {
372 BUNDLE_ACTIVE_LOGE("table does not exist");
373 return nullptr;
374 }
375 int32_t tableNameIndex;
376 bundleActiveResult->GetColumnIndex(SQLITE_MASTER_NAME, tableNameIndex);
377 string tableName;
378 for (int32_t i = 0; i < tableNumber; i++) {
379 bundleActiveResult->GoToRow(i);
380 bundleActiveResult->GetString(tableNameIndex, tableName);
381 if (ParseStartTime(tableName) < currentTimeMillis) {
382 overdueTableCreateTime->push_back(ParseStartTime(tableName));
383 }
384 }
385 return overdueTableCreateTime;
386 }
387
DeleteInvalidTable(uint32_t databaseType, int64_t tableTimeMillis)388 int32_t BundleActiveUsageDatabase::DeleteInvalidTable(uint32_t databaseType, int64_t tableTimeMillis)
389 {
390 shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(databaseType);
391 if (rdbStore == nullptr) {
392 BUNDLE_ACTIVE_LOGE("delete invalid table fail, rdbStore is nullptr");
393 return BUNDLE_ACTIVE_FAIL;
394 }
395 if (databaseType >= 0 && databaseType < sortedTableArray_.size()) {
396 string packageTable = PACKAGE_LOG_TABLE + to_string(tableTimeMillis);
397 string deletePackageTableSql = "drop table " + packageTable;
398 int32_t deletePackageTable = rdbStore->ExecuteSql(deletePackageTableSql);
399 if (deletePackageTable != NativeRdb::E_OK) {
400 BUNDLE_ACTIVE_LOGE("delete package table failed, rdb error number: %{public}d", deletePackageTable);
401 return BUNDLE_ACTIVE_FAIL;
402 }
403 } else if (databaseType == EVENT_DATABASE_INDEX) {
404 string eventTable = EVENT_LOG_TABLE + to_string(tableTimeMillis);
405 string deleteEventTableSql = "drop table " + eventTable;
406 int32_t deleteEventTable = rdbStore->ExecuteSql(deleteEventTableSql);
407 if (deleteEventTable != NativeRdb::E_OK) {
408 BUNDLE_ACTIVE_LOGE("delete event table failed, rdb error number: %{public}d", deleteEventTable);
409 return BUNDLE_ACTIVE_FAIL;
410 }
411 } else if (databaseType == APP_GROUP_DATABASE_INDEX) {
412 }
413 return BUNDLE_ACTIVE_SUCCESS;
414 }
415
ParseStartTime(const string &tableName)416 int64_t BundleActiveUsageDatabase::ParseStartTime(const string &tableName)
417 {
418 if (tableName.empty()) {
419 int64_t invalidStartTime(BUNDLE_ACTIVE_FAIL);
420 return invalidStartTime;
421 }
422 string tableTime = tableName;
423 for (uint32_t i = 0; i < tableTime.length(); i++) {
424 if (tableTime[i] >= '0' && tableTime[i] <= '9') {
425 tableTime = tableTime.substr(i);
426 break;
427 }
428 }
429 return atoll(tableTime.c_str());
430 }
431
CheckDatabaseVersion()432 void BundleActiveUsageDatabase::CheckDatabaseVersion()
433 {
434 if (access(BUNDLE_ACTIVE_DATABASE_DIR.c_str(), F_OK) == 0) {
435 int32_t oldVersion = GetOldDbVersion();
436 if (oldVersion != BUNDLE_ACTIVE_FAIL && oldVersion < BUNDLE_ACTIVE_CURRENT_VERSION) {
437 UpgradleDatabase(oldVersion, BUNDLE_ACTIVE_CURRENT_VERSION);
438 }
439 ofstream openVersionFile;
440 openVersionFile.open(BUNDLE_ACTIVE_VERSION_DIRECTORY_PATH, ios::out);
441 if (openVersionFile) {
442 openVersionFile << "version : " << BUNDLE_ACTIVE_CURRENT_VERSION;
443 }
444 openVersionFile.close();
445 }
446 }
447
GetOldDbVersion()448 int32_t BundleActiveUsageDatabase::GetOldDbVersion()
449 {
450 int32_t oldVersion = -1;
451 if (access(BUNDLE_ACTIVE_DATABASE_DIR.c_str(), F_OK) == 0) {
452 ifstream openVersionFile;
453 openVersionFile.open(BUNDLE_ACTIVE_VERSION_DIRECTORY_PATH, ios::in);
454 if (openVersionFile) {
455 char str[FILE_VERSION_LINE_NUM] = {0};
456 openVersionFile.getline(str, FILE_VERSION_LINE_NUM);
457 oldVersion = GetVersionByFileInput(str);
458 }
459 openVersionFile.close();
460 }
461 return oldVersion;
462 }
463
GetVersionByFileInput(const std::string& FileVersionInput)464 int32_t BundleActiveUsageDatabase::GetVersionByFileInput(const std::string& FileVersionInput)
465 {
466 if (FileVersionInput.empty()) {
467 return BUNDLE_ACTIVE_FAIL;
468 }
469 string databaseVersion = FileVersionInput;
470 for (uint32_t i = 0; i < databaseVersion.length(); i++) {
471 if (databaseVersion[i] >= '0' && databaseVersion[i] <= '9') {
472 databaseVersion = databaseVersion.substr(i);
473 break;
474 }
475 }
476 return atoi(databaseVersion.c_str());
477 }
478
UpgradleDatabase(const int32_t oldVersion, const int32_t curVersion)479 void BundleActiveUsageDatabase::UpgradleDatabase(const int32_t oldVersion, const int32_t curVersion)
480 {
481 BUNDLE_ACTIVE_LOGI("upgradle database oldVersion: %{public}d, curVersion: %{public}d", oldVersion, curVersion);
482 if (oldVersion < curVersion && curVersion == BUNDLE_ACTIVE_CURRENT_VERSION) {
483 if (oldVersion == BUNDLE_ACTIVE_VERSION_V1) {
484 SupportAppTwin();
485 }
486 }
487 }
488
SupportAppTwin()489 void BundleActiveUsageDatabase::SupportAppTwin()
490 {
491 vector<vector<string>> allTableName = vector<vector<string>>(ALL_TABLE_ARRAY_NUMBER);
492 for (uint32_t i = 0; i <databaseFiles_.size(); i++) {
493 HandleAllTableName(i, allTableName);
494 }
495
496 map<string, int32_t> bundleNameUidMap;
497 vector<int32_t> activatedOsAccountIds;
498 BundleActiveAccountHelper::GetActiveUserId(activatedOsAccountIds);
499 for (uint32_t i = 0; i < allTableName.size(); i++) {
500 auto tableNames = allTableName.at(i);
501 shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(i);
502 if (!rdbStore) {
503 BUNDLE_ACTIVE_LOGI("get RdbStore fail, databaseType: %{public}u", i);
504 continue;
505 }
506 for (string tableName: tableNames) {
507 if (DURATION_LOG_TABLE == tableName) {
508 continue;
509 }
510 AddRdbColumn(rdbStore, tableName, BUNDLE_ACTIVE_DB_UID, RDB_STORE_COLUMN_TYPE_INT);
511 for (auto userId: activatedOsAccountIds) {
512 UpdateOldDataUid(rdbStore, tableName, userId, bundleNameUidMap);
513 }
514 }
515 }
516 }
517
AddRdbColumn(const shared_ptr<NativeRdb::RdbStore> store, const string& tableName, const string& columnName, const string& columnType)518 void BundleActiveUsageDatabase::AddRdbColumn(const shared_ptr<NativeRdb::RdbStore> store,
519 const string& tableName, const string& columnName, const string& columnType)
520 {
521 string sqlStr = "";
522 if (columnType == RDB_STORE_COLUMN_TYPE_INT) {
523 sqlStr = "ALTER TABLE " + tableName + " ADD " + columnName + " " + columnType + " NOT NULL DEFAULT -1";
524 }
525 store->ExecuteSql(sqlStr);
526 }
527
UpdateOldDataUid(const shared_ptr<NativeRdb::RdbStore> store, const string& tableName, const int32_t userId, map<string, int32_t>& bundleNameUidMap)528 void BundleActiveUsageDatabase::UpdateOldDataUid(const shared_ptr<NativeRdb::RdbStore> store,
529 const string& tableName, const int32_t userId, map<string, int32_t>& bundleNameUidMap)
530 {
531 vector<string> queryCondition;
532 string querySql = "select * from " + tableName;
533 shared_ptr<NativeRdb::ResultSet> bundleActiveResult;
534 bundleActiveResult = store->QueryByStep(querySql);
535 int32_t tableRowNumber = 0;
536 bundleActiveResult->GetRowCount(tableRowNumber);
537 string bundleName;
538 int32_t uid;
539 int32_t changeRow = BUNDLE_ACTIVE_FAIL;
540 NativeRdb::ValuesBucket valuesBucket;
541 for (int32_t i = 0; i < tableRowNumber; i++) {
542 bundleActiveResult->GoToRow(i);
543 bundleActiveResult->GetString(BUNDLE_NAME_COLUMN_INDEX, bundleName);
544 AppExecFwk::ApplicationInfo appInfo;
545 string bundleNameUserIdKey = bundleName + to_string(userId);
546 auto it = bundleNameUidMap.find(bundleNameUserIdKey);
547 if (it == bundleNameUidMap.end()) {
548 BundleActiveBundleMgrHelper::GetInstance()->GetApplicationInfo(bundleName,
549 AppExecFwk::ApplicationFlag::GET_BASIC_APPLICATION_INFO, userId, appInfo);
550 uid = appInfo.uid;
551 bundleNameUidMap[bundleNameUserIdKey] = uid;
552 } else {
553 uid = it->second;
554 }
555 queryCondition.push_back(to_string(userId));
556 queryCondition.push_back(bundleName);
557 valuesBucket.PutInt(BUNDLE_ACTIVE_DB_UID, uid);
558 store->Update(changeRow, tableName, valuesBucket, "userId = ? and bundleName = ?", queryCondition);
559 queryCondition.clear();
560 valuesBucket.Clear();
561 changeRow = BUNDLE_ACTIVE_FAIL;
562 }
563 }
564
GetBundleActiveRdbStore(uint32_t databaseType)565 shared_ptr<NativeRdb::RdbStore> WEAK_FUNC BundleActiveUsageDatabase::GetBundleActiveRdbStore(uint32_t databaseType)
566 {
567 shared_ptr<NativeRdb::RdbStore> rdbStore;
568 string file = databaseFiles_.at(databaseType);
569 if (bundleActiveRdbStoreCache_.find(file) == bundleActiveRdbStoreCache_.end()) {
570 int32_t errCode(BUNDLE_ACTIVE_FAIL);
571 string currDatabaseFileConfig = BUNDLE_ACTIVE_DATABASE_DIR + databaseFiles_.at(databaseType);
572 RdbStoreConfig config(currDatabaseFileConfig);
573 BundleActiveOpenCallback rdbDataCallBack;
574 config.SetJournalMode(NativeRdb::JournalMode::MODE_OFF);
575 config.SetSecurityLevel(NativeRdb::SecurityLevel::S1);
576 rdbStore = RdbHelper::GetRdbStore(config, BUNDLE_ACTIVE_RDB_VERSION, rdbDataCallBack, errCode);
577 if ((rdbStore == nullptr)) {
578 BUNDLE_ACTIVE_LOGE("get bundle active rdbStore fail, rdbStore is nullptr");
579 return nullptr;
580 }
581 bundleActiveRdbStoreCache_.insert(pair {file, rdbStore});
582 } else {
583 rdbStore = bundleActiveRdbStoreCache_[file];
584 }
585 if (rdbStore == nullptr) {
586 BUNDLE_ACTIVE_LOGE("get bundle active rdbStore fail, rdbStore is nullptr");
587 return nullptr;
588 }
589 return rdbStore;
590 }
591
CheckDatabaseFile(uint32_t databaseType)592 void BundleActiveUsageDatabase::CheckDatabaseFile(uint32_t databaseType)
593 {
594 std::string databaseFileName = databaseFiles_.at(databaseType);
595 for (uint32_t i = 0; i < sizeof(SUFFIX_TYPE) / sizeof(SUFFIX_TYPE[0]); i++) {
596 std::string dbFile = BUNDLE_ACTIVE_DATABASE_DIR + DATABASE_TYPE[databaseType] + SUFFIX_TYPE[i];
597 if ((access(dbFile.c_str(), F_OK) != 0)
598 && (bundleActiveRdbStoreCache_.find(databaseFileName) != bundleActiveRdbStoreCache_.end())) {
599 bundleActiveRdbStoreCache_.erase(databaseFileName);
600 std::string rdbStorePath = BUNDLE_ACTIVE_DATABASE_DIR + DATABASE_TYPE[databaseType] + SUFFIX_TYPE[0];
601 RdbHelper::DeleteRdbStore(rdbStorePath);
602 if (databaseType >= 0 && databaseType < sortedTableArray_.size()) {
603 sortedTableArray_.at(databaseType).clear();
604 } else if (databaseType == EVENT_DATABASE_INDEX) {
605 eventTableName_ = UNKNOWN_TABLE_NAME;
606 } else if (databaseType == APP_GROUP_DATABASE_INDEX) {
607 durationTableName_ = UNKNOWN_TABLE_NAME;
608 bundleHistoryTableName_ = UNKNOWN_TABLE_NAME;
609 moduleRecordsTableName_ = UNKNOWN_TABLE_NAME;
610 formRecordsTableName_ = UNKNOWN_TABLE_NAME;
611 }
612 return;
613 }
614 }
615 }
616
CreateEventLogTable(uint32_t databaseType, int64_t currentTimeMillis)617 int32_t BundleActiveUsageDatabase::CreateEventLogTable(uint32_t databaseType, int64_t currentTimeMillis)
618 {
619 shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(databaseType);
620 if (rdbStore == nullptr) {
621 BUNDLE_ACTIVE_LOGE(" create event log table faile, rdbStore is nullptr");
622 return BUNDLE_ACTIVE_FAIL;
623 }
624 string eventTable = EVENT_LOG_TABLE + to_string(currentTimeMillis);
625 eventTableName_ = eventTable;
626 const string createEventTableSql = "CREATE TABLE IF NOT EXISTS "
627 + eventTable
628 + " ("
629 + BUNDLE_ACTIVE_DB_USER_ID + " INTEGER NOT NULL, "
630 + BUNDLE_ACTIVE_DB_BUNDLE_NAME + " TEXT NOT NULL, "
631 + BUNDLE_ACTIVE_DB_EVENT_ID + " INTEGER NOT NULL, "
632 + BUNDLE_ACTIVE_DB_TIME_STAMP + " INTEGER NOT NULL, "
633 + BUNDLE_ACTIVE_DB_ABILITY_ID + " TEXT NOT NULL, "
634 + BUNDLE_ACTIVE_DB_UID + " INTEGER NOT NULL DEFAULT -1);";
635 int32_t createEventTable = rdbStore->ExecuteSql(createEventTableSql);
636 if (createEventTable != NativeRdb::E_OK) {
637 BUNDLE_ACTIVE_LOGE("create event table failed, rdb error number: %{public}d", createEventTable);
638 return createEventTable;
639 }
640 string createEventTableIndex = GetTableIndexSql(EVENT_DATABASE_INDEX, currentTimeMillis, true);
641 int32_t createResult = rdbStore->ExecuteSql(createEventTableIndex);
642 if (createResult != NativeRdb::E_OK) {
643 BUNDLE_ACTIVE_LOGE("create event table index failed, rdb error number: %{public}d", createResult);
644 return BUNDLE_ACTIVE_FAIL;
645 }
646 return BUNDLE_ACTIVE_SUCCESS;
647 }
648
CreatePackageLogTable(uint32_t databaseType, int64_t currentTimeMillis)649 int32_t BundleActiveUsageDatabase::CreatePackageLogTable(uint32_t databaseType, int64_t currentTimeMillis)
650 {
651 shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(databaseType);
652 if (rdbStore == nullptr) {
653 BUNDLE_ACTIVE_LOGE(" create package log table fail, rdbStore is nullptr");
654 return BUNDLE_ACTIVE_FAIL;
655 }
656 string packageTable = PACKAGE_LOG_TABLE + to_string(currentTimeMillis);
657 string createPackageTableSql = "CREATE TABLE IF NOT EXISTS "
658 + packageTable
659 + " ("
660 + BUNDLE_ACTIVE_DB_USER_ID + " INTEGER NOT NULL, "
661 + BUNDLE_ACTIVE_DB_BUNDLE_NAME + " TEXT NOT NULL, "
662 + BUNDLE_ACTIVE_DB_BUNDLE_STARTED_COUNT + " INTEGER NOT NULL, "
663 + BUNDLE_ACTIVE_DB_LAST_TIME + " INTEGER NOT NULL, "
664 + BUNDLE_ACTIVE_DB_LAST_TIME_CONTINUOUS_TASK + " INTEGER NOT NULL, "
665 + BUNDLE_ACTIVE_DB_TOTAL_TIME + " INTEGER NOT NULL, "
666 + BUNDLE_ACTIVE_DB_TOTAL_TIME_CONTINUOUS_TASK + " INTEGER NOT NULL, "
667 + BUNDLE_ACTIVE_DB_UID + " INTEGER NOT NULL DEFAULT -1);";
668 int32_t createPackageTable = rdbStore->ExecuteSql(createPackageTableSql);
669 if (createPackageTable != NativeRdb::E_OK) {
670 BUNDLE_ACTIVE_LOGE("create packageLog table failed, rdb error number: %{public}d", createPackageTable);
671 return BUNDLE_ACTIVE_FAIL;
672 }
673 string createPackageTableIndex = GetTableIndexSql(databaseType, currentTimeMillis, true);
674 int32_t createResult = rdbStore->ExecuteSql(createPackageTableIndex);
675 if (createResult != NativeRdb::E_OK) {
676 BUNDLE_ACTIVE_LOGE("create package table index failed, rdb error number: %{public}d", createResult);
677 return BUNDLE_ACTIVE_FAIL;
678 }
679 return BUNDLE_ACTIVE_SUCCESS;
680 }
681
CreateModuleRecordTable(uint32_t databaseType, int64_t timeStamp)682 int32_t BundleActiveUsageDatabase::CreateModuleRecordTable(uint32_t databaseType, int64_t timeStamp)
683 {
684 shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(databaseType);
685 if (rdbStore == nullptr) {
686 BUNDLE_ACTIVE_LOGE("create module record table fail, rdbStore is nullptr");
687 return BUNDLE_ACTIVE_FAIL;
688 }
689 string moduleRecord = MODULE_RECORD_LOG_TABLE + to_string(timeStamp);
690 moduleRecordsTableName_ = moduleRecord;
691 string createModuleRecordTableSql = "CREATE TABLE IF NOT EXISTS "
692 + moduleRecord
693 + " ("
694 + BUNDLE_ACTIVE_DB_USER_ID + " INTEGER NOT NULL, "
695 + BUNDLE_ACTIVE_DB_BUNDLE_NAME + " TEXT NOT NULL, "
696 + BUNDLE_ACTIVE_DB_MODULE_NAME + " TEXT NOT NULL, "
697 + BUNDLE_ACTIVE_DB_MODULE_LAUNCHED_COUNT + " INTEGER NOT NULL, "
698 + BUNDLE_ACTIVE_DB_LAST_TIME + " INTEGER NOT NULL, "
699 + BUNDLE_ACTIVE_DB_UID + " INTEGER NOT NULL DEFAULT -1);";
700 int32_t createModuleRecordTable = rdbStore->ExecuteSql(createModuleRecordTableSql);
701 if (createModuleRecordTable != NativeRdb::E_OK) {
702 BUNDLE_ACTIVE_LOGE("create ModuleRecord table failed, rdb error number: %{public}d", createModuleRecordTable);
703 return BUNDLE_ACTIVE_FAIL;
704 }
705 string createModuleTableIndex = GetTableIndexSql(databaseType, timeStamp, true, BUNDLE_ACTIVE_DB_INDEX_MODULE);
706 int32_t createResult = rdbStore->ExecuteSql(createModuleTableIndex);
707 if (createResult != NativeRdb::E_OK) {
708 BUNDLE_ACTIVE_LOGE("create module table index failed, rdb error number: %{public}d", createResult);
709 return BUNDLE_ACTIVE_FAIL;
710 }
711 return BUNDLE_ACTIVE_SUCCESS;
712 }
713
CreateFormRecordTable(uint32_t databaseType, int64_t timeStamp)714 int32_t BundleActiveUsageDatabase::CreateFormRecordTable(uint32_t databaseType, int64_t timeStamp)
715 {
716 shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(databaseType);
717 if (rdbStore == nullptr) {
718 BUNDLE_ACTIVE_LOGE("create form record table fail, rdbStore is nullptr");
719 return BUNDLE_ACTIVE_FAIL;
720 }
721 string formRecord = FORM_RECORD_LOG_TABLE + to_string(timeStamp);
722 formRecordsTableName_ = formRecord;
723 string createFormRecordTableSql = "CREATE TABLE IF NOT EXISTS "
724 + formRecord
725 + " ("
726 + BUNDLE_ACTIVE_DB_USER_ID + " INTEGER NOT NULL, "
727 + BUNDLE_ACTIVE_DB_BUNDLE_NAME + " TEXT NOT NULL, "
728 + BUNDLE_ACTIVE_DB_MODULE_NAME + " TEXT NOT NULL, "
729 + BUNDLE_ACTIVE_DB_FORM_NAME + " TEXT NOT NULL, "
730 + BUNDLE_ACTIVE_DB_FORM_DIMENSION + " INTEGER NOT NULL, "
731 + BUNDLE_ACTIVE_DB_FORM_ID + " INTEGER NOT NULL, "
732 + BUNDLE_ACTIVE_DB_FORM_TOUCH_COUNT + " INTEGER NOT NULL, "
733 + BUNDLE_ACTIVE_DB_LAST_TIME + " INTEGER NOT NULL, "
734 + BUNDLE_ACTIVE_DB_UID + " INTEGER NOT NULL DEFAULT -1);";
735 int32_t createFormRecordTable = rdbStore->ExecuteSql(createFormRecordTableSql);
736 if (createFormRecordTable != NativeRdb::E_OK) {
737 BUNDLE_ACTIVE_LOGE("create ModuleRecord table failed, rdb error number: %{public}d", createFormRecordTable);
738 return BUNDLE_ACTIVE_FAIL;
739 }
740 string createFormTableIndex = GetTableIndexSql(databaseType, timeStamp, true, BUNDLE_ACTIVE_DB_INDEX_FORM);
741 int32_t createResult = rdbStore->ExecuteSql(createFormTableIndex);
742 if (createResult != NativeRdb::E_OK) {
743 BUNDLE_ACTIVE_LOGE("create module table index failed, rdb error number: %{public}d", createResult);
744 return BUNDLE_ACTIVE_FAIL;
745 }
746 return BUNDLE_ACTIVE_SUCCESS;
747 }
748
CreateDurationTable(uint32_t databaseType)749 int32_t BundleActiveUsageDatabase::CreateDurationTable(uint32_t databaseType)
750 {
751 shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(databaseType);
752 if (rdbStore == nullptr) {
753 BUNDLE_ACTIVE_LOGE("create duration table fail, rdbStore is nullptr");
754 return BUNDLE_ACTIVE_FAIL;
755 }
756 string createDurationTableSql = "CREATE TABLE IF NOT EXISTS "
757 + DURATION_LOG_TABLE
758 + " ("
759 + BUNDLE_ACTIVE_DB_BOOT_BASED_DURATION + " INTEGER NOT NULL, "
760 + BUNDLE_ACTIVE_DB_SCREEN_ON_DURATION + " INTEGER NOT NULL);";
761 int32_t createDurationTable = rdbStore->ExecuteSql(createDurationTableSql);
762 if (createDurationTable != NativeRdb::E_OK) {
763 BUNDLE_ACTIVE_LOGE("create duration table failed, rdb error number: %{public}d", createDurationTable);
764 return BUNDLE_ACTIVE_FAIL;
765 }
766 return BUNDLE_ACTIVE_SUCCESS;
767 }
768
CreateBundleHistoryTable(uint32_t databaseType)769 int32_t BundleActiveUsageDatabase::CreateBundleHistoryTable(uint32_t databaseType)
770 {
771 shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(databaseType);
772 if (rdbStore == nullptr) {
773 BUNDLE_ACTIVE_LOGE("create bundle history table fail, rdbStore is nullptr");
774 return BUNDLE_ACTIVE_FAIL;
775 }
776 string createBundleHistoryTableSql = "CREATE TABLE IF NOT EXISTS "
777 + BUNDLE_HISTORY_LOG_TABLE
778 + " ("
779 + BUNDLE_ACTIVE_DB_USER_ID + " INTEGER NOT NULL, "
780 + BUNDLE_ACTIVE_DB_BUNDLE_NAME + " TEXT NOT NULL, "
781 + BUNDLE_ACTIVE_DB_LAST_BOOT_FROM_USED_TIME + " INTEGER NOT NULL, "
782 + BUNDLE_ACTIVE_DB_LAST_SCREEN_USED_TIME + " INTEGER NOT NULL, "
783 + BUNDLE_ACTIVE_DB_CURRENT_GROUP + " INTEGER NOT NULL, "
784 + BUNDLE_ACTIVE_DB_REASON_IN_GROUP + " INTEGER NOT NULL, "
785 + BUNDLE_ACTIVE_DB_BUNDLE_ALIVE_TIMEOUT_TIME + " INTEGER NOT NULL, "
786 + BUNDLE_ACTIVE_DB_BUNDLE_DAILY_TIMEOUT_TIME + " INTEGER NOT NULL, "
787 + BUNDLE_ACTIVE_DB_UID + " INTEGER NOT NULL DEFAULT -1);";
788 int32_t createBundleHistoryTable = rdbStore->ExecuteSql(createBundleHistoryTableSql);
789 if (createBundleHistoryTable != NativeRdb::E_OK) {
790 BUNDLE_ACTIVE_LOGE("create bundleHistory table failed, rdb error number: %{public}d", createBundleHistoryTable);
791 return createBundleHistoryTable;
792 }
793 int32_t time = 0;
794 string createBundleHistoryTableIndex = GetTableIndexSql(databaseType, time, true);
795 int32_t createResult = rdbStore->ExecuteSql(createBundleHistoryTableIndex);
796 if (createResult != NativeRdb::E_OK) {
797 BUNDLE_ACTIVE_LOGE("create bundleHistory table index failed, rdb error number: %{public}d", createResult);
798 return BUNDLE_ACTIVE_FAIL;
799 }
800 return BUNDLE_ACTIVE_SUCCESS;
801 }
802
PutBundleHistoryData(int32_t userId, shared_ptr<map<string, shared_ptr<BundleActivePackageHistory>>> userHistory)803 void BundleActiveUsageDatabase::PutBundleHistoryData(int32_t userId,
804 shared_ptr<map<string, shared_ptr<BundleActivePackageHistory>>> userHistory)
805 {
806 lock_guard<ffrt::mutex> lock(databaseMutex_);
807 if (userHistory == nullptr) {
808 return;
809 }
810 shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(APP_GROUP_DATABASE_INDEX);
811 if (userHistory == nullptr || rdbStore == nullptr) {
812 return;
813 }
814 CheckDatabaseFileAndTable();
815 int32_t changeRow = BUNDLE_ACTIVE_FAIL;
816 int64_t outRowId = BUNDLE_ACTIVE_FAIL;
817 NativeRdb::ValuesBucket valuesBucket;
818 vector<string> queryCondition;
819 int32_t updatedcount = 0;
820 int32_t unupdatedcount = 0;
821 for (auto iter = userHistory->begin(); iter != userHistory->end(); iter++) {
822 if (iter->second == nullptr || !iter->second->isChanged_) {
823 unupdatedcount++;
824 continue;
825 }
826 queryCondition.push_back(to_string(userId));
827 queryCondition.push_back(iter->second->bundleName_);
828 queryCondition.push_back(to_string(iter->second->uid_));
829 valuesBucket.PutLong(BUNDLE_ACTIVE_DB_LAST_BOOT_FROM_USED_TIME, iter->second->lastBootFromUsedTimeStamp_);
830 valuesBucket.PutLong(BUNDLE_ACTIVE_DB_LAST_SCREEN_USED_TIME, iter->second->lastScreenUsedTimeStamp_);
831 valuesBucket.PutInt(BUNDLE_ACTIVE_DB_CURRENT_GROUP, iter->second->currentGroup_);
832 valuesBucket.PutInt(BUNDLE_ACTIVE_DB_REASON_IN_GROUP, static_cast<int32_t>(iter->second->reasonInGroup_));
833 valuesBucket.PutLong(BUNDLE_ACTIVE_DB_BUNDLE_ALIVE_TIMEOUT_TIME, iter->second->bundleAliveTimeoutTimeStamp_);
834 valuesBucket.PutLong(BUNDLE_ACTIVE_DB_BUNDLE_DAILY_TIMEOUT_TIME, iter->second->bundleDailyTimeoutTimeStamp_);
835 rdbStore->Update(changeRow, BUNDLE_HISTORY_LOG_TABLE, valuesBucket,
836 "userId = ? and bundleName = ? and uid = ?", queryCondition);
837 if (changeRow == NO_UPDATE_ROW) {
838 valuesBucket.PutString(BUNDLE_ACTIVE_DB_BUNDLE_NAME, iter->second->bundleName_);
839 valuesBucket.PutInt(BUNDLE_ACTIVE_DB_USER_ID, userId);
840 valuesBucket.PutInt(BUNDLE_ACTIVE_DB_UID, iter->second->uid_);
841 rdbStore->Insert(outRowId, BUNDLE_HISTORY_LOG_TABLE, valuesBucket);
842 outRowId = BUNDLE_ACTIVE_FAIL;
843 } else {
844 changeRow = BUNDLE_ACTIVE_FAIL;
845 }
846 valuesBucket.Clear();
847 queryCondition.clear();
848 iter->second->isChanged_ = false;
849 updatedcount++;
850 }
851 BUNDLE_ACTIVE_LOGI("update %{public}d bundles, keep %{public}d bundles group", updatedcount, unupdatedcount);
852 }
853
CheckDatabaseFileAndTable()854 void BundleActiveUsageDatabase::CheckDatabaseFileAndTable()
855 {
856 CheckDatabaseFile(APP_GROUP_DATABASE_INDEX);
857 if (bundleHistoryTableName_ == UNKNOWN_TABLE_NAME) {
858 CreateBundleHistoryTable(APP_GROUP_DATABASE_INDEX);
859 bundleHistoryTableName_ = BUNDLE_HISTORY_LOG_TABLE;
860 }
861 }
862
GetBundleHistoryData( int32_t userId)863 shared_ptr<map<string, shared_ptr<BundleActivePackageHistory>>> BundleActiveUsageDatabase::GetBundleHistoryData(
864 int32_t userId)
865 {
866 lock_guard<ffrt::mutex> lock(databaseMutex_);
867 if (bundleHistoryTableName_ == UNKNOWN_TABLE_NAME) {
868 return nullptr;
869 }
870 string queryHistoryDataSql = "select * from " + BUNDLE_HISTORY_LOG_TABLE + " where userId = ?";
871 vector<string> queryCondition;
872 queryCondition.push_back(to_string(userId));
873 auto bundleActiveResult = QueryStatsInfoByStep(APP_GROUP_DATABASE_INDEX,
874 queryHistoryDataSql, queryCondition);
875 if (bundleActiveResult == nullptr) {
876 return nullptr;
877 }
878 int32_t tableRowNumber;
879 bundleActiveResult->GetRowCount(tableRowNumber);
880 if (tableRowNumber == TABLE_ROW_ZERO) {
881 return nullptr;
882 }
883 shared_ptr<map<string, shared_ptr<BundleActivePackageHistory>>> userUsageHistory =
884 make_shared<map<string, shared_ptr<BundleActivePackageHistory>>>();
885 int32_t currentBundleGroupReason = 0;
886 for (int32_t i = 0; i < tableRowNumber; i++) {
887 bundleActiveResult->GoToRow(i);
888 shared_ptr<BundleActivePackageHistory> usageHistory = make_shared<BundleActivePackageHistory>();
889 bundleActiveResult->GetString(BUNDLE_NAME_COLUMN_INDEX, usageHistory->bundleName_);
890 bundleActiveResult->GetLong(LAST_BOOT_FROM_USED_TIME_COLUMN_INDEX, usageHistory->lastBootFromUsedTimeStamp_);
891 bundleActiveResult->GetLong(LAST_SCREEN_USED_TIME_COLUMN_INDEX, usageHistory->lastScreenUsedTimeStamp_);
892 bundleActiveResult->GetInt(CURRENT_GROUP_COLUMN_INDEX, usageHistory->currentGroup_);
893 bundleActiveResult->GetInt(REASON_IN_GROUP_COLUMN_INDEX, currentBundleGroupReason);
894 usageHistory->reasonInGroup_ = static_cast<uint32_t>(currentBundleGroupReason);
895 bundleActiveResult->GetLong(BUNDLE_ALIVE_TIMEOUT_TIME_COLUMN_INDEX,
896 usageHistory->bundleAliveTimeoutTimeStamp_);
897 bundleActiveResult->GetLong(BUNDLE_DAILY_TIMEOUT_TIME_COLUMN_INDEX,
898 usageHistory->bundleDailyTimeoutTimeStamp_);
899 bundleActiveResult->GetInt(BUNDLE_HISTORY_LOG_UID_COLUMN_INDEX, usageHistory->uid_);
900 string usageHistoryKey = usageHistory->bundleName_ + to_string(usageHistory->uid_);
901 userUsageHistory->insert(pair<string, shared_ptr<BundleActivePackageHistory>>(usageHistoryKey,
902 usageHistory));
903 }
904 return userUsageHistory;
905 }
906
PutDurationData(int64_t bootBasedDuration, int64_t screenOnDuration)907 void BundleActiveUsageDatabase::PutDurationData(int64_t bootBasedDuration, int64_t screenOnDuration)
908 {
909 lock_guard<ffrt::mutex> lock(databaseMutex_);
910 CheckDatabaseFile(APP_GROUP_DATABASE_INDEX);
911 if (durationTableName_ == UNKNOWN_TABLE_NAME) {
912 CreateDurationTable(APP_GROUP_DATABASE_INDEX);
913 durationTableName_ = DURATION_LOG_TABLE;
914 }
915 shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(APP_GROUP_DATABASE_INDEX);
916 if (rdbStore == nullptr) {
917 return;
918 }
919 int32_t changeRow = BUNDLE_ACTIVE_FAIL;
920 int64_t outRowId = BUNDLE_ACTIVE_FAIL;
921 NativeRdb::ValuesBucket valuesBucket;
922 valuesBucket.PutLong(BUNDLE_ACTIVE_DB_BOOT_BASED_DURATION, bootBasedDuration);
923 valuesBucket.PutLong(BUNDLE_ACTIVE_DB_SCREEN_ON_DURATION, screenOnDuration);
924 rdbStore->Update(changeRow, DURATION_LOG_TABLE, valuesBucket);
925 if (changeRow == NO_UPDATE_ROW) {
926 rdbStore->Insert(outRowId, DURATION_LOG_TABLE, valuesBucket);
927 }
928 }
929
GetDurationData()930 pair<int64_t, int64_t> BundleActiveUsageDatabase::GetDurationData()
931 {
932 lock_guard<ffrt::mutex> lock(databaseMutex_);
933 pair<int64_t, int64_t> durationData;
934 if (durationTableName_ == UNKNOWN_TABLE_NAME) {
935 return durationData;
936 }
937 string queryDurationDataSql = "select * from " + DURATION_LOG_TABLE;
938 auto bundleActiveResult = QueryStatsInfoByStep(APP_GROUP_DATABASE_INDEX,
939 queryDurationDataSql,
940 vector<string> {});
941 if (bundleActiveResult == nullptr) {
942 return durationData;
943 }
944 int32_t tableRowNumber;
945 bundleActiveResult->GetRowCount(tableRowNumber);
946 if (tableRowNumber == DURATION_TABLE_ROW_NUMBER) {
947 bundleActiveResult->GoToRow(tableRowNumber - DURATION_TABLE_ROW_NUMBER);
948 bundleActiveResult->GetLong(BOOT_BASED_DURATION_COLUMN_INDEX, durationData.first);
949 bundleActiveResult->GetLong(SCREEN_ON_DURATION_COLUMN_INDEX, durationData.second);
950 }
951 return durationData;
952 }
953
FlushPackageInfo(uint32_t databaseType, const BundleActivePeriodStats &stats)954 void BundleActiveUsageDatabase::FlushPackageInfo(uint32_t databaseType, const BundleActivePeriodStats &stats)
955 {
956 shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(databaseType);
957 if (rdbStore == nullptr) {
958 BUNDLE_ACTIVE_LOGE("flush package info fail, rdbStore is nullptr");
959 return;
960 }
961 string tableName = PACKAGE_LOG_TABLE + to_string(stats.beginTime_);
962 int32_t changeRow = BUNDLE_ACTIVE_FAIL;
963 int64_t outRowId = BUNDLE_ACTIVE_FAIL;
964 NativeRdb::ValuesBucket valuesBucket;
965 vector<string> queryCondition;
966 for (auto iter = stats.bundleStats_.begin(); iter != stats.bundleStats_.end(); iter++) {
967 if (iter->second == nullptr || (iter->second->totalInFrontTime_ == 0 &&
968 iter->second->totalContiniousTaskUsedTime_ == 0)) {
969 continue;
970 }
971 queryCondition.push_back(to_string(stats.userId_));
972 queryCondition.push_back(iter->second->bundleName_);
973 queryCondition.push_back(to_string(iter->second->uid_));
974 valuesBucket.PutLong(BUNDLE_ACTIVE_DB_BUNDLE_STARTED_COUNT, iter->second->startCount_);
975 int64_t lastTimeUsedAdjusted = iter->second->lastTimeUsed_ == -1 ?
976 iter->second->lastTimeUsed_ : iter->second->lastTimeUsed_ - stats.beginTime_;
977 valuesBucket.PutLong(BUNDLE_ACTIVE_DB_LAST_TIME, lastTimeUsedAdjusted);
978 int64_t lastContinuousTaskUsedAdjusted = iter->second->lastContiniousTaskUsed_ == -1 ?
979 iter->second->lastContiniousTaskUsed_ : iter->second->lastContiniousTaskUsed_ - stats.beginTime_;
980 valuesBucket.PutLong(BUNDLE_ACTIVE_DB_LAST_TIME_CONTINUOUS_TASK, lastContinuousTaskUsedAdjusted);
981 valuesBucket.PutLong(BUNDLE_ACTIVE_DB_TOTAL_TIME, iter->second->totalInFrontTime_);
982 valuesBucket.PutLong(BUNDLE_ACTIVE_DB_TOTAL_TIME_CONTINUOUS_TASK, iter->second->totalContiniousTaskUsedTime_);
983 rdbStore->Update(changeRow, tableName, valuesBucket, "userId = ? and bundleName = ? and uid = ?",
984 queryCondition);
985 if (changeRow == NO_UPDATE_ROW) {
986 valuesBucket.PutString(BUNDLE_ACTIVE_DB_BUNDLE_NAME, iter->second->bundleName_);
987 valuesBucket.PutInt(BUNDLE_ACTIVE_DB_USER_ID, stats.userId_);
988 valuesBucket.PutInt(BUNDLE_ACTIVE_DB_UID, iter->second->uid_);
989 rdbStore->Insert(outRowId, tableName, valuesBucket);
990 outRowId = BUNDLE_ACTIVE_FAIL;
991 } else {
992 changeRow = BUNDLE_ACTIVE_FAIL;
993 }
994 valuesBucket.Clear();
995 queryCondition.clear();
996 }
997 }
998
GetCurrentUsageData(int32_t databaseType, int32_t userId)999 shared_ptr<BundleActivePeriodStats> BundleActiveUsageDatabase::GetCurrentUsageData(int32_t databaseType,
1000 int32_t userId)
1001 {
1002 lock_guard<ffrt::mutex> lock(databaseMutex_);
1003 if (databaseType < 0 || databaseType >= static_cast<int32_t>(sortedTableArray_.size())) {
1004 return nullptr;
1005 }
1006 int32_t tableNumber = static_cast<int32_t>(sortedTableArray_.at(databaseType).size());
1007 if (tableNumber == TABLE_NOT_EXIST) {
1008 return nullptr;
1009 }
1010 int64_t currentPackageTime = sortedTableArray_.at(databaseType).at(tableNumber - 1);
1011 auto intervalStats = make_shared<BundleActivePeriodStats>(userId, currentPackageTime);
1012 string packageTableName = PACKAGE_LOG_TABLE + to_string(currentPackageTime);
1013 string queryPackageSql = "select * from " + packageTableName + " where userId = ?";
1014 vector<string> queryCondition;
1015 queryCondition.push_back(to_string(userId));
1016 auto bundleActiveResult = QueryStatsInfoByStep(databaseType, queryPackageSql, queryCondition);
1017 if (bundleActiveResult == nullptr) {
1018 return nullptr;
1019 }
1020 int32_t tableRowNumber;
1021 bundleActiveResult->GetRowCount(tableRowNumber);
1022 map<string, shared_ptr<BundleActivePackageStats>> bundleStats;
1023 int64_t relativeLastTimeUsed;
1024 int64_t relativeLastTimeFrontServiceUsed;
1025 for (int32_t i = 0; i < tableRowNumber; i++) {
1026 shared_ptr<BundleActivePackageStats> usageStats = make_shared<BundleActivePackageStats>();
1027 bundleActiveResult->GoToRow(i);
1028 bundleActiveResult->GetInt(USER_ID_COLUMN_INDEX, intervalStats->userId_);
1029 bundleActiveResult->GetString(BUNDLE_NAME_COLUMN_INDEX, usageStats->bundleName_);
1030 bundleActiveResult->GetInt(BUNDLE_STARTED_COUNT_COLUMN_INDEX, usageStats->startCount_);
1031 bundleActiveResult->GetLong(LAST_TIME_COLUMN_INDEX, relativeLastTimeUsed);
1032 usageStats->lastTimeUsed_ = relativeLastTimeUsed == -1 ? -1 : relativeLastTimeUsed + currentPackageTime;
1033 bundleActiveResult->GetLong(LAST_TIME_CONTINUOUS_TASK_COLUMN_INDEX, relativeLastTimeFrontServiceUsed);
1034 usageStats->lastContiniousTaskUsed_ = relativeLastTimeFrontServiceUsed == -1 ? -1 :
1035 relativeLastTimeFrontServiceUsed + currentPackageTime;
1036 bundleActiveResult->GetLong(TOTAL_TIME_COLUMN_INDEX, usageStats->totalInFrontTime_);
1037 bundleActiveResult->GetLong(TOTAL_TIME_CONTINUOUS_TASK_COLUMN_INDEX, usageStats->totalContiniousTaskUsedTime_);
1038 bundleActiveResult->GetInt(PACKAGE_LOG_UID_COLUMN_INDEX, usageStats->uid_);
1039 string bundleStatsKey = usageStats->bundleName_ + std::to_string(usageStats->uid_);
1040 intervalStats->packageContainUid_[usageStats->bundleName_].insert(usageStats->uid_);
1041 bundleStats.insert(pair<string, shared_ptr<BundleActivePackageStats>>(bundleStatsKey, usageStats));
1042 }
1043 intervalStats->bundleStats_ = bundleStats;
1044 if (databaseType == DAILY_DATABASE_INDEX) {
1045 eventBeginTime_ = currentPackageTime;
1046 }
1047 int64_t systemTime = GetSystemTimeMs();
1048 intervalStats->lastTimeSaved_ = systemTime;
1049 return intervalStats;
1050 }
1051
FlushEventInfo(uint32_t databaseType, BundleActivePeriodStats &stats)1052 void BundleActiveUsageDatabase::FlushEventInfo(uint32_t databaseType, BundleActivePeriodStats &stats)
1053 {
1054 shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(databaseType);
1055 if (rdbStore == nullptr) {
1056 BUNDLE_ACTIVE_LOGE("flush event info fail, rdbStore is nullptr");
1057 return;
1058 }
1059 if (eventTableName_ == UNKNOWN_TABLE_NAME) {
1060 CreateEventLogTable(databaseType, stats.beginTime_);
1061 }
1062 int64_t eventTableTime = ParseStartTime(eventTableName_);
1063 int64_t outRowId = BUNDLE_ACTIVE_FAIL;
1064 NativeRdb::ValuesBucket valuesBucket;
1065 for (int32_t i = 0; i < stats.events_.Size(); i++) {
1066 valuesBucket.PutInt(BUNDLE_ACTIVE_DB_USER_ID, stats.userId_);
1067 valuesBucket.PutString(BUNDLE_ACTIVE_DB_BUNDLE_NAME, stats.events_.events_.at(i).bundleName_);
1068 valuesBucket.PutInt(BUNDLE_ACTIVE_DB_EVENT_ID, stats.events_.events_.at(i).eventId_);
1069 valuesBucket.PutLong(BUNDLE_ACTIVE_DB_TIME_STAMP, stats.events_.events_.at(i).timeStamp_ - eventTableTime);
1070 valuesBucket.PutString(BUNDLE_ACTIVE_DB_ABILITY_ID, stats.events_.events_.at(i).abilityId_);
1071 valuesBucket.PutInt(BUNDLE_ACTIVE_DB_UID, stats.events_.events_.at(i).uid_);
1072 rdbStore->Insert(outRowId, eventTableName_, valuesBucket);
1073 valuesBucket.Clear();
1074 }
1075 }
1076
GetTableIndexSql(uint32_t databaseType, int64_t tableTime, bool createFlag, int32_t indexFlag)1077 string BundleActiveUsageDatabase::GetTableIndexSql(uint32_t databaseType, int64_t tableTime, bool createFlag,
1078 int32_t indexFlag)
1079 {
1080 string tableIndexSql;
1081 if (databaseType >= 0 && databaseType < sortedTableArray_.size()) {
1082 string packageTableIndex = PACKAGE_LOG_TABLE_INDEX_PREFIX + to_string(tableTime);
1083 string PackageTableName = PACKAGE_LOG_TABLE + to_string(tableTime);
1084 if (createFlag) {
1085 tableIndexSql = "CREATE INDEX " + packageTableIndex + " ON "
1086 + PackageTableName + " (userId, lastTime, bundleName);";
1087 } else {
1088 tableIndexSql = "DROP INDEX " + packageTableIndex;
1089 }
1090 } else if (databaseType == EVENT_DATABASE_INDEX) {
1091 string eventTableIndex = EVENT_LOG_TABLE_INDEX_PREFIX + to_string(tableTime);
1092 string eventTableName = EVENT_LOG_TABLE + to_string(tableTime);
1093 if (createFlag) {
1094 tableIndexSql = "CREATE INDEX " + eventTableIndex + " ON " + eventTableName +
1095 " (timeStamp, userId, bundleName);";
1096 } else {
1097 tableIndexSql = "DROP INDEX " + eventTableIndex;
1098 }
1099 } else if (databaseType == APP_GROUP_DATABASE_INDEX) {
1100 if (createFlag) {
1101 if (indexFlag == BUNDLE_ACTIVE_DB_INDEX_NORMAL) {
1102 tableIndexSql = "CREATE INDEX " + BUNDLE_HISTORY_LOG_TABLE_INDEX_PREFIX
1103 + " ON " + BUNDLE_HISTORY_LOG_TABLE + " (userId, bundleName);";
1104 } else if (indexFlag == BUNDLE_ACTIVE_DB_INDEX_MODULE) {
1105 tableIndexSql = "CREATE INDEX " + MODULE_RECORD_LOG_TABLE_INDEX_PREFIX
1106 + " ON " + MODULE_RECORD_LOG_TABLE + to_string(tableTime) + " (userId, bundleName, moduleName);";
1107 } else if (indexFlag == BUNDLE_ACTIVE_DB_INDEX_FORM) {
1108 tableIndexSql = "CREATE INDEX " + FORM_RECORD_LOG_TABLE_INDEX_PREFIX
1109 + " ON " + FORM_RECORD_LOG_TABLE + to_string(tableTime) +
1110 " (userId, moduleName, formName, formDimension, formId);";
1111 }
1112 } else {
1113 if (indexFlag == BUNDLE_ACTIVE_DB_INDEX_NORMAL) {
1114 tableIndexSql = "DROP INDEX " + BUNDLE_HISTORY_LOG_TABLE_INDEX_PREFIX;
1115 } else if (indexFlag == BUNDLE_ACTIVE_DB_INDEX_MODULE) {
1116 tableIndexSql = "DROP INDEX " + MODULE_RECORD_LOG_TABLE_INDEX_PREFIX;
1117 } else if (indexFlag == BUNDLE_ACTIVE_DB_INDEX_FORM) {
1118 tableIndexSql = "DROP INDEX " + FORM_RECORD_LOG_TABLE_INDEX_PREFIX;
1119 }
1120 }
1121 } else {
1122 BUNDLE_ACTIVE_LOGE("databaseType is invalid, databaseType = %{public}d", databaseType);
1123 }
1124 return tableIndexSql;
1125 }
1126
SetNewIndexWhenTimeChanged(uint32_t databaseType, int64_t tableOldTime, int64_t tableNewTime, std::shared_ptr<NativeRdb::RdbStore> rdbStore)1127 int32_t BundleActiveUsageDatabase::SetNewIndexWhenTimeChanged(uint32_t databaseType, int64_t tableOldTime,
1128 int64_t tableNewTime, std::shared_ptr<NativeRdb::RdbStore> rdbStore)
1129 {
1130 if (rdbStore == nullptr) {
1131 return BUNDLE_ACTIVE_FAIL;
1132 }
1133 if (databaseType == APP_GROUP_DATABASE_INDEX) {
1134 string oldModuleTableIndex = GetTableIndexSql(databaseType, tableOldTime, false,
1135 BUNDLE_ACTIVE_DB_INDEX_MODULE);
1136 int32_t deleteResult = rdbStore->ExecuteSql(oldModuleTableIndex);
1137 if (deleteResult != NativeRdb::E_OK) {
1138 return BUNDLE_ACTIVE_FAIL;
1139 }
1140 string newModuleTableIndex = GetTableIndexSql(databaseType, tableNewTime, true,
1141 BUNDLE_ACTIVE_DB_INDEX_MODULE);
1142 int32_t createResult = rdbStore->ExecuteSql(newModuleTableIndex);
1143 if (createResult != NativeRdb::E_OK) {
1144 return BUNDLE_ACTIVE_FAIL;
1145 }
1146 string oldFormTableIndex = GetTableIndexSql(databaseType, tableOldTime, false,
1147 BUNDLE_ACTIVE_DB_INDEX_FORM);
1148 deleteResult = rdbStore->ExecuteSql(oldFormTableIndex);
1149 if (deleteResult != NativeRdb::E_OK) {
1150 return BUNDLE_ACTIVE_FAIL;
1151 }
1152 string newFormTableIndex = GetTableIndexSql(databaseType, tableNewTime, true,
1153 BUNDLE_ACTIVE_DB_INDEX_FORM);
1154 createResult = rdbStore->ExecuteSql(newFormTableIndex);
1155 if (createResult != NativeRdb::E_OK) {
1156 return BUNDLE_ACTIVE_FAIL;
1157 }
1158 } else {
1159 string oldTableIndex = GetTableIndexSql(databaseType, tableOldTime, false);
1160 int32_t deleteResult = rdbStore->ExecuteSql(oldTableIndex);
1161 if (deleteResult != NativeRdb::E_OK) {
1162 return BUNDLE_ACTIVE_FAIL;
1163 }
1164 string newTableIndex = GetTableIndexSql(databaseType, tableNewTime, true);
1165 int32_t createResult = rdbStore->ExecuteSql(newTableIndex);
1166 if (createResult != NativeRdb::E_OK) {
1167 return BUNDLE_ACTIVE_FAIL;
1168 }
1169 }
1170 return BUNDLE_ACTIVE_SUCCESS;
1171 }
1172
RenameTableName(uint32_t databaseType, int64_t tableOldTime, int64_t tableNewTime)1173 int32_t BundleActiveUsageDatabase::RenameTableName(uint32_t databaseType, int64_t tableOldTime,
1174 int64_t tableNewTime)
1175 {
1176 shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(databaseType);
1177 if (rdbStore == nullptr) {
1178 return BUNDLE_ACTIVE_FAIL;
1179 }
1180 if (databaseType >= 0 && databaseType < sortedTableArray_.size()) {
1181 if (ExecuteRenameTableName(PACKAGE_LOG_TABLE, tableOldTime, tableNewTime, rdbStore) != ERR_OK) {
1182 return BUNDLE_ACTIVE_FAIL;
1183 }
1184 } else if (databaseType == EVENT_DATABASE_INDEX) {
1185 if (ExecuteRenameTableName(EVENT_LOG_TABLE, tableOldTime, tableNewTime, rdbStore) != ERR_OK) {
1186 return BUNDLE_ACTIVE_FAIL;
1187 }
1188 } else if (databaseType == APP_GROUP_DATABASE_INDEX) {
1189 if (ExecuteRenameTableName(MODULE_RECORD_LOG_TABLE, tableOldTime, tableNewTime, rdbStore) != ERR_OK) {
1190 return BUNDLE_ACTIVE_FAIL;
1191 }
1192 if (ExecuteRenameTableName(FORM_RECORD_LOG_TABLE, tableOldTime, tableNewTime, rdbStore) != ERR_OK) {
1193 return BUNDLE_ACTIVE_FAIL;
1194 }
1195 }
1196 int32_t setResult = SetNewIndexWhenTimeChanged(databaseType, tableOldTime, tableNewTime, rdbStore);
1197 if (setResult != BUNDLE_ACTIVE_SUCCESS) {
1198 return BUNDLE_ACTIVE_FAIL;
1199 }
1200 return BUNDLE_ACTIVE_SUCCESS;
1201 }
1202
ExecuteRenameTableName(std::string tablePrefix, int64_t tableOldTime, int64_t tableNewTime, std::shared_ptr<NativeRdb::RdbStore> rdbStore)1203 int32_t BundleActiveUsageDatabase::ExecuteRenameTableName(std::string tablePrefix, int64_t tableOldTime,
1204 int64_t tableNewTime, std::shared_ptr<NativeRdb::RdbStore> rdbStore)
1205 {
1206 if (!rdbStore) {
1207 BUNDLE_ACTIVE_LOGE("execute rename table name fail, rdbstore is nullptr");
1208 return BUNDLE_ACTIVE_FAIL;
1209 }
1210 string oldTableName = tablePrefix + to_string(tableOldTime);
1211 string newTableName = tablePrefix + to_string(tableNewTime);
1212 string renameTableNameSql = "alter table " + oldTableName + " rename to " + newTableName;
1213 int32_t renameTableName = rdbStore->ExecuteSql(renameTableNameSql);
1214 if (renameTableName != NativeRdb::E_OK) {
1215 BUNDLE_ACTIVE_LOGE("Rename table failed");
1216 return BUNDLE_ACTIVE_FAIL;
1217 }
1218 return ERR_OK;
1219 }
1220
GetOptimalIntervalType(int64_t beginTime, int64_t endTime)1221 int32_t BundleActiveUsageDatabase::GetOptimalIntervalType(int64_t beginTime, int64_t endTime)
1222 {
1223 lock_guard<ffrt::mutex> lock(databaseMutex_);
1224 int32_t optimalIntervalType = -1;
1225 int64_t leastTimeDiff = numeric_limits<int64_t>::max();
1226 for (int32_t i = static_cast<int32_t>(sortedTableArray_.size() - 1); i >= 0; i--) {
1227 int32_t index = NearIndexOnOrBeforeCurrentTime(beginTime, sortedTableArray_.at(i));
1228 int32_t size = static_cast<int32_t>(sortedTableArray_.at(i).size());
1229 if (index >= 0 && index < size) {
1230 int64_t diff = abs(sortedTableArray_.at(i).at(index) - beginTime);
1231 if (diff < leastTimeDiff) {
1232 leastTimeDiff = diff;
1233 optimalIntervalType = i;
1234 }
1235 }
1236 }
1237 BUNDLE_ACTIVE_LOGI("optimalIntervalType is %{public}d", optimalIntervalType);
1238 return optimalIntervalType;
1239 }
1240
RemoveOldData(int64_t currentTime)1241 void BundleActiveUsageDatabase::RemoveOldData(int64_t currentTime)
1242 {
1243 lock_guard<ffrt::mutex> lock(databaseMutex_);
1244 calendar_->SetMilliseconds(currentTime);
1245 calendar_->IncreaseYears(-1 * MAX_FILES_EVERY_INTERVAL_TYPE[YEARLY_DATABASE_INDEX]);
1246 std::unique_ptr<std::vector<int64_t>> overdueYearsTableCreateTime = GetOverdueTableCreateTime(YEARLY_DATABASE_INDEX,
1247 calendar_->GetMilliseconds());
1248 if (overdueYearsTableCreateTime != nullptr) {
1249 for (uint32_t i = 0; i < overdueYearsTableCreateTime->size(); i++) {
1250 DeleteInvalidTable(YEARLY_DATABASE_INDEX, overdueYearsTableCreateTime->at(i));
1251 }
1252 }
1253 calendar_->SetMilliseconds(currentTime);
1254 calendar_->IncreaseMonths(-1 * MAX_FILES_EVERY_INTERVAL_TYPE[MONTHLY_DATABASE_INDEX]);
1255 std::unique_ptr<std::vector<int64_t>> overdueMonthsTableCreateTime
1256 = GetOverdueTableCreateTime(MONTHLY_DATABASE_INDEX, calendar_->GetMilliseconds());
1257 if (overdueMonthsTableCreateTime != nullptr) {
1258 for (uint32_t i = 0; i < overdueMonthsTableCreateTime->size(); i++) {
1259 DeleteInvalidTable(MONTHLY_DATABASE_INDEX, overdueMonthsTableCreateTime->at(i));
1260 }
1261 }
1262 calendar_->SetMilliseconds(currentTime);
1263 calendar_->IncreaseWeeks(-1 * MAX_FILES_EVERY_INTERVAL_TYPE[WEEKLY_DATABASE_INDEX]);
1264 std::unique_ptr<std::vector<int64_t>> overdueWeeksTableCreateTime = GetOverdueTableCreateTime(WEEKLY_DATABASE_INDEX,
1265 calendar_->GetMilliseconds());
1266 if (overdueWeeksTableCreateTime != nullptr) {
1267 for (uint32_t i = 0; i < overdueWeeksTableCreateTime->size(); i++) {
1268 DeleteInvalidTable(WEEKLY_DATABASE_INDEX, overdueWeeksTableCreateTime->at(i));
1269 }
1270 }
1271 calendar_->SetMilliseconds(currentTime);
1272 calendar_->IncreaseDays(-1 * MAX_FILES_EVERY_INTERVAL_TYPE[DAILY_DATABASE_INDEX]);
1273 std::unique_ptr<std::vector<int64_t>> overdueDaysTableCreateTime = GetOverdueTableCreateTime(DAILY_DATABASE_INDEX,
1274 calendar_->GetMilliseconds());
1275 if (overdueDaysTableCreateTime != nullptr) {
1276 for (uint32_t i = 0; i < overdueDaysTableCreateTime->size(); i++) {
1277 DeleteInvalidTable(DAILY_DATABASE_INDEX, overdueDaysTableCreateTime->at(i));
1278 }
1279 }
1280 for (uint32_t i = 0; i < sortedTableArray_.size(); i++) {
1281 HandleTableInfo(i);
1282 DeleteExcessiveTableData(i);
1283 }
1284 }
1285
RenewTableTime(int64_t timeDiffMillis)1286 void BundleActiveUsageDatabase::RenewTableTime(int64_t timeDiffMillis)
1287 {
1288 lock_guard<ffrt::mutex> lock(databaseMutex_);
1289 for (uint32_t i = 0; i < sortedTableArray_.size(); i++) {
1290 if (sortedTableArray_.at(i).empty()) {
1291 continue;
1292 }
1293 vector<int64_t> tableArray = sortedTableArray_.at(i);
1294 for (uint32_t j = 0; j < tableArray.size(); j++) {
1295 int64_t newTime = tableArray.at(j) + timeDiffMillis;
1296 BUNDLE_ACTIVE_LOGI("new table time is %{public}lld", (long long)newTime);
1297 if (newTime < 0) {
1298 DeleteInvalidTable(i, tableArray.at(j));
1299 } else {
1300 RenameTableName(i, tableArray.at(j), newTime);
1301 }
1302 }
1303 sortedTableArray_.at(i).clear();
1304 HandleTableInfo(i);
1305 DeleteExcessiveTableData(i);
1306 }
1307 if (eventTableName_ != UNKNOWN_TABLE_NAME) {
1308 int64_t oldTime = ParseStartTime(eventTableName_);
1309 int64_t newTime = oldTime + timeDiffMillis;
1310 if (newTime < 0) {
1311 int32_t deletedResult = DeleteInvalidTable(EVENT_DATABASE_INDEX, oldTime);
1312 if (deletedResult == BUNDLE_ACTIVE_SUCCESS) {
1313 eventTableName_ = UNKNOWN_TABLE_NAME;
1314 }
1315 } else {
1316 int32_t renamedResult = RenameTableName(EVENT_DATABASE_INDEX, oldTime, newTime);
1317 if (renamedResult == BUNDLE_ACTIVE_SUCCESS) {
1318 eventTableName_ = EVENT_LOG_TABLE + to_string(newTime);
1319 }
1320 }
1321 }
1322 if (formRecordsTableName_ != UNKNOWN_TABLE_NAME && moduleRecordsTableName_ != UNKNOWN_TABLE_NAME) {
1323 int64_t oldTime = ParseStartTime(moduleRecordsTableName_);
1324 int64_t newTime = oldTime + timeDiffMillis;
1325 int32_t renamedResult = RenameTableName(APP_GROUP_DATABASE_INDEX, oldTime, newTime);
1326 if (renamedResult == BUNDLE_ACTIVE_SUCCESS) {
1327 moduleRecordsTableName_ = MODULE_RECORD_LOG_TABLE + to_string(newTime);
1328 formRecordsTableName_ = FORM_RECORD_LOG_TABLE + to_string(newTime);
1329 }
1330 }
1331 }
1332
UpdateEventData(int32_t databaseType, BundleActivePeriodStats &stats)1333 void BundleActiveUsageDatabase::UpdateEventData(int32_t databaseType, BundleActivePeriodStats &stats)
1334 {
1335 lock_guard<ffrt::mutex> lock(databaseMutex_);
1336 CheckDatabaseFile(databaseType);
1337 if (databaseType != DAILY_DATABASE_INDEX) {
1338 return;
1339 }
1340 if (stats.events_.Size() != 0) {
1341 CheckDatabaseFile(EVENT_DATABASE_INDEX);
1342 FlushEventInfo(EVENT_DATABASE_INDEX, stats);
1343 }
1344 }
1345
UpdateBundleUsageData(int32_t databaseType, BundleActivePeriodStats &stats)1346 void BundleActiveUsageDatabase::UpdateBundleUsageData(int32_t databaseType, BundleActivePeriodStats &stats)
1347 {
1348 lock_guard<ffrt::mutex> lock(databaseMutex_);
1349 if (databaseType < 0 || databaseType >= EVENT_DATABASE_INDEX) {
1350 BUNDLE_ACTIVE_LOGE("databaseType is invalid : %{public}d", databaseType);
1351 return;
1352 }
1353 CheckDatabaseFile(databaseType);
1354 int32_t packageTableIndex = BundleActiveBinarySearch::GetInstance()->BinarySearch(
1355 sortedTableArray_.at(databaseType), stats.beginTime_);
1356 if (packageTableIndex < 0) {
1357 CreatePackageLogTable(databaseType, stats.beginTime_);
1358 if (databaseType == DAILY_DATABASE_INDEX) {
1359 eventBeginTime_ = stats.beginTime_;
1360 DeleteExcessiveTableData(EVENT_DATABASE_INDEX);
1361 }
1362 sortedTableArray_.at(databaseType).push_back(stats.beginTime_);
1363 sort(sortedTableArray_.at(databaseType).begin(), sortedTableArray_.at(databaseType).end());
1364 DeleteExcessiveTableData(databaseType);
1365 }
1366 FlushPackageInfo(databaseType, stats);
1367 int64_t systemTime = GetSystemTimeMs();
1368 stats.lastTimeSaved_ = systemTime;
1369 }
1370
GetDbIndex(const int64_t beginTime, const int64_t endTime, const int32_t databaseType, int32_t &startIndex, int32_t &endIndex)1371 bool BundleActiveUsageDatabase::GetDbIndex(const int64_t beginTime, const int64_t endTime,
1372 const int32_t databaseType, int32_t &startIndex, int32_t &endIndex)
1373 {
1374 if (databaseType < 0 || databaseType >= static_cast<int32_t>(sortedTableArray_.size())) {
1375 BUNDLE_ACTIVE_LOGE("databaseType is invalid, databaseType = %{public}d", databaseType);
1376 return false;
1377 }
1378 if (endTime <= beginTime) {
1379 BUNDLE_ACTIVE_LOGE("endTime(%{public}lld) <= beginTime(%{public}lld)",
1380 (long long)endTime, (long long)beginTime);
1381 return false;
1382 }
1383 startIndex = NearIndexOnOrBeforeCurrentTime(beginTime, sortedTableArray_.at(databaseType));
1384 if (startIndex < 0) {
1385 startIndex = 0;
1386 }
1387 endIndex = NearIndexOnOrBeforeCurrentTime(endTime, sortedTableArray_.at(databaseType));
1388 if (endIndex < 0) {
1389 return false;
1390 }
1391 if (sortedTableArray_.at(databaseType).at(endIndex) == endTime) {
1392 endIndex--;
1393 if (endIndex < 0) {
1394 return false;
1395 }
1396 }
1397 return true;
1398 }
1399
GetQuerySqlCommand(const int64_t beginTime, const int64_t endTime, const int32_t databaseType, const int32_t index, const int32_t startIndex, const int32_t endIndex, const int32_t userId, std::vector<std::string> &queryCondition, std::string &queryPackageSql)1400 void BundleActiveUsageDatabase::GetQuerySqlCommand(const int64_t beginTime,
1401 const int64_t endTime, const int32_t databaseType,
1402 const int32_t index, const int32_t startIndex, const int32_t endIndex, const int32_t userId,
1403 std::vector<std::string> &queryCondition, std::string &queryPackageSql)
1404 {
1405 string packageTableName;
1406 int64_t packageTableTime = sortedTableArray_.at(databaseType).at(index);
1407 packageTableName = PACKAGE_LOG_TABLE + to_string(packageTableTime);
1408 queryCondition.push_back(to_string(userId));
1409 if (startIndex == endIndex) {
1410 int64_t diff = beginTime - packageTableTime;
1411 if (diff >= 0) {
1412 queryCondition.push_back(to_string(diff));
1413 } else {
1414 queryCondition.push_back(to_string(LAST_TIME_IN_MILLIS_MIN));
1415 }
1416 queryCondition.push_back(to_string(endTime - packageTableTime));
1417 queryPackageSql = "select * from " + packageTableName +
1418 " where userId = ? and lastTime >= ? and lastTime <= ?";
1419 } else {
1420 if (index == startIndex) {
1421 int64_t diff = beginTime - packageTableTime;
1422 if (diff >= 0) {
1423 queryCondition.push_back(to_string(diff));
1424 } else {
1425 queryCondition.push_back(to_string(LAST_TIME_IN_MILLIS_MIN));
1426 }
1427 queryPackageSql = "select * from " + packageTableName + " where userId = ? and lastTime >= ?";
1428 } else if (index == endIndex) {
1429 queryCondition.push_back(to_string(endTime - packageTableTime));
1430 queryPackageSql = "select * from " + packageTableName + " where userId = ? and lastTime <= ?";
1431 } else {
1432 queryPackageSql = "select * from " + packageTableName + " where userId = ?";
1433 }
1434 }
1435 }
1436
QueryDatabaseUsageStats(int32_t databaseType, int64_t beginTime, int64_t endTime, int32_t userId)1437 vector<BundleActivePackageStats> BundleActiveUsageDatabase::QueryDatabaseUsageStats(int32_t databaseType,
1438 int64_t beginTime, int64_t endTime, int32_t userId)
1439 {
1440 lock_guard<ffrt::mutex> lock(databaseMutex_);
1441 vector<BundleActivePackageStats> databaseUsageStats;
1442 int32_t startIndex = 0;
1443 int32_t endIndex = 0;
1444 if (!GetDbIndex(beginTime, endTime, databaseType, startIndex, endIndex)) {
1445 return databaseUsageStats;
1446 }
1447 for (int32_t i = startIndex; i <= endIndex; i++) {
1448 string queryPackageSql;
1449 vector<string> queryCondition;
1450 GetQuerySqlCommand(beginTime, endTime, databaseType, i, startIndex,
1451 endIndex, userId, queryCondition, queryPackageSql);
1452 auto bundleActiveResult = QueryStatsInfoByStep(databaseType, queryPackageSql,
1453 queryCondition);
1454 if (bundleActiveResult == nullptr) {
1455 return databaseUsageStats;
1456 }
1457 int32_t tableRowNumber;
1458 bundleActiveResult->GetRowCount(tableRowNumber);
1459 BundleActivePackageStats usageStats;
1460 int64_t relativeLastTimeUsed;
1461 int64_t relativeLastTimeFrontServiceUsed;
1462 int64_t packageTableTime = sortedTableArray_.at(databaseType).at(i);
1463 for (int32_t j = 0; j < tableRowNumber; j++) {
1464 bundleActiveResult->GoToRow(j);
1465 bundleActiveResult->GetString(BUNDLE_NAME_COLUMN_INDEX, usageStats.bundleName_);
1466 bundleActiveResult->GetInt(BUNDLE_STARTED_COUNT_COLUMN_INDEX, usageStats.startCount_);
1467 bundleActiveResult->GetLong(LAST_TIME_COLUMN_INDEX, usageStats.lastTimeUsed_);
1468 bundleActiveResult->GetLong(LAST_TIME_COLUMN_INDEX, relativeLastTimeUsed);
1469 usageStats.lastTimeUsed_ = relativeLastTimeUsed == -1 ? -1 :
1470 relativeLastTimeUsed + packageTableTime;
1471 bundleActiveResult->GetLong(LAST_TIME_CONTINUOUS_TASK_COLUMN_INDEX, relativeLastTimeFrontServiceUsed);
1472 usageStats.lastContiniousTaskUsed_ = relativeLastTimeFrontServiceUsed == -1 ? -1 :
1473 relativeLastTimeFrontServiceUsed + packageTableTime;
1474 bundleActiveResult->GetLong(TOTAL_TIME_COLUMN_INDEX, usageStats.totalInFrontTime_);
1475 bundleActiveResult->GetLong(TOTAL_TIME_CONTINUOUS_TASK_COLUMN_INDEX,
1476 usageStats.totalContiniousTaskUsedTime_);
1477 bundleActiveResult->GetInt(PACKAGE_LOG_UID_COLUMN_INDEX, usageStats.uid_);
1478 usageStats.userId_ = userId;
1479 databaseUsageStats.push_back(usageStats);
1480 }
1481 queryCondition.clear();
1482 }
1483 return databaseUsageStats;
1484 }
1485
QueryDatabaseEvents(int64_t beginTime, int64_t endTime, int32_t userId, string bundleName)1486 vector<BundleActiveEvent> BundleActiveUsageDatabase::QueryDatabaseEvents(int64_t beginTime, int64_t endTime,
1487 int32_t userId, string bundleName)
1488 {
1489 lock_guard<ffrt::mutex> lock(databaseMutex_);
1490 vector<BundleActiveEvent> databaseEvents;
1491 int64_t eventTableTime = ParseStartTime(eventTableName_);
1492 if (JudgeQueryCondition(beginTime, endTime, eventTableTime) == QUERY_CONDITION_INVALID) {
1493 return databaseEvents;
1494 }
1495 vector<string> queryCondition;
1496 int64_t diff = beginTime - eventTableTime;
1497 if (diff >= 0) {
1498 queryCondition.push_back(to_string(diff));
1499 } else {
1500 queryCondition.push_back(to_string(EVENT_TIME_IN_MILLIS_MIN));
1501 }
1502 queryCondition.push_back(to_string(endTime - eventTableTime));
1503 queryCondition.push_back(to_string(userId));
1504 string queryEventSql;
1505 if (bundleName.empty()) {
1506 queryEventSql = "select * from " + eventTableName_ + " where timeStamp >= ? and timeStamp <= ? and userId = ?";
1507 } else {
1508 queryCondition.push_back(bundleName);
1509 queryEventSql = "select * from " + eventTableName_ +
1510 " where timeStamp >= ? and timeStamp <= ? and userId = ? and bundleName = ?";
1511 }
1512 auto bundleActiveResult = QueryStatsInfoByStep(EVENT_DATABASE_INDEX,
1513 queryEventSql, queryCondition);
1514 if (bundleActiveResult == nullptr) {
1515 return databaseEvents;
1516 }
1517 int32_t tableRowNumber;
1518 bundleActiveResult->GetRowCount(tableRowNumber);
1519 BundleActiveEvent event;
1520 string relativeTimeStamp;
1521 for (int32_t i = 0; i < tableRowNumber; i++) {
1522 bundleActiveResult->GoToRow(i);
1523 bundleActiveResult->GetString(BUNDLE_NAME_COLUMN_INDEX, event.bundleName_);
1524 bundleActiveResult->GetInt(EVENT_ID_COLUMN_INDEX, event.eventId_);
1525 bundleActiveResult->GetString(TIME_STAMP_COLUMN_INDEX, relativeTimeStamp);
1526 event.timeStamp_ = atoll(relativeTimeStamp.c_str()) + eventTableTime;
1527 bundleActiveResult->GetString(ABILITY_ID_COLUMN_INDEX, event.abilityId_);
1528 bundleActiveResult->GetInt(EVENT_UID_COLUMN_INDEX, event.uid_);
1529 databaseEvents.push_back(event);
1530 }
1531 return databaseEvents;
1532 }
1533
OnPackageUninstalled(const int32_t userId, const string& bundleName, const int32_t uid, const int32_t appIndex)1534 void BundleActiveUsageDatabase::OnPackageUninstalled(const int32_t userId, const string& bundleName,
1535 const int32_t uid, const int32_t appIndex)
1536 {
1537 lock_guard<ffrt::mutex> lock(databaseMutex_);
1538 for (uint32_t i = 0; i < sortedTableArray_.size(); i++) {
1539 if (sortedTableArray_.at(i).empty()) {
1540 continue;
1541 }
1542 for (uint32_t j = 0; j < sortedTableArray_.at(i).size(); j++) {
1543 string packageTableName = PACKAGE_LOG_TABLE + to_string(sortedTableArray_.at(i).at(j));
1544 DeleteUninstalledInfo(userId, bundleName, uid, packageTableName, i, appIndex);
1545 }
1546 }
1547 if (eventTableName_ != UNKNOWN_TABLE_NAME) {
1548 DeleteUninstalledInfo(userId, bundleName, uid, eventTableName_, EVENT_DATABASE_INDEX, appIndex);
1549 }
1550 if (bundleHistoryTableName_ != UNKNOWN_TABLE_NAME) {
1551 DeleteUninstalledInfo(userId, bundleName, uid, bundleHistoryTableName_, APP_GROUP_DATABASE_INDEX, appIndex);
1552 }
1553 if (moduleRecordsTableName_ != UNKNOWN_TABLE_NAME) {
1554 DeleteUninstalledInfo(userId, bundleName, uid, moduleRecordsTableName_, APP_GROUP_DATABASE_INDEX, appIndex);
1555 }
1556 if (formRecordsTableName_ != UNKNOWN_TABLE_NAME) {
1557 DeleteUninstalledInfo(userId, bundleName, uid, formRecordsTableName_, APP_GROUP_DATABASE_INDEX, appIndex);
1558 }
1559 }
1560
DeleteUninstalledInfo(const int32_t userId, const string& bundleName, const int32_t uid, const string& tableName, uint32_t databaseType, const int32_t appIndex)1561 void BundleActiveUsageDatabase::DeleteUninstalledInfo(const int32_t userId, const string& bundleName,
1562 const int32_t uid, const string& tableName, uint32_t databaseType, const int32_t appIndex)
1563 {
1564 shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(databaseType);
1565 if (rdbStore == nullptr) {
1566 BUNDLE_ACTIVE_LOGE("delete uninstalled info fail, rdbStore is nullptr");
1567 return;
1568 }
1569 int32_t deletedRows = BUNDLE_ACTIVE_FAIL;
1570 vector<string> queryCondition;
1571 queryCondition.push_back(to_string(userId));
1572 if (bundleName.empty()) {
1573 rdbStore->Delete(deletedRows, tableName, "userId = ?", queryCondition);
1574 return;
1575 }
1576 if (appIndex == MAIN_APP_INDEX) {
1577 queryCondition.push_back(bundleName);
1578 rdbStore->Delete(deletedRows, tableName, "userId = ? and bundleName = ?", queryCondition);
1579 return;
1580 }
1581 queryCondition.push_back(bundleName);
1582 queryCondition.push_back(to_string(uid));
1583 rdbStore->Delete(deletedRows, tableName, "userId = ? and bundleName = ? and uid = ?", queryCondition);
1584 }
1585
GetSystemTimeMs()1586 int64_t BundleActiveUsageDatabase::GetSystemTimeMs()
1587 {
1588 time_t now;
1589 (void)time(&now); // unit is seconds.
1590 if (static_cast<int64_t>(now) < 0) {
1591 BUNDLE_ACTIVE_LOGE("Get now time error");
1592 return 0;
1593 }
1594 auto tarEndTimePoint = std::chrono::system_clock::from_time_t(now);
1595 auto tarDuration = std::chrono::duration_cast<std::chrono::milliseconds>(tarEndTimePoint.time_since_epoch());
1596 int64_t tarDate = tarDuration.count();
1597 if (tarDate < 0) {
1598 BUNDLE_ACTIVE_LOGE("tarDuration is less than 0.");
1599 return -1;
1600 }
1601 return static_cast<int64_t>(tarDate);
1602 }
1603
UpdateModuleData(const int32_t userId, std::map<std::string, std::shared_ptr<BundleActiveModuleRecord>>& moduleRecords, const int64_t timeStamp)1604 void BundleActiveUsageDatabase::UpdateModuleData(const int32_t userId,
1605 std::map<std::string, std::shared_ptr<BundleActiveModuleRecord>>& moduleRecords, const int64_t timeStamp)
1606 {
1607 lock_guard<ffrt::mutex> lock(databaseMutex_);
1608 CheckDatabaseFile(APP_GROUP_DATABASE_INDEX);
1609 shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(APP_GROUP_DATABASE_INDEX);
1610 if (rdbStore == nullptr) {
1611 BUNDLE_ACTIVE_LOGE("update module data fail, rdbStore is nullptr");
1612 return;
1613 }
1614 CreateRecordTable(timeStamp);
1615 int64_t moduleTableTime = ParseStartTime(moduleRecordsTableName_);
1616 int32_t changeRow = BUNDLE_ACTIVE_FAIL;
1617 int64_t outRowId = BUNDLE_ACTIVE_FAIL;
1618 NativeRdb::ValuesBucket moduleValuesBucket;
1619 vector<string> queryCondition;
1620 for (const auto& oneModuleRecord : moduleRecords) {
1621 if (oneModuleRecord.second) {
1622 queryCondition.emplace_back(to_string(oneModuleRecord.second->userId_));
1623 queryCondition.emplace_back(oneModuleRecord.second->bundleName_);
1624 queryCondition.emplace_back(oneModuleRecord.second->moduleName_);
1625 queryCondition.emplace_back(to_string(oneModuleRecord.second->uid_));
1626 moduleValuesBucket.PutInt(BUNDLE_ACTIVE_DB_MODULE_LAUNCHED_COUNT, oneModuleRecord.second->launchedCount_);
1627 int64_t adjustLastTime = oneModuleRecord.second->lastModuleUsedTime_ != -1 ?
1628 oneModuleRecord.second->lastModuleUsedTime_ - moduleTableTime : -1;
1629 moduleValuesBucket.PutLong(BUNDLE_ACTIVE_DB_LAST_TIME, adjustLastTime);
1630 rdbStore->Update(changeRow, moduleRecordsTableName_, moduleValuesBucket,
1631 "userId = ? and bundleName = ? and moduleName = ? and uid = ?", queryCondition);
1632 if (changeRow == NO_UPDATE_ROW) {
1633 moduleValuesBucket.PutInt(BUNDLE_ACTIVE_DB_USER_ID, oneModuleRecord.second->userId_);
1634 moduleValuesBucket.PutString(BUNDLE_ACTIVE_DB_BUNDLE_NAME, oneModuleRecord.second->bundleName_);
1635 moduleValuesBucket.PutString(BUNDLE_ACTIVE_DB_MODULE_NAME, oneModuleRecord.second->moduleName_);
1636 moduleValuesBucket.PutInt(BUNDLE_ACTIVE_DB_UID, oneModuleRecord.second->uid_);
1637 rdbStore->Insert(outRowId, moduleRecordsTableName_, moduleValuesBucket);
1638 outRowId = BUNDLE_ACTIVE_FAIL;
1639 changeRow = BUNDLE_ACTIVE_FAIL;
1640 } else {
1641 changeRow = BUNDLE_ACTIVE_FAIL;
1642 }
1643 moduleValuesBucket.Clear();
1644 queryCondition.clear();
1645 for (const auto& oneFormRecord : oneModuleRecord.second->formRecords_) {
1646 UpdateFormData(oneModuleRecord.second->userId_, oneModuleRecord.second->bundleName_,
1647 oneModuleRecord.second->moduleName_, oneFormRecord, rdbStore);
1648 }
1649 }
1650 }
1651 }
1652
CreateRecordTable(const int64_t timeStamp)1653 void BundleActiveUsageDatabase::CreateRecordTable(const int64_t timeStamp)
1654 {
1655 if (moduleRecordsTableName_ == UNKNOWN_TABLE_NAME) {
1656 CreateModuleRecordTable(APP_GROUP_DATABASE_INDEX, timeStamp);
1657 }
1658 if (formRecordsTableName_ == UNKNOWN_TABLE_NAME) {
1659 CreateFormRecordTable(APP_GROUP_DATABASE_INDEX, timeStamp);
1660 }
1661 }
1662
UpdateFormData(const int32_t userId, const std::string bundleName, const string moduleName, const BundleActiveFormRecord& formRecord, std::shared_ptr<NativeRdb::RdbStore> rdbStore)1663 void BundleActiveUsageDatabase::UpdateFormData(const int32_t userId, const std::string bundleName,
1664 const string moduleName, const BundleActiveFormRecord& formRecord,
1665 std::shared_ptr<NativeRdb::RdbStore> rdbStore)
1666 {
1667 if (rdbStore == nullptr) {
1668 return;
1669 }
1670 int64_t formRecordsTableTime = ParseStartTime(formRecordsTableName_);
1671 NativeRdb::ValuesBucket formValueBucket;
1672 vector<string> queryCondition;
1673 int32_t changeRow = BUNDLE_ACTIVE_FAIL;
1674 int64_t outRowId = BUNDLE_ACTIVE_FAIL;
1675 queryCondition.emplace_back(to_string(userId));
1676 queryCondition.emplace_back(bundleName);
1677 queryCondition.emplace_back(moduleName);
1678 queryCondition.emplace_back(formRecord.formName_);
1679 queryCondition.emplace_back(to_string(formRecord.formDimension_));
1680 queryCondition.emplace_back(to_string(formRecord.formId_));
1681 queryCondition.emplace_back(to_string(formRecord.uid_));
1682 formValueBucket.PutInt(BUNDLE_ACTIVE_DB_FORM_TOUCH_COUNT, formRecord.count_);
1683 int64_t adjustLastTime = formRecord.formLastUsedTime_ != -1 ? formRecord.formLastUsedTime_ -
1684 formRecordsTableTime : -1;
1685 formValueBucket.PutLong(BUNDLE_ACTIVE_DB_LAST_TIME, adjustLastTime);
1686 rdbStore->Update(changeRow, formRecordsTableName_, formValueBucket,
1687 "userId = ? and bundleName = ? and moduleName = ? and formName = ? and formDimension = ? "
1688 "and formId = ?",
1689 queryCondition);
1690 if (changeRow == NO_UPDATE_ROW) {
1691 formValueBucket.PutInt(BUNDLE_ACTIVE_DB_USER_ID, userId);
1692 formValueBucket.PutString(BUNDLE_ACTIVE_DB_BUNDLE_NAME, bundleName);
1693 formValueBucket.PutString(BUNDLE_ACTIVE_DB_MODULE_NAME, moduleName);
1694 formValueBucket.PutString(BUNDLE_ACTIVE_DB_FORM_NAME, formRecord.formName_);
1695 formValueBucket.PutInt(BUNDLE_ACTIVE_DB_FORM_DIMENSION, formRecord.formDimension_);
1696 formValueBucket.PutInt(BUNDLE_ACTIVE_DB_FORM_ID, formRecord.formId_);
1697 formValueBucket.PutInt(BUNDLE_ACTIVE_DB_FORM_ID, formRecord.uid_);
1698 rdbStore->Insert(outRowId, formRecordsTableName_, formValueBucket);
1699 }
1700 }
1701
RemoveFormData(const int32_t userId, const std::string bundleName, const std::string moduleName, const std::string formName, const int32_t formDimension, const int64_t formId, const int32_t uid)1702 void BundleActiveUsageDatabase::RemoveFormData(const int32_t userId, const std::string bundleName,
1703 const std::string moduleName, const std::string formName, const int32_t formDimension,
1704 const int64_t formId, const int32_t uid)
1705 {
1706 lock_guard<ffrt::mutex> lock(databaseMutex_);
1707 shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(APP_GROUP_DATABASE_INDEX);
1708 if (rdbStore == nullptr) {
1709 BUNDLE_ACTIVE_LOGE("remove for data fail, rdbStore is nullptr");
1710 return;
1711 }
1712 int32_t deletedRows = BUNDLE_ACTIVE_FAIL;
1713 if (formRecordsTableName_ != UNKNOWN_TABLE_NAME) {
1714 vector<string> queryCondition;
1715 queryCondition.emplace_back(to_string(userId));
1716 queryCondition.emplace_back(bundleName);
1717 queryCondition.emplace_back(moduleName);
1718 queryCondition.emplace_back(formName);
1719 queryCondition.emplace_back(to_string(formDimension));
1720 queryCondition.emplace_back(to_string(formId));
1721 int32_t ret = rdbStore->Delete(deletedRows, formRecordsTableName_,
1722 "userId = ? and bundleName = ? and moduleName = ? and formName = ? and formDimension = ? "
1723 "and formId = ? and uid = ?",
1724 queryCondition);
1725 if (ret != NativeRdb::E_OK) {
1726 BUNDLE_ACTIVE_LOGE("delete event data failed, rdb error number: %{public}d", ret);
1727 }
1728 }
1729 }
1730
LoadModuleData(const int32_t userId, std::map<std::string, std::shared_ptr<BundleActiveModuleRecord>>& moduleRecords)1731 void BundleActiveUsageDatabase::LoadModuleData(const int32_t userId, std::map<std::string,
1732 std::shared_ptr<BundleActiveModuleRecord>>& moduleRecords)
1733 {
1734 lock_guard<ffrt::mutex> lock(databaseMutex_);
1735 string queryModuleSql = "select * from " + moduleRecordsTableName_ + " where userId = ?";
1736 vector<string> queryCondition;
1737 queryCondition.emplace_back(to_string(userId));
1738 auto moduleRecordResult = QueryStatsInfoByStep(APP_GROUP_DATABASE_INDEX, queryModuleSql,
1739 queryCondition);
1740 if (!moduleRecordResult) {
1741 return;
1742 }
1743 int64_t baseTime = ParseStartTime(moduleRecordsTableName_);
1744 int32_t numOfModuleRecord = 0;
1745 moduleRecordResult->GetRowCount(numOfModuleRecord);
1746 for (int32_t i = 0; i < numOfModuleRecord; i++) {
1747 shared_ptr<BundleActiveModuleRecord> oneModuleRecord = make_shared<BundleActiveModuleRecord>();
1748 moduleRecordResult->GoToRow(i);
1749 moduleRecordResult->GetInt(USER_ID_COLUMN_INDEX, oneModuleRecord->userId_);
1750 moduleRecordResult->GetString(BUNDLE_NAME_COLUMN_INDEX, oneModuleRecord->bundleName_);
1751 moduleRecordResult->GetString(MODULE_NAME_COLUMN_INDEX, oneModuleRecord->moduleName_);
1752 moduleRecordResult->GetInt(MODULE_USED_COUNT_COLUMN_INDEX, oneModuleRecord->launchedCount_);
1753 moduleRecordResult->GetInt(MODULE_UID_COLUMN_INDEX, oneModuleRecord->uid_);
1754 int64_t relativeLastTime = 0;
1755 moduleRecordResult->GetLong(MODULE_LAST_TIME_COLUMN_INDEX, relativeLastTime);
1756 oneModuleRecord->lastModuleUsedTime_ = relativeLastTime != -1 ? relativeLastTime + baseTime : -1;
1757 string combinedInfo = oneModuleRecord->bundleName_
1758 + " " + to_string(oneModuleRecord->uid_) + " " + oneModuleRecord->moduleName_;
1759 moduleRecords[combinedInfo] = oneModuleRecord;
1760 }
1761 }
1762
LoadFormData(const int32_t userId, std::map<std::string, std::shared_ptr<BundleActiveModuleRecord>>& moduleRecords)1763 void BundleActiveUsageDatabase::LoadFormData(const int32_t userId, std::map<std::string,
1764 std::shared_ptr<BundleActiveModuleRecord>>& moduleRecords)
1765 {
1766 lock_guard<ffrt::mutex> lock(databaseMutex_);
1767 string queryFormSql = "select * from " + formRecordsTableName_ + " where userId = ?";
1768 vector<string> queryCondition;
1769 queryCondition.emplace_back(to_string(userId));
1770 auto formRecordResult = QueryStatsInfoByStep(APP_GROUP_DATABASE_INDEX, queryFormSql,
1771 queryCondition);
1772 if (!formRecordResult) {
1773 return;
1774 }
1775 int32_t numOfFormRecord = 0;
1776 int64_t baseTime = ParseStartTime(formRecordsTableName_);
1777 formRecordResult->GetRowCount(numOfFormRecord);
1778 for (int32_t i = 0; i < numOfFormRecord; i++) {
1779 BundleActiveFormRecord oneFormRecord;
1780 string moduleName = "";
1781 string bundleName = "";
1782 formRecordResult->GoToRow(i);
1783 formRecordResult->GetInt(USER_ID_COLUMN_INDEX, oneFormRecord.userId_);
1784 formRecordResult->GetString(BUNDLE_NAME_COLUMN_INDEX, bundleName);
1785 formRecordResult->GetString(MODULE_NAME_COLUMN_INDEX, moduleName);
1786 formRecordResult->GetString(FORM_NAME_COLUMN_INDEX, oneFormRecord.formName_);
1787 formRecordResult->GetInt(FORM_DIMENSION_COLUMN_INDEX, oneFormRecord.formDimension_);
1788 formRecordResult->GetLong(FORM_ID_COLUMN_INDEX, oneFormRecord.formId_);
1789 formRecordResult->GetInt(FORM_COUNT_COLUMN_INDEX, oneFormRecord.count_);
1790 formRecordResult->GetInt(FORM_UID_COLUMN_INDEX, oneFormRecord.uid_);
1791 int64_t relativeLastTime = 0;
1792 formRecordResult->GetLong(FORM_LAST_TIME_COLUMN_INDEX, relativeLastTime);
1793 oneFormRecord.formLastUsedTime_ = relativeLastTime != -1 ? relativeLastTime + baseTime : -1;
1794 auto it = moduleRecords.find(bundleName + " " + to_string(oneFormRecord.uid_) + " " + moduleName);
1795 if (it != moduleRecords.end() && it->second) {
1796 it->second->formRecords_.emplace_back(oneFormRecord);
1797 }
1798 }
1799 }
1800
QueryDeviceEventStats(int32_t eventId, int64_t beginTime, int64_t endTime, std::map<std::string, BundleActiveEventStats>& eventStats, int32_t userId)1801 void BundleActiveUsageDatabase::QueryDeviceEventStats(int32_t eventId, int64_t beginTime,
1802 int64_t endTime, std::map<std::string, BundleActiveEventStats>& eventStats, int32_t userId)
1803 {
1804 lock_guard<ffrt::mutex> lock(databaseMutex_);
1805 int64_t eventTableTime = ParseStartTime(eventTableName_);
1806 if (JudgeQueryCondition(beginTime, endTime, eventTableTime) == QUERY_CONDITION_INVALID) {
1807 return;
1808 }
1809 vector<string> queryCondition;
1810 int64_t diff = beginTime - eventTableTime;
1811 if (diff >= 0) {
1812 queryCondition.push_back(to_string(diff));
1813 } else {
1814 queryCondition.push_back(to_string(EVENT_TIME_IN_MILLIS_MIN));
1815 }
1816 queryCondition.push_back(to_string(endTime - eventTableTime));
1817 queryCondition.push_back(to_string(userId));
1818 queryCondition.push_back(to_string(eventId));
1819 string queryEventSql = "select * from " + eventTableName_ +
1820 " where timeStamp >= ? and timeStamp <= ? and userId = ? and eventId = ?";
1821 auto bundleActiveResult = QueryStatsInfoByStep(EVENT_DATABASE_INDEX,
1822 queryEventSql, queryCondition);
1823 if (bundleActiveResult == nullptr) {
1824 return;
1825 }
1826 int32_t tableRowNumber;
1827 bundleActiveResult->GetRowCount(tableRowNumber);
1828 if (tableRowNumber == 0) {
1829 return;
1830 }
1831 BundleActiveEventStats event;
1832 event.name_= GetSystemEventName(eventId);
1833 event.count_ = tableRowNumber;
1834 event.eventId_ = eventId;
1835 eventStats.insert(std::pair<std::string, BundleActiveEventStats>(event.name_, event));
1836 }
1837
GetSystemEventName(const int32_t userId)1838 std::string BundleActiveUsageDatabase::GetSystemEventName(const int32_t userId)
1839 {
1840 std::string systemEventName = "";
1841 switch (userId) {
1842 case BundleActiveEvent::SYSTEM_LOCK:
1843 systemEventName = OPERATION_SYSTEM_LOCK;
1844 break;
1845 case BundleActiveEvent::SYSTEM_UNLOCK:
1846 systemEventName = OPERATION_SYSTEM_UNLOCK;
1847 break;
1848 case BundleActiveEvent::SYSTEM_SLEEP:
1849 systemEventName = OPERATION_SYSTEM_SLEEP;
1850 break;
1851 case BundleActiveEvent::SYSTEM_WAKEUP:
1852 systemEventName = OPERATION_SYSTEM_WAKEUP;
1853 break;
1854 default:
1855 break;
1856 }
1857 return systemEventName;
1858 }
1859
QueryNotificationEventStats(int32_t eventId, int64_t beginTime, int64_t endTime, std::map<std::string, BundleActiveEventStats>& notificationEventStats, int32_t userId)1860 void BundleActiveUsageDatabase::QueryNotificationEventStats(int32_t eventId, int64_t beginTime,
1861 int64_t endTime, std::map<std::string, BundleActiveEventStats>& notificationEventStats, int32_t userId)
1862 {
1863 lock_guard<ffrt::mutex> lock(databaseMutex_);
1864 int64_t eventTableTime = ParseStartTime(eventTableName_);
1865 if (JudgeQueryCondition(beginTime, endTime, eventTableTime) == QUERY_CONDITION_INVALID) {
1866 return;
1867 }
1868 vector<string> queryCondition;
1869 int64_t diff = beginTime - eventTableTime;
1870 if (diff >= 0) {
1871 queryCondition.push_back(to_string(diff));
1872 } else {
1873 queryCondition.push_back(to_string(EVENT_TIME_IN_MILLIS_MIN));
1874 }
1875 queryCondition.push_back(to_string(endTime - eventTableTime));
1876 queryCondition.push_back(to_string(userId));
1877 queryCondition.push_back(to_string(eventId));
1878 string queryEventSql = "select * from " + eventTableName_ +
1879 " where timeStamp >= ? and timeStamp <= ? and userId = ? and eventId = ?";
1880 auto bundleActiveResult = QueryStatsInfoByStep(EVENT_DATABASE_INDEX,
1881 queryEventSql, queryCondition);
1882 if (bundleActiveResult == nullptr) {
1883 return;
1884 }
1885 int32_t tableRowNumber;
1886 bundleActiveResult->GetRowCount(tableRowNumber);
1887 if (tableRowNumber == 0) {
1888 return;
1889 }
1890 BundleActiveEventStats event;
1891 std::map<std::string, BundleActiveEventStats>::iterator iter;
1892 for (int32_t i = 0; i < tableRowNumber; i++) {
1893 bundleActiveResult->GoToRow(i);
1894 bundleActiveResult->GetString(BUNDLE_NAME_COLUMN_INDEX, event.name_);
1895 bundleActiveResult->GetInt(EVENT_ID_COLUMN_INDEX, event.eventId_);
1896 bundleActiveResult->GetInt(EVENT_UID_COLUMN_INDEX, event.uid_);
1897 iter = notificationEventStats.find(event.name_);
1898 if (iter != notificationEventStats.end()) {
1899 iter->second.count_++;
1900 } else {
1901 event.count_ = 1;
1902 notificationEventStats.insert(std::pair<std::string, BundleActiveEventStats>(event.name_, event));
1903 }
1904 }
1905 }
1906
JudgeQueryCondition(const int64_t beginTime, const int64_t endTime, const int64_t eventTableTime)1907 int32_t BundleActiveUsageDatabase::JudgeQueryCondition(const int64_t beginTime,
1908 const int64_t endTime, const int64_t eventTableTime)
1909 {
1910 if (eventTableName_ == UNKNOWN_TABLE_NAME) {
1911 BUNDLE_ACTIVE_LOGE("eventTable does not exist");
1912 return QUERY_CONDITION_INVALID;
1913 }
1914 if (endTime <= beginTime) {
1915 BUNDLE_ACTIVE_LOGE("endTime(%{public}lld) <= beginTime(%{public}lld)",
1916 (long long)endTime, (long long)beginTime);
1917 return QUERY_CONDITION_INVALID;
1918 }
1919 if (endTime < eventTableTime) {
1920 BUNDLE_ACTIVE_LOGE("endTime(%{public}lld) <= eventTableTime(%{public}lld)",
1921 (long long)endTime, (long long)eventTableTime);
1922 return QUERY_CONDITION_INVALID;
1923 }
1924 return QUERY_CONDITION_VALID;
1925 }
1926 } // namespace DeviceUsageStats
1927 } // namespace OHOS
1928
1929