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