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 BundleActiveBundleMgrHelper::GetInstance()->InsertPackageUid(usageStats->bundleName_, 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,const std::string & bundleName)1437 vector<BundleActivePackageStats> BundleActiveUsageDatabase::QueryDatabaseUsageStats(int32_t databaseType,
1438 int64_t beginTime, int64_t endTime, int32_t userId, const std::string& bundleName)
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
1451 GetQuerySqlCommand(beginTime, endTime, databaseType, i, startIndex,
1452 endIndex, userId, queryCondition, queryPackageSql);
1453 if (bundleName != "") {
1454 queryCondition.push_back(bundleName);
1455 queryPackageSql += " and bundleName = ?";
1456 }
1457 auto bundleActiveResult = QueryStatsInfoByStep(databaseType, queryPackageSql,
1458 queryCondition);
1459 if (bundleActiveResult == nullptr) {
1460 return databaseUsageStats;
1461 }
1462 int32_t tableRowNumber;
1463 bundleActiveResult->GetRowCount(tableRowNumber);
1464 BundleActivePackageStats usageStats;
1465 int64_t relativeLastTimeUsed;
1466 int64_t relativeLastTimeFrontServiceUsed;
1467 int64_t packageTableTime = sortedTableArray_.at(databaseType).at(i);
1468 for (int32_t j = 0; j < tableRowNumber; j++) {
1469 bundleActiveResult->GoToRow(j);
1470 bundleActiveResult->GetString(BUNDLE_NAME_COLUMN_INDEX, usageStats.bundleName_);
1471 bundleActiveResult->GetInt(BUNDLE_STARTED_COUNT_COLUMN_INDEX, usageStats.startCount_);
1472 bundleActiveResult->GetLong(LAST_TIME_COLUMN_INDEX, usageStats.lastTimeUsed_);
1473 bundleActiveResult->GetLong(LAST_TIME_COLUMN_INDEX, relativeLastTimeUsed);
1474 usageStats.lastTimeUsed_ = relativeLastTimeUsed == -1 ? -1 :
1475 relativeLastTimeUsed + packageTableTime;
1476 bundleActiveResult->GetLong(LAST_TIME_CONTINUOUS_TASK_COLUMN_INDEX, relativeLastTimeFrontServiceUsed);
1477 usageStats.lastContiniousTaskUsed_ = relativeLastTimeFrontServiceUsed == -1 ? -1 :
1478 relativeLastTimeFrontServiceUsed + packageTableTime;
1479 bundleActiveResult->GetLong(TOTAL_TIME_COLUMN_INDEX, usageStats.totalInFrontTime_);
1480 bundleActiveResult->GetLong(TOTAL_TIME_CONTINUOUS_TASK_COLUMN_INDEX,
1481 usageStats.totalContiniousTaskUsedTime_);
1482 bundleActiveResult->GetInt(PACKAGE_LOG_UID_COLUMN_INDEX, usageStats.uid_);
1483 usageStats.userId_ = userId;
1484 databaseUsageStats.push_back(usageStats);
1485 }
1486 queryCondition.clear();
1487 }
1488 return databaseUsageStats;
1489 }
1490
QueryDatabaseEvents(int64_t beginTime,int64_t endTime,int32_t userId,string bundleName)1491 vector<BundleActiveEvent> BundleActiveUsageDatabase::QueryDatabaseEvents(int64_t beginTime, int64_t endTime,
1492 int32_t userId, string bundleName)
1493 {
1494 lock_guard<ffrt::mutex> lock(databaseMutex_);
1495 vector<BundleActiveEvent> databaseEvents;
1496 int64_t eventTableTime = ParseStartTime(eventTableName_);
1497 if (JudgeQueryCondition(beginTime, endTime, eventTableTime) == QUERY_CONDITION_INVALID) {
1498 return databaseEvents;
1499 }
1500 vector<string> queryCondition;
1501 int64_t diff = beginTime - eventTableTime;
1502 if (diff >= 0) {
1503 queryCondition.push_back(to_string(diff));
1504 } else {
1505 queryCondition.push_back(to_string(EVENT_TIME_IN_MILLIS_MIN));
1506 }
1507 queryCondition.push_back(to_string(endTime - eventTableTime));
1508 queryCondition.push_back(to_string(userId));
1509 string queryEventSql;
1510 if (bundleName.empty()) {
1511 queryEventSql = "select * from " + eventTableName_ + " where timeStamp >= ? and timeStamp <= ? and userId = ?";
1512 } else {
1513 queryCondition.push_back(bundleName);
1514 queryEventSql = "select * from " + eventTableName_ +
1515 " where timeStamp >= ? and timeStamp <= ? and userId = ? and bundleName = ?";
1516 }
1517 auto bundleActiveResult = QueryStatsInfoByStep(EVENT_DATABASE_INDEX,
1518 queryEventSql, queryCondition);
1519 if (bundleActiveResult == nullptr) {
1520 return databaseEvents;
1521 }
1522 int32_t tableRowNumber;
1523 bundleActiveResult->GetRowCount(tableRowNumber);
1524 BundleActiveEvent event;
1525 string relativeTimeStamp;
1526 for (int32_t i = 0; i < tableRowNumber; i++) {
1527 bundleActiveResult->GoToRow(i);
1528 bundleActiveResult->GetString(BUNDLE_NAME_COLUMN_INDEX, event.bundleName_);
1529 bundleActiveResult->GetInt(EVENT_ID_COLUMN_INDEX, event.eventId_);
1530 bundleActiveResult->GetString(TIME_STAMP_COLUMN_INDEX, relativeTimeStamp);
1531 event.timeStamp_ = atoll(relativeTimeStamp.c_str()) + eventTableTime;
1532 bundleActiveResult->GetString(ABILITY_ID_COLUMN_INDEX, event.abilityId_);
1533 bundleActiveResult->GetInt(EVENT_UID_COLUMN_INDEX, event.uid_);
1534 databaseEvents.push_back(event);
1535 }
1536 return databaseEvents;
1537 }
1538
OnPackageUninstalled(const int32_t userId,const string & bundleName,const int32_t uid,const int32_t appIndex)1539 void BundleActiveUsageDatabase::OnPackageUninstalled(const int32_t userId, const string& bundleName,
1540 const int32_t uid, const int32_t appIndex)
1541 {
1542 lock_guard<ffrt::mutex> lock(databaseMutex_);
1543 for (uint32_t i = 0; i < sortedTableArray_.size(); i++) {
1544 if (sortedTableArray_.at(i).empty()) {
1545 continue;
1546 }
1547 for (uint32_t j = 0; j < sortedTableArray_.at(i).size(); j++) {
1548 string packageTableName = PACKAGE_LOG_TABLE + to_string(sortedTableArray_.at(i).at(j));
1549 DeleteUninstalledInfo(userId, bundleName, uid, packageTableName, i, appIndex);
1550 }
1551 }
1552 if (eventTableName_ != UNKNOWN_TABLE_NAME) {
1553 DeleteUninstalledInfo(userId, bundleName, uid, eventTableName_, EVENT_DATABASE_INDEX, appIndex);
1554 }
1555 if (bundleHistoryTableName_ != UNKNOWN_TABLE_NAME) {
1556 DeleteUninstalledInfo(userId, bundleName, uid, bundleHistoryTableName_, APP_GROUP_DATABASE_INDEX, appIndex);
1557 }
1558 if (moduleRecordsTableName_ != UNKNOWN_TABLE_NAME) {
1559 DeleteUninstalledInfo(userId, bundleName, uid, moduleRecordsTableName_, APP_GROUP_DATABASE_INDEX, appIndex);
1560 }
1561 if (formRecordsTableName_ != UNKNOWN_TABLE_NAME) {
1562 DeleteUninstalledInfo(userId, bundleName, uid, formRecordsTableName_, APP_GROUP_DATABASE_INDEX, appIndex);
1563 }
1564 }
1565
DeleteUninstalledInfo(const int32_t userId,const string & bundleName,const int32_t uid,const string & tableName,uint32_t databaseType,const int32_t appIndex)1566 void BundleActiveUsageDatabase::DeleteUninstalledInfo(const int32_t userId, const string& bundleName,
1567 const int32_t uid, const string& tableName, uint32_t databaseType, const int32_t appIndex)
1568 {
1569 shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(databaseType);
1570 if (rdbStore == nullptr) {
1571 BUNDLE_ACTIVE_LOGE("delete uninstalled info fail, rdbStore is nullptr");
1572 return;
1573 }
1574 int32_t deletedRows = BUNDLE_ACTIVE_FAIL;
1575 vector<string> queryCondition;
1576 queryCondition.push_back(to_string(userId));
1577 if (bundleName.empty()) {
1578 rdbStore->Delete(deletedRows, tableName, "userId = ?", queryCondition);
1579 return;
1580 }
1581 if (appIndex == MAIN_APP_INDEX) {
1582 queryCondition.push_back(bundleName);
1583 rdbStore->Delete(deletedRows, tableName, "userId = ? and bundleName = ?", queryCondition);
1584 return;
1585 }
1586 queryCondition.push_back(bundleName);
1587 queryCondition.push_back(to_string(uid));
1588 rdbStore->Delete(deletedRows, tableName, "userId = ? and bundleName = ? and uid = ?", queryCondition);
1589 }
1590
GetSystemTimeMs()1591 int64_t BundleActiveUsageDatabase::GetSystemTimeMs()
1592 {
1593 time_t now;
1594 (void)time(&now); // unit is seconds.
1595 if (static_cast<int64_t>(now) < 0) {
1596 BUNDLE_ACTIVE_LOGE("Get now time error");
1597 return 0;
1598 }
1599 auto tarEndTimePoint = std::chrono::system_clock::from_time_t(now);
1600 auto tarDuration = std::chrono::duration_cast<std::chrono::milliseconds>(tarEndTimePoint.time_since_epoch());
1601 int64_t tarDate = tarDuration.count();
1602 if (tarDate < 0) {
1603 BUNDLE_ACTIVE_LOGE("tarDuration is less than 0.");
1604 return -1;
1605 }
1606 return static_cast<int64_t>(tarDate);
1607 }
1608
UpdateModuleData(const int32_t userId,std::map<std::string,std::shared_ptr<BundleActiveModuleRecord>> & moduleRecords,const int64_t timeStamp)1609 void BundleActiveUsageDatabase::UpdateModuleData(const int32_t userId,
1610 std::map<std::string, std::shared_ptr<BundleActiveModuleRecord>>& moduleRecords, const int64_t timeStamp)
1611 {
1612 lock_guard<ffrt::mutex> lock(databaseMutex_);
1613 CheckDatabaseFile(APP_GROUP_DATABASE_INDEX);
1614 shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(APP_GROUP_DATABASE_INDEX);
1615 if (rdbStore == nullptr) {
1616 BUNDLE_ACTIVE_LOGE("update module data fail, rdbStore is nullptr");
1617 return;
1618 }
1619 CreateRecordTable(timeStamp);
1620 int64_t moduleTableTime = ParseStartTime(moduleRecordsTableName_);
1621 int32_t changeRow = BUNDLE_ACTIVE_FAIL;
1622 int64_t outRowId = BUNDLE_ACTIVE_FAIL;
1623 NativeRdb::ValuesBucket moduleValuesBucket;
1624 vector<string> queryCondition;
1625 for (const auto& oneModuleRecord : moduleRecords) {
1626 if (oneModuleRecord.second) {
1627 queryCondition.emplace_back(to_string(oneModuleRecord.second->userId_));
1628 queryCondition.emplace_back(oneModuleRecord.second->bundleName_);
1629 queryCondition.emplace_back(oneModuleRecord.second->moduleName_);
1630 queryCondition.emplace_back(to_string(oneModuleRecord.second->uid_));
1631 moduleValuesBucket.PutInt(BUNDLE_ACTIVE_DB_MODULE_LAUNCHED_COUNT, oneModuleRecord.second->launchedCount_);
1632 int64_t adjustLastTime = oneModuleRecord.second->lastModuleUsedTime_ != -1 ?
1633 oneModuleRecord.second->lastModuleUsedTime_ - moduleTableTime : -1;
1634 moduleValuesBucket.PutLong(BUNDLE_ACTIVE_DB_LAST_TIME, adjustLastTime);
1635 rdbStore->Update(changeRow, moduleRecordsTableName_, moduleValuesBucket,
1636 "userId = ? and bundleName = ? and moduleName = ? and uid = ?", queryCondition);
1637 if (changeRow == NO_UPDATE_ROW) {
1638 moduleValuesBucket.PutInt(BUNDLE_ACTIVE_DB_USER_ID, oneModuleRecord.second->userId_);
1639 moduleValuesBucket.PutString(BUNDLE_ACTIVE_DB_BUNDLE_NAME, oneModuleRecord.second->bundleName_);
1640 moduleValuesBucket.PutString(BUNDLE_ACTIVE_DB_MODULE_NAME, oneModuleRecord.second->moduleName_);
1641 moduleValuesBucket.PutInt(BUNDLE_ACTIVE_DB_UID, oneModuleRecord.second->uid_);
1642 rdbStore->Insert(outRowId, moduleRecordsTableName_, moduleValuesBucket);
1643 outRowId = BUNDLE_ACTIVE_FAIL;
1644 changeRow = BUNDLE_ACTIVE_FAIL;
1645 } else {
1646 changeRow = BUNDLE_ACTIVE_FAIL;
1647 }
1648 moduleValuesBucket.Clear();
1649 queryCondition.clear();
1650 for (const auto& oneFormRecord : oneModuleRecord.second->formRecords_) {
1651 UpdateFormData(oneModuleRecord.second->userId_, oneModuleRecord.second->bundleName_,
1652 oneModuleRecord.second->moduleName_, oneFormRecord, rdbStore);
1653 }
1654 }
1655 }
1656 }
1657
CreateRecordTable(const int64_t timeStamp)1658 void BundleActiveUsageDatabase::CreateRecordTable(const int64_t timeStamp)
1659 {
1660 if (moduleRecordsTableName_ == UNKNOWN_TABLE_NAME) {
1661 CreateModuleRecordTable(APP_GROUP_DATABASE_INDEX, timeStamp);
1662 }
1663 if (formRecordsTableName_ == UNKNOWN_TABLE_NAME) {
1664 CreateFormRecordTable(APP_GROUP_DATABASE_INDEX, timeStamp);
1665 }
1666 }
1667
UpdateFormData(const int32_t userId,const std::string bundleName,const string moduleName,const BundleActiveFormRecord & formRecord,std::shared_ptr<NativeRdb::RdbStore> rdbStore)1668 void BundleActiveUsageDatabase::UpdateFormData(const int32_t userId, const std::string bundleName,
1669 const string moduleName, const BundleActiveFormRecord& formRecord,
1670 std::shared_ptr<NativeRdb::RdbStore> rdbStore)
1671 {
1672 if (rdbStore == nullptr) {
1673 return;
1674 }
1675 int64_t formRecordsTableTime = ParseStartTime(formRecordsTableName_);
1676 NativeRdb::ValuesBucket formValueBucket;
1677 vector<string> queryCondition;
1678 int32_t changeRow = BUNDLE_ACTIVE_FAIL;
1679 int64_t outRowId = BUNDLE_ACTIVE_FAIL;
1680 queryCondition.emplace_back(to_string(userId));
1681 queryCondition.emplace_back(bundleName);
1682 queryCondition.emplace_back(moduleName);
1683 queryCondition.emplace_back(formRecord.formName_);
1684 queryCondition.emplace_back(to_string(formRecord.formDimension_));
1685 queryCondition.emplace_back(to_string(formRecord.formId_));
1686 queryCondition.emplace_back(to_string(formRecord.uid_));
1687 formValueBucket.PutInt(BUNDLE_ACTIVE_DB_FORM_TOUCH_COUNT, formRecord.count_);
1688 int64_t adjustLastTime = formRecord.formLastUsedTime_ != -1 ? formRecord.formLastUsedTime_ -
1689 formRecordsTableTime : -1;
1690 formValueBucket.PutLong(BUNDLE_ACTIVE_DB_LAST_TIME, adjustLastTime);
1691 rdbStore->Update(changeRow, formRecordsTableName_, formValueBucket,
1692 "userId = ? and bundleName = ? and moduleName = ? and formName = ? and formDimension = ? "
1693 "and formId = ?",
1694 queryCondition);
1695 if (changeRow == NO_UPDATE_ROW) {
1696 formValueBucket.PutInt(BUNDLE_ACTIVE_DB_USER_ID, userId);
1697 formValueBucket.PutString(BUNDLE_ACTIVE_DB_BUNDLE_NAME, bundleName);
1698 formValueBucket.PutString(BUNDLE_ACTIVE_DB_MODULE_NAME, moduleName);
1699 formValueBucket.PutString(BUNDLE_ACTIVE_DB_FORM_NAME, formRecord.formName_);
1700 formValueBucket.PutInt(BUNDLE_ACTIVE_DB_FORM_DIMENSION, formRecord.formDimension_);
1701 formValueBucket.PutInt(BUNDLE_ACTIVE_DB_FORM_ID, formRecord.formId_);
1702 formValueBucket.PutInt(BUNDLE_ACTIVE_DB_FORM_ID, formRecord.uid_);
1703 rdbStore->Insert(outRowId, formRecordsTableName_, formValueBucket);
1704 }
1705 }
1706
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)1707 void BundleActiveUsageDatabase::RemoveFormData(const int32_t userId, const std::string bundleName,
1708 const std::string moduleName, const std::string formName, const int32_t formDimension,
1709 const int64_t formId, const int32_t uid)
1710 {
1711 lock_guard<ffrt::mutex> lock(databaseMutex_);
1712 shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(APP_GROUP_DATABASE_INDEX);
1713 if (rdbStore == nullptr) {
1714 BUNDLE_ACTIVE_LOGE("remove for data fail, rdbStore is nullptr");
1715 return;
1716 }
1717 int32_t deletedRows = BUNDLE_ACTIVE_FAIL;
1718 if (formRecordsTableName_ != UNKNOWN_TABLE_NAME) {
1719 vector<string> queryCondition;
1720 queryCondition.emplace_back(to_string(userId));
1721 queryCondition.emplace_back(bundleName);
1722 queryCondition.emplace_back(moduleName);
1723 queryCondition.emplace_back(formName);
1724 queryCondition.emplace_back(to_string(formDimension));
1725 queryCondition.emplace_back(to_string(formId));
1726 int32_t ret = rdbStore->Delete(deletedRows, formRecordsTableName_,
1727 "userId = ? and bundleName = ? and moduleName = ? and formName = ? and formDimension = ? "
1728 "and formId = ? and uid = ?",
1729 queryCondition);
1730 if (ret != NativeRdb::E_OK) {
1731 BUNDLE_ACTIVE_LOGE("delete event data failed, rdb error number: %{public}d", ret);
1732 }
1733 }
1734 }
1735
LoadModuleData(const int32_t userId,std::map<std::string,std::shared_ptr<BundleActiveModuleRecord>> & moduleRecords)1736 void BundleActiveUsageDatabase::LoadModuleData(const int32_t userId, std::map<std::string,
1737 std::shared_ptr<BundleActiveModuleRecord>>& moduleRecords)
1738 {
1739 lock_guard<ffrt::mutex> lock(databaseMutex_);
1740 string queryModuleSql = "select * from " + moduleRecordsTableName_ + " where userId = ?";
1741 vector<string> queryCondition;
1742 queryCondition.emplace_back(to_string(userId));
1743 auto moduleRecordResult = QueryStatsInfoByStep(APP_GROUP_DATABASE_INDEX, queryModuleSql,
1744 queryCondition);
1745 if (!moduleRecordResult) {
1746 return;
1747 }
1748 int64_t baseTime = ParseStartTime(moduleRecordsTableName_);
1749 int32_t numOfModuleRecord = 0;
1750 moduleRecordResult->GetRowCount(numOfModuleRecord);
1751 for (int32_t i = 0; i < numOfModuleRecord; i++) {
1752 shared_ptr<BundleActiveModuleRecord> oneModuleRecord = make_shared<BundleActiveModuleRecord>();
1753 moduleRecordResult->GoToRow(i);
1754 moduleRecordResult->GetInt(USER_ID_COLUMN_INDEX, oneModuleRecord->userId_);
1755 moduleRecordResult->GetString(BUNDLE_NAME_COLUMN_INDEX, oneModuleRecord->bundleName_);
1756 moduleRecordResult->GetString(MODULE_NAME_COLUMN_INDEX, oneModuleRecord->moduleName_);
1757 moduleRecordResult->GetInt(MODULE_USED_COUNT_COLUMN_INDEX, oneModuleRecord->launchedCount_);
1758 moduleRecordResult->GetInt(MODULE_UID_COLUMN_INDEX, oneModuleRecord->uid_);
1759 int64_t relativeLastTime = 0;
1760 moduleRecordResult->GetLong(MODULE_LAST_TIME_COLUMN_INDEX, relativeLastTime);
1761 oneModuleRecord->lastModuleUsedTime_ = relativeLastTime != -1 ? relativeLastTime + baseTime : -1;
1762 string combinedInfo = oneModuleRecord->bundleName_
1763 + " " + to_string(oneModuleRecord->uid_) + " " + oneModuleRecord->moduleName_;
1764 moduleRecords[combinedInfo] = oneModuleRecord;
1765 }
1766 }
1767
LoadFormData(const int32_t userId,std::map<std::string,std::shared_ptr<BundleActiveModuleRecord>> & moduleRecords)1768 void BundleActiveUsageDatabase::LoadFormData(const int32_t userId, std::map<std::string,
1769 std::shared_ptr<BundleActiveModuleRecord>>& moduleRecords)
1770 {
1771 lock_guard<ffrt::mutex> lock(databaseMutex_);
1772 string queryFormSql = "select * from " + formRecordsTableName_ + " where userId = ?";
1773 vector<string> queryCondition;
1774 queryCondition.emplace_back(to_string(userId));
1775 auto formRecordResult = QueryStatsInfoByStep(APP_GROUP_DATABASE_INDEX, queryFormSql,
1776 queryCondition);
1777 if (!formRecordResult) {
1778 return;
1779 }
1780 int32_t numOfFormRecord = 0;
1781 int64_t baseTime = ParseStartTime(formRecordsTableName_);
1782 formRecordResult->GetRowCount(numOfFormRecord);
1783 for (int32_t i = 0; i < numOfFormRecord; i++) {
1784 BundleActiveFormRecord oneFormRecord;
1785 string moduleName = "";
1786 string bundleName = "";
1787 formRecordResult->GoToRow(i);
1788 formRecordResult->GetInt(USER_ID_COLUMN_INDEX, oneFormRecord.userId_);
1789 formRecordResult->GetString(BUNDLE_NAME_COLUMN_INDEX, bundleName);
1790 formRecordResult->GetString(MODULE_NAME_COLUMN_INDEX, moduleName);
1791 formRecordResult->GetString(FORM_NAME_COLUMN_INDEX, oneFormRecord.formName_);
1792 formRecordResult->GetInt(FORM_DIMENSION_COLUMN_INDEX, oneFormRecord.formDimension_);
1793 formRecordResult->GetLong(FORM_ID_COLUMN_INDEX, oneFormRecord.formId_);
1794 formRecordResult->GetInt(FORM_COUNT_COLUMN_INDEX, oneFormRecord.count_);
1795 formRecordResult->GetInt(FORM_UID_COLUMN_INDEX, oneFormRecord.uid_);
1796 int64_t relativeLastTime = 0;
1797 formRecordResult->GetLong(FORM_LAST_TIME_COLUMN_INDEX, relativeLastTime);
1798 oneFormRecord.formLastUsedTime_ = relativeLastTime != -1 ? relativeLastTime + baseTime : -1;
1799 auto it = moduleRecords.find(bundleName + " " + to_string(oneFormRecord.uid_) + " " + moduleName);
1800 if (it != moduleRecords.end() && it->second) {
1801 it->second->formRecords_.emplace_back(oneFormRecord);
1802 }
1803 }
1804 }
1805
QueryDeviceEventStats(int32_t eventId,int64_t beginTime,int64_t endTime,std::map<std::string,BundleActiveEventStats> & eventStats,int32_t userId)1806 void BundleActiveUsageDatabase::QueryDeviceEventStats(int32_t eventId, int64_t beginTime,
1807 int64_t endTime, std::map<std::string, BundleActiveEventStats>& eventStats, int32_t userId)
1808 {
1809 lock_guard<ffrt::mutex> lock(databaseMutex_);
1810 int64_t eventTableTime = ParseStartTime(eventTableName_);
1811 if (JudgeQueryCondition(beginTime, endTime, eventTableTime) == QUERY_CONDITION_INVALID) {
1812 return;
1813 }
1814 vector<string> queryCondition;
1815 int64_t diff = beginTime - eventTableTime;
1816 if (diff >= 0) {
1817 queryCondition.push_back(to_string(diff));
1818 } else {
1819 queryCondition.push_back(to_string(EVENT_TIME_IN_MILLIS_MIN));
1820 }
1821 queryCondition.push_back(to_string(endTime - eventTableTime));
1822 queryCondition.push_back(to_string(userId));
1823 queryCondition.push_back(to_string(eventId));
1824 string queryEventSql = "select * from " + eventTableName_ +
1825 " where timeStamp >= ? and timeStamp <= ? and userId = ? and eventId = ?";
1826 auto bundleActiveResult = QueryStatsInfoByStep(EVENT_DATABASE_INDEX,
1827 queryEventSql, queryCondition);
1828 if (bundleActiveResult == nullptr) {
1829 return;
1830 }
1831 int32_t tableRowNumber;
1832 bundleActiveResult->GetRowCount(tableRowNumber);
1833 if (tableRowNumber == 0) {
1834 return;
1835 }
1836 BundleActiveEventStats event;
1837 event.name_= GetSystemEventName(eventId);
1838 event.count_ = tableRowNumber;
1839 event.eventId_ = eventId;
1840 eventStats.insert(std::pair<std::string, BundleActiveEventStats>(event.name_, event));
1841 }
1842
GetSystemEventName(const int32_t userId)1843 std::string BundleActiveUsageDatabase::GetSystemEventName(const int32_t userId)
1844 {
1845 std::string systemEventName = "";
1846 switch (userId) {
1847 case BundleActiveEvent::SYSTEM_LOCK:
1848 systemEventName = OPERATION_SYSTEM_LOCK;
1849 break;
1850 case BundleActiveEvent::SYSTEM_UNLOCK:
1851 systemEventName = OPERATION_SYSTEM_UNLOCK;
1852 break;
1853 case BundleActiveEvent::SYSTEM_SLEEP:
1854 systemEventName = OPERATION_SYSTEM_SLEEP;
1855 break;
1856 case BundleActiveEvent::SYSTEM_WAKEUP:
1857 systemEventName = OPERATION_SYSTEM_WAKEUP;
1858 break;
1859 default:
1860 break;
1861 }
1862 return systemEventName;
1863 }
1864
QueryNotificationEventStats(int32_t eventId,int64_t beginTime,int64_t endTime,std::map<std::string,BundleActiveEventStats> & notificationEventStats,int32_t userId)1865 void BundleActiveUsageDatabase::QueryNotificationEventStats(int32_t eventId, int64_t beginTime,
1866 int64_t endTime, std::map<std::string, BundleActiveEventStats>& notificationEventStats, int32_t userId)
1867 {
1868 lock_guard<ffrt::mutex> lock(databaseMutex_);
1869 int64_t eventTableTime = ParseStartTime(eventTableName_);
1870 if (JudgeQueryCondition(beginTime, endTime, eventTableTime) == QUERY_CONDITION_INVALID) {
1871 return;
1872 }
1873 vector<string> queryCondition;
1874 int64_t diff = beginTime - eventTableTime;
1875 if (diff >= 0) {
1876 queryCondition.push_back(to_string(diff));
1877 } else {
1878 queryCondition.push_back(to_string(EVENT_TIME_IN_MILLIS_MIN));
1879 }
1880 queryCondition.push_back(to_string(endTime - eventTableTime));
1881 queryCondition.push_back(to_string(userId));
1882 queryCondition.push_back(to_string(eventId));
1883 string queryEventSql = "select * from " + eventTableName_ +
1884 " where timeStamp >= ? and timeStamp <= ? and userId = ? and eventId = ?";
1885 auto bundleActiveResult = QueryStatsInfoByStep(EVENT_DATABASE_INDEX,
1886 queryEventSql, queryCondition);
1887 if (bundleActiveResult == nullptr) {
1888 return;
1889 }
1890 int32_t tableRowNumber;
1891 bundleActiveResult->GetRowCount(tableRowNumber);
1892 if (tableRowNumber == 0) {
1893 return;
1894 }
1895 BundleActiveEventStats event;
1896 std::map<std::string, BundleActiveEventStats>::iterator iter;
1897 for (int32_t i = 0; i < tableRowNumber; i++) {
1898 bundleActiveResult->GoToRow(i);
1899 bundleActiveResult->GetString(BUNDLE_NAME_COLUMN_INDEX, event.name_);
1900 bundleActiveResult->GetInt(EVENT_ID_COLUMN_INDEX, event.eventId_);
1901 bundleActiveResult->GetInt(EVENT_UID_COLUMN_INDEX, event.uid_);
1902 iter = notificationEventStats.find(event.name_);
1903 if (iter != notificationEventStats.end()) {
1904 iter->second.count_++;
1905 } else {
1906 event.count_ = 1;
1907 notificationEventStats.insert(std::pair<std::string, BundleActiveEventStats>(event.name_, event));
1908 }
1909 }
1910 }
1911
JudgeQueryCondition(const int64_t beginTime,const int64_t endTime,const int64_t eventTableTime)1912 int32_t BundleActiveUsageDatabase::JudgeQueryCondition(const int64_t beginTime,
1913 const int64_t endTime, const int64_t eventTableTime)
1914 {
1915 if (eventTableName_ == UNKNOWN_TABLE_NAME) {
1916 BUNDLE_ACTIVE_LOGE("eventTable does not exist");
1917 return QUERY_CONDITION_INVALID;
1918 }
1919 if (endTime <= beginTime) {
1920 BUNDLE_ACTIVE_LOGE("endTime(%{public}lld) <= beginTime(%{public}lld)",
1921 (long long)endTime, (long long)beginTime);
1922 return QUERY_CONDITION_INVALID;
1923 }
1924 if (endTime < eventTableTime) {
1925 BUNDLE_ACTIVE_LOGE("endTime(%{public}lld) <= eventTableTime(%{public}lld)",
1926 (long long)endTime, (long long)eventTableTime);
1927 return QUERY_CONDITION_INVALID;
1928 }
1929 return QUERY_CONDITION_VALID;
1930 }
1931 } // namespace DeviceUsageStats
1932 } // namespace OHOS
1933
1934