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