• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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