• 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         config.SetSecurityLevel(NativeRdb::SecurityLevel::S1);
419         rdbStore = RdbHelper::GetRdbStore(config, BUNDLE_ACTIVE_RDB_VERSION, rdbDataCallBack, errCode);
420         if ((rdbStore == nullptr)) {
421             BUNDLE_ACTIVE_LOGE("rdbStore is nullptr");
422             return nullptr;
423         }
424         bundleActiveRdbStoreCache_.insert(pair {file, rdbStore});
425     } else {
426         rdbStore = bundleActiveRdbStoreCache_[file];
427     }
428     if (rdbStore == nullptr) {
429         BUNDLE_ACTIVE_LOGE("rdbStore is nullptr");
430         return nullptr;
431     }
432     return rdbStore;
433 }
434 
CheckDatabaseFile(uint32_t databaseType)435 void BundleActiveUsageDatabase::CheckDatabaseFile(uint32_t databaseType)
436 {
437     std::string databaseFileName = databaseFiles_.at(databaseType);
438     for (uint32_t i = 0; i < sizeof(SUFFIX_TYPE) / sizeof(SUFFIX_TYPE[0]); i++) {
439         std::string dbFile = BUNDLE_ACTIVE_DATABASE_DIR + DATABASE_TYPE[databaseType] + SUFFIX_TYPE[i];
440         if ((access(dbFile.c_str(), F_OK) != 0)
441             && (bundleActiveRdbStoreCache_.find(databaseFileName) != bundleActiveRdbStoreCache_.end())) {
442             bundleActiveRdbStoreCache_.erase(databaseFileName);
443             std::string rdbStorePath = BUNDLE_ACTIVE_DATABASE_DIR + DATABASE_TYPE[databaseType] + SUFFIX_TYPE[0];
444             RdbHelper::DeleteRdbStore(rdbStorePath);
445             if (databaseType >= 0 && databaseType < sortedTableArray_.size()) {
446                 sortedTableArray_.at(databaseType).clear();
447             } else if (databaseType == EVENT_DATABASE_INDEX) {
448                 eventTableName_ = UNKNOWN_TABLE_NAME;
449             } else if (databaseType == APP_GROUP_DATABASE_INDEX) {
450                 durationTableName_ = UNKNOWN_TABLE_NAME;
451                 bundleHistoryTableName_ = UNKNOWN_TABLE_NAME;
452                 moduleRecordsTableName_ = UNKNOWN_TABLE_NAME;
453                 formRecordsTableName_ = UNKNOWN_TABLE_NAME;
454             }
455             return;
456         }
457     }
458 }
459 
CreateEventLogTable(uint32_t databaseType,int64_t currentTimeMillis)460 int32_t BundleActiveUsageDatabase::CreateEventLogTable(uint32_t databaseType, int64_t currentTimeMillis)
461 {
462     shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(databaseType);
463     if (rdbStore == nullptr) {
464         BUNDLE_ACTIVE_LOGE("rdbStore is nullptr");
465         return BUNDLE_ACTIVE_FAIL;
466     }
467     string eventTable = EVENT_LOG_TABLE + to_string(currentTimeMillis);
468     eventTableName_ = eventTable;
469     const string createEventTableSql = "CREATE TABLE IF NOT EXISTS "
470                                            + eventTable
471                                            + " ("
472                                            + BUNDLE_ACTIVE_DB_USER_ID + " INTEGER NOT NULL, "
473                                            + BUNDLE_ACTIVE_DB_BUNDLE_NAME + " TEXT NOT NULL, "
474                                            + BUNDLE_ACTIVE_DB_EVENT_ID + " INTEGER NOT NULL, "
475                                            + BUNDLE_ACTIVE_DB_TIME_STAMP + " INTEGER NOT NULL, "
476                                            + BUNDLE_ACTIVE_DB_ABILITY_ID + " TEXT NOT NULL);";
477     int32_t createEventTable = rdbStore->ExecuteSql(createEventTableSql);
478     if (createEventTable != NativeRdb::E_OK) {
479         BUNDLE_ACTIVE_LOGE("create event table failed, rdb error number: %{public}d", createEventTable);
480         return createEventTable;
481     }
482     string createEventTableIndex = GetTableIndexSql(EVENT_DATABASE_INDEX, currentTimeMillis, true);
483     int32_t createResult = rdbStore->ExecuteSql(createEventTableIndex);
484     if (createResult != NativeRdb::E_OK) {
485         BUNDLE_ACTIVE_LOGE("create event table index failed, rdb error number: %{public}d", createResult);
486         return BUNDLE_ACTIVE_FAIL;
487     }
488     return BUNDLE_ACTIVE_SUCCESS;
489 }
490 
CreatePackageLogTable(uint32_t databaseType,int64_t currentTimeMillis)491 int32_t BundleActiveUsageDatabase::CreatePackageLogTable(uint32_t databaseType, int64_t currentTimeMillis)
492 {
493     shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(databaseType);
494     if (rdbStore == nullptr) {
495         BUNDLE_ACTIVE_LOGE("rdbStore is nullptr");
496         return BUNDLE_ACTIVE_FAIL;
497     }
498     string packageTable = PACKAGE_LOG_TABLE + to_string(currentTimeMillis);
499     string createPackageTableSql = "CREATE TABLE IF NOT EXISTS "
500                                         + packageTable
501                                         + " ("
502                                         + BUNDLE_ACTIVE_DB_USER_ID + " INTEGER NOT NULL, "
503                                         + BUNDLE_ACTIVE_DB_BUNDLE_NAME + " TEXT NOT NULL, "
504                                         + BUNDLE_ACTIVE_DB_BUNDLE_STARTED_COUNT + " INTEGER NOT NULL, "
505                                         + BUNDLE_ACTIVE_DB_LAST_TIME + " INTEGER NOT NULL, "
506                                         + BUNDLE_ACTIVE_DB_LAST_TIME_CONTINUOUS_TASK + " INTEGER NOT NULL, "
507                                         + BUNDLE_ACTIVE_DB_TOTAL_TIME + " INTEGER NOT NULL, "
508                                         + BUNDLE_ACTIVE_DB_TOTAL_TIME_CONTINUOUS_TASK + " INTEGER NOT NULL);";
509     int32_t createPackageTable = rdbStore->ExecuteSql(createPackageTableSql);
510     if (createPackageTable != NativeRdb::E_OK) {
511         BUNDLE_ACTIVE_LOGE("create packageLog table failed, rdb error number: %{public}d", createPackageTable);
512         return BUNDLE_ACTIVE_FAIL;
513     }
514     string createPackageTableIndex = GetTableIndexSql(databaseType, currentTimeMillis, true);
515     int32_t createResult = rdbStore->ExecuteSql(createPackageTableIndex);
516     if (createResult != NativeRdb::E_OK) {
517         BUNDLE_ACTIVE_LOGE("create package table index failed, rdb error number: %{public}d", createResult);
518         return BUNDLE_ACTIVE_FAIL;
519     }
520     return BUNDLE_ACTIVE_SUCCESS;
521 }
522 
CreateModuleRecordTable(uint32_t databaseType,int64_t timeStamp)523 int32_t BundleActiveUsageDatabase::CreateModuleRecordTable(uint32_t databaseType, int64_t timeStamp)
524 {
525     shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(databaseType);
526     if (rdbStore == nullptr) {
527         BUNDLE_ACTIVE_LOGE("rdbStore is nullptr");
528         return BUNDLE_ACTIVE_FAIL;
529     }
530     string moduleRecord = MODULE_RECORD_LOG_TABLE + to_string(timeStamp);
531     moduleRecordsTableName_ = moduleRecord;
532     string createModuleRecordTableSql = "CREATE TABLE IF NOT EXISTS "
533                                         + moduleRecord
534                                         + " ("
535                                         + BUNDLE_ACTIVE_DB_USER_ID + " INTEGER NOT NULL, "
536                                         + BUNDLE_ACTIVE_DB_BUNDLE_NAME + " TEXT NOT NULL, "
537                                         + BUNDLE_ACTIVE_DB_MODULE_NAME + " TEXT NOT NULL, "
538                                         + BUNDLE_ACTIVE_DB_MODULE_LAUNCHED_COUNT + " INTEGER NOT NULL, "
539                                         + BUNDLE_ACTIVE_DB_LAST_TIME + " INTEGER NOT NULL);";
540     int32_t createModuleRecordTable = rdbStore->ExecuteSql(createModuleRecordTableSql);
541     if (createModuleRecordTable != NativeRdb::E_OK) {
542         BUNDLE_ACTIVE_LOGE("create ModuleRecord table failed, rdb error number: %{public}d", createModuleRecordTable);
543         return BUNDLE_ACTIVE_FAIL;
544     }
545     string createModuleTableIndex = GetTableIndexSql(databaseType, timeStamp, true, BUNDLE_ACTIVE_DB_INDEX_MODULE);
546     int32_t createResult = rdbStore->ExecuteSql(createModuleTableIndex);
547     if (createResult != NativeRdb::E_OK) {
548         BUNDLE_ACTIVE_LOGE("create module table index failed, rdb error number: %{public}d", createResult);
549         return BUNDLE_ACTIVE_FAIL;
550     }
551     return BUNDLE_ACTIVE_SUCCESS;
552 }
553 
CreateFormRecordTable(uint32_t databaseType,int64_t timeStamp)554 int32_t BundleActiveUsageDatabase::CreateFormRecordTable(uint32_t databaseType, int64_t timeStamp)
555 {
556     shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(databaseType);
557     if (rdbStore == nullptr) {
558         BUNDLE_ACTIVE_LOGE("rdbStore is nullptr");
559         return BUNDLE_ACTIVE_FAIL;
560     }
561     string formRecord = FORM_RECORD_LOG_TABLE + to_string(timeStamp);
562     formRecordsTableName_ = formRecord;
563     string createFormRecordTableSql = "CREATE TABLE IF NOT EXISTS "
564                                         + formRecord
565                                         + " ("
566                                         + BUNDLE_ACTIVE_DB_USER_ID + " INTEGER NOT NULL, "
567                                         + BUNDLE_ACTIVE_DB_BUNDLE_NAME + " TEXT NOT NULL, "
568                                         + BUNDLE_ACTIVE_DB_MODULE_NAME + " TEXT NOT NULL, "
569                                         + BUNDLE_ACTIVE_DB_FORM_NAME + " TEXT NOT NULL, "
570                                         + BUNDLE_ACTIVE_DB_FORM_DIMENSION + " INTEGER NOT NULL, "
571                                         + BUNDLE_ACTIVE_DB_FORM_ID + " INTEGER NOT NULL, "
572                                         + BUNDLE_ACTIVE_DB_FORM_TOUCH_COUNT + " INTEGER NOT NULL, "
573                                         + BUNDLE_ACTIVE_DB_LAST_TIME + " INTEGER NOT NULL);";
574     int32_t createFormRecordTable = rdbStore->ExecuteSql(createFormRecordTableSql);
575     if (createFormRecordTable != NativeRdb::E_OK) {
576         BUNDLE_ACTIVE_LOGE("create ModuleRecord table failed, rdb error number: %{public}d", createFormRecordTable);
577         return BUNDLE_ACTIVE_FAIL;
578     }
579     string createFormTableIndex = GetTableIndexSql(databaseType, timeStamp, true, BUNDLE_ACTIVE_DB_INDEX_FORM);
580     int32_t createResult = rdbStore->ExecuteSql(createFormTableIndex);
581     if (createResult != NativeRdb::E_OK) {
582         BUNDLE_ACTIVE_LOGE("create module table index failed, rdb error number: %{public}d", createResult);
583         return BUNDLE_ACTIVE_FAIL;
584     }
585     return BUNDLE_ACTIVE_SUCCESS;
586 }
587 
CreateDurationTable(uint32_t databaseType)588 int32_t BundleActiveUsageDatabase::CreateDurationTable(uint32_t databaseType)
589 {
590     shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(databaseType);
591     if (rdbStore == nullptr) {
592         BUNDLE_ACTIVE_LOGE("rdbStore is nullptr");
593         return BUNDLE_ACTIVE_FAIL;
594     }
595     string createDurationTableSql = "CREATE TABLE IF NOT EXISTS "
596                                         + DURATION_LOG_TABLE
597                                         + " ("
598                                         + BUNDLE_ACTIVE_DB_BOOT_BASED_DURATION + " INTEGER NOT NULL, "
599                                         + BUNDLE_ACTIVE_DB_SCREEN_ON_DURATION + " INTEGER NOT NULL);";
600     int32_t createDurationTable = rdbStore->ExecuteSql(createDurationTableSql);
601     if (createDurationTable != NativeRdb::E_OK) {
602         BUNDLE_ACTIVE_LOGE("create duration table failed, rdb error number: %{public}d", createDurationTable);
603         return BUNDLE_ACTIVE_FAIL;
604     }
605     return BUNDLE_ACTIVE_SUCCESS;
606 }
607 
CreateBundleHistoryTable(uint32_t databaseType)608 int32_t BundleActiveUsageDatabase::CreateBundleHistoryTable(uint32_t databaseType)
609 {
610     shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(databaseType);
611     if (rdbStore == nullptr) {
612         BUNDLE_ACTIVE_LOGE("rdbStore is nullptr");
613         return BUNDLE_ACTIVE_FAIL;
614     }
615     string createBundleHistoryTableSql = "CREATE TABLE IF NOT EXISTS "
616                                         + BUNDLE_HISTORY_LOG_TABLE
617                                         + " ("
618                                         + BUNDLE_ACTIVE_DB_USER_ID + " INTEGER NOT NULL, "
619                                         + BUNDLE_ACTIVE_DB_BUNDLE_NAME + " TEXT NOT NULL, "
620                                         + BUNDLE_ACTIVE_DB_LAST_BOOT_FROM_USED_TIME + " INTEGER NOT NULL, "
621                                         + BUNDLE_ACTIVE_DB_LAST_SCREEN_USED_TIME + " INTEGER NOT NULL, "
622                                         + BUNDLE_ACTIVE_DB_CURRENT_GROUP + " INTEGER NOT NULL, "
623                                         + BUNDLE_ACTIVE_DB_REASON_IN_GROUP + " INTEGER NOT NULL, "
624                                         + BUNDLE_ACTIVE_DB_BUNDLE_ALIVE_TIMEOUT_TIME + " INTEGER NOT NULL, "
625                                         + BUNDLE_ACTIVE_DB_BUNDLE_DAILY_TIMEOUT_TIME + " INTEGER NOT NULL);";
626     int32_t createBundleHistoryTable = rdbStore->ExecuteSql(createBundleHistoryTableSql);
627     if (createBundleHistoryTable != NativeRdb::E_OK) {
628         BUNDLE_ACTIVE_LOGE("create bundleHistory table failed, rdb error number: %{public}d", createBundleHistoryTable);
629         return createBundleHistoryTable;
630     }
631     int32_t time = 0;
632     string createBundleHistoryTableIndex = GetTableIndexSql(databaseType, time, true);
633     int32_t createResult = rdbStore->ExecuteSql(createBundleHistoryTableIndex);
634     if (createResult != NativeRdb::E_OK) {
635         BUNDLE_ACTIVE_LOGE("create bundleHistory table index failed, rdb error number: %{public}d", createResult);
636         return BUNDLE_ACTIVE_FAIL;
637     }
638     return BUNDLE_ACTIVE_SUCCESS;
639 }
640 
PutBundleHistoryData(int32_t userId,shared_ptr<map<string,shared_ptr<BundleActivePackageHistory>>> userHistory)641 void BundleActiveUsageDatabase::PutBundleHistoryData(int32_t userId,
642     shared_ptr<map<string, shared_ptr<BundleActivePackageHistory>>> userHistory)
643 {
644     lock_guard<mutex> lock(databaseMutex_);
645     if (userHistory == nullptr) {
646         BUNDLE_ACTIVE_LOGE("userHistory is nullptr");
647         return;
648     }
649     shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(APP_GROUP_DATABASE_INDEX);
650     if (rdbStore == nullptr) {
651         return;
652     }
653     CheckDatabaseFile(APP_GROUP_DATABASE_INDEX);
654     if (bundleHistoryTableName_ == UNKNOWN_TABLE_NAME) {
655         CreateBundleHistoryTable(APP_GROUP_DATABASE_INDEX);
656         bundleHistoryTableName_ = BUNDLE_HISTORY_LOG_TABLE;
657     }
658     int32_t changeRow = BUNDLE_ACTIVE_FAIL;
659     int64_t outRowId = BUNDLE_ACTIVE_FAIL;
660     NativeRdb::ValuesBucket valuesBucket;
661     vector<string> queryCondition;
662     int32_t updatedcount = 0;
663     int32_t unupdatedcount = 0;
664     for (auto iter = userHistory->begin(); iter != userHistory->end(); iter++) {
665         if (iter->second == nullptr || !iter->second->isChanged_) {
666             unupdatedcount++;
667             continue;
668         }
669         queryCondition.push_back(to_string(userId));
670         queryCondition.push_back(iter->first);
671         valuesBucket.PutLong(BUNDLE_ACTIVE_DB_LAST_BOOT_FROM_USED_TIME, iter->second->lastBootFromUsedTimeStamp_);
672         valuesBucket.PutLong(BUNDLE_ACTIVE_DB_LAST_SCREEN_USED_TIME, iter->second->lastScreenUsedTimeStamp_);
673         valuesBucket.PutInt(BUNDLE_ACTIVE_DB_CURRENT_GROUP, iter->second->currentGroup_);
674         valuesBucket.PutInt(BUNDLE_ACTIVE_DB_REASON_IN_GROUP, static_cast<int32_t>(iter->second->reasonInGroup_));
675         valuesBucket.PutLong(BUNDLE_ACTIVE_DB_BUNDLE_ALIVE_TIMEOUT_TIME, iter->second->bundleAliveTimeoutTimeStamp_);
676         valuesBucket.PutLong(BUNDLE_ACTIVE_DB_BUNDLE_DAILY_TIMEOUT_TIME, iter->second->bundleDailyTimeoutTimeStamp_);
677         rdbStore->Update(changeRow, BUNDLE_HISTORY_LOG_TABLE, valuesBucket, "userId = ? and bundleName = ?",
678             queryCondition);
679         if (changeRow == NO_UPDATE_ROW) {
680             valuesBucket.PutString(BUNDLE_ACTIVE_DB_BUNDLE_NAME, iter->first);
681             valuesBucket.PutInt(BUNDLE_ACTIVE_DB_USER_ID, userId);
682             rdbStore->Insert(outRowId, BUNDLE_HISTORY_LOG_TABLE, valuesBucket);
683             outRowId = BUNDLE_ACTIVE_FAIL;
684         } else {
685             changeRow = BUNDLE_ACTIVE_FAIL;
686         }
687         valuesBucket.Clear();
688         queryCondition.clear();
689         iter->second->isChanged_ = false;
690         updatedcount++;
691     }
692     BUNDLE_ACTIVE_LOGI("PutBundleHistoryData, update %{public}d bundles, keep %{public}d bundles group",
693         updatedcount, unupdatedcount);
694 }
695 
GetBundleHistoryData(int32_t userId)696 shared_ptr<map<string, shared_ptr<BundleActivePackageHistory>>> BundleActiveUsageDatabase::GetBundleHistoryData(
697     int32_t userId)
698 {
699     lock_guard<mutex> lock(databaseMutex_);
700     if (bundleHistoryTableName_ == UNKNOWN_TABLE_NAME) {
701         return nullptr;
702     }
703     string queryHistoryDataSql = "select * from " + BUNDLE_HISTORY_LOG_TABLE + " where userId = ?";
704     vector<string> queryCondition;
705     queryCondition.push_back(to_string(userId));
706     unique_ptr<NativeRdb::ResultSet> bundleActiveResult = QueryStatsInfoByStep(APP_GROUP_DATABASE_INDEX,
707         queryHistoryDataSql, queryCondition);
708     if (bundleActiveResult == nullptr) {
709         return nullptr;
710     }
711     int32_t tableRowNumber;
712     bundleActiveResult->GetRowCount(tableRowNumber);
713     if (tableRowNumber == TABLE_ROW_ZERO) {
714         return nullptr;
715     }
716     string bundleName;
717     shared_ptr<map<string, shared_ptr<BundleActivePackageHistory>>> userUsageHistory =
718         make_shared<map<string, shared_ptr<BundleActivePackageHistory>>>();
719     int32_t currentBundleGroupReason = 0;
720     for (int32_t i = 0; i < tableRowNumber; i++) {
721         bundleActiveResult->GoToRow(i);
722         bundleActiveResult->GetString(BUNDLE_NAME_COLUMN_INDEX, bundleName);
723         shared_ptr<BundleActivePackageHistory> usageHistory = make_shared<BundleActivePackageHistory>();
724         bundleActiveResult->GetLong(LAST_BOOT_FROM_USED_TIME_COLUMN_INDEX, usageHistory->lastBootFromUsedTimeStamp_);
725         bundleActiveResult->GetLong(LAST_SCREEN_USED_TIME_COLUMN_INDEX, usageHistory->lastScreenUsedTimeStamp_);
726         bundleActiveResult->GetInt(CURRENT_GROUP_COLUMN_INDEX, usageHistory->currentGroup_);
727         bundleActiveResult->GetInt(REASON_IN_GROUP_COLUMN_INDEX, currentBundleGroupReason);
728         usageHistory->reasonInGroup_ = static_cast<uint32_t>(currentBundleGroupReason);
729         bundleActiveResult->GetLong(BUNDLE_ALIVE_TIMEOUT_TIME_COLUMN_INDEX,
730             usageHistory->bundleAliveTimeoutTimeStamp_);
731         bundleActiveResult->GetLong(BUNDLE_DAILY_TIMEOUT_TIME_COLUMN_INDEX,
732             usageHistory->bundleDailyTimeoutTimeStamp_);
733         userUsageHistory->insert(pair<string, shared_ptr<BundleActivePackageHistory>>(bundleName,
734             usageHistory));
735     }
736     return userUsageHistory;
737 }
738 
PutDurationData(int64_t bootBasedDuration,int64_t screenOnDuration)739 void BundleActiveUsageDatabase::PutDurationData(int64_t bootBasedDuration, int64_t screenOnDuration)
740 {
741     lock_guard<mutex> lock(databaseMutex_);
742     CheckDatabaseFile(APP_GROUP_DATABASE_INDEX);
743     if (durationTableName_ == UNKNOWN_TABLE_NAME) {
744         CreateDurationTable(APP_GROUP_DATABASE_INDEX);
745         durationTableName_ = DURATION_LOG_TABLE;
746     }
747     shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(APP_GROUP_DATABASE_INDEX);
748     if (rdbStore == nullptr) {
749         return;
750     }
751     int32_t changeRow = BUNDLE_ACTIVE_FAIL;
752     int64_t outRowId = BUNDLE_ACTIVE_FAIL;
753     NativeRdb::ValuesBucket valuesBucket;
754     valuesBucket.PutLong(BUNDLE_ACTIVE_DB_BOOT_BASED_DURATION, bootBasedDuration);
755     valuesBucket.PutLong(BUNDLE_ACTIVE_DB_SCREEN_ON_DURATION, screenOnDuration);
756     rdbStore->Update(changeRow, DURATION_LOG_TABLE, valuesBucket);
757     if (changeRow == NO_UPDATE_ROW) {
758         rdbStore->Insert(outRowId, DURATION_LOG_TABLE, valuesBucket);
759     }
760 }
761 
GetDurationData()762 pair<int64_t, int64_t> BundleActiveUsageDatabase::GetDurationData()
763 {
764     lock_guard<mutex> lock(databaseMutex_);
765     pair<int64_t, int64_t> durationData;
766     if (durationTableName_ == UNKNOWN_TABLE_NAME) {
767         return durationData;
768     }
769     string queryDurationDataSql = "select * from " + DURATION_LOG_TABLE;
770     unique_ptr<NativeRdb::ResultSet> bundleActiveResult = QueryStatsInfoByStep(APP_GROUP_DATABASE_INDEX,
771         queryDurationDataSql,
772         vector<string> {});
773     if (bundleActiveResult == nullptr) {
774         return durationData;
775     }
776     int32_t tableRowNumber;
777     bundleActiveResult->GetRowCount(tableRowNumber);
778     if (tableRowNumber == DURATION_TABLE_ROW_NUMBER) {
779         bundleActiveResult->GoToRow(tableRowNumber - DURATION_TABLE_ROW_NUMBER);
780         bundleActiveResult->GetLong(BOOT_BASED_DURATION_COLUMN_INDEX, durationData.first);
781         bundleActiveResult->GetLong(SCREEN_ON_DURATION_COLUMN_INDEX, durationData.second);
782     }
783     return durationData;
784 }
785 
FlushPackageInfo(uint32_t databaseType,const BundleActivePeriodStats & stats)786 void BundleActiveUsageDatabase::FlushPackageInfo(uint32_t databaseType, const BundleActivePeriodStats &stats)
787 {
788     shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(databaseType);
789     if (rdbStore == nullptr) {
790         BUNDLE_ACTIVE_LOGE("rdbStore is nullptr");
791         return;
792     }
793     string tableName = PACKAGE_LOG_TABLE + to_string(stats.beginTime_);
794     int32_t changeRow = BUNDLE_ACTIVE_FAIL;
795     int64_t outRowId = BUNDLE_ACTIVE_FAIL;
796     NativeRdb::ValuesBucket valuesBucket;
797     vector<string> queryCondition;
798     for (auto iter = stats.bundleStats_.begin(); iter != stats.bundleStats_.end(); iter++) {
799         if (iter->second == nullptr || (iter->second->totalInFrontTime_ == 0 &&
800             iter->second->totalContiniousTaskUsedTime_ == 0)) {
801             continue;
802         }
803         queryCondition.push_back(to_string(stats.userId_));
804         queryCondition.push_back(iter->first);
805         valuesBucket.PutLong(BUNDLE_ACTIVE_DB_BUNDLE_STARTED_COUNT, iter->second->bundleStartedCount_);
806         int64_t lastTimeUsedAdjusted = iter->second->lastTimeUsed_ == -1 ?
807             iter->second->lastTimeUsed_ : iter->second->lastTimeUsed_ - stats.beginTime_;
808         valuesBucket.PutLong(BUNDLE_ACTIVE_DB_LAST_TIME, lastTimeUsedAdjusted);
809         int64_t lastContinuousTaskUsedAdjusted = iter->second->lastContiniousTaskUsed_ == -1 ?
810             iter->second->lastContiniousTaskUsed_ : iter->second->lastContiniousTaskUsed_ - stats.beginTime_;
811         valuesBucket.PutLong(BUNDLE_ACTIVE_DB_LAST_TIME_CONTINUOUS_TASK, lastContinuousTaskUsedAdjusted);
812         valuesBucket.PutLong(BUNDLE_ACTIVE_DB_TOTAL_TIME, iter->second->totalInFrontTime_);
813         valuesBucket.PutLong(BUNDLE_ACTIVE_DB_TOTAL_TIME_CONTINUOUS_TASK, iter->second->totalContiniousTaskUsedTime_);
814         rdbStore->Update(changeRow, tableName, valuesBucket, "userId = ? and bundleName = ?", queryCondition);
815         if (changeRow == NO_UPDATE_ROW) {
816             valuesBucket.PutString(BUNDLE_ACTIVE_DB_BUNDLE_NAME, iter->second->bundleName_);
817             valuesBucket.PutInt(BUNDLE_ACTIVE_DB_USER_ID, stats.userId_);
818             rdbStore->Insert(outRowId, tableName, valuesBucket);
819             outRowId = BUNDLE_ACTIVE_FAIL;
820         } else {
821             changeRow = BUNDLE_ACTIVE_FAIL;
822         }
823         valuesBucket.Clear();
824         queryCondition.clear();
825     }
826 }
827 
GetCurrentUsageData(int32_t databaseType,int32_t userId)828 shared_ptr<BundleActivePeriodStats> BundleActiveUsageDatabase::GetCurrentUsageData(int32_t databaseType,
829     int32_t userId)
830 {
831     lock_guard<mutex> lock(databaseMutex_);
832     if (databaseType < 0 || databaseType >= static_cast<int32_t>(sortedTableArray_.size())) {
833         BUNDLE_ACTIVE_LOGE("databaseType is invalid, databaseType = %{public}d", databaseType);
834         return nullptr;
835     }
836 
837     int32_t tableNumber = static_cast<int32_t>(sortedTableArray_.at(databaseType).size());
838     if (tableNumber == TABLE_NOT_EXIST) {
839         return nullptr;
840     }
841     shared_ptr<BundleActivePeriodStats> intervalStats = make_shared<BundleActivePeriodStats>();
842     intervalStats->userId_ = userId;
843     int64_t currentPackageTime = sortedTableArray_.at(databaseType).at(tableNumber - 1);
844     intervalStats->beginTime_ = currentPackageTime;
845     string packageTableName = PACKAGE_LOG_TABLE + to_string(currentPackageTime);
846     string queryPackageSql = "select * from " + packageTableName + " where userId = ?";
847     vector<string> queryCondition;
848     queryCondition.push_back(to_string(userId));
849     unique_ptr<NativeRdb::ResultSet> bundleActiveResult = QueryStatsInfoByStep(databaseType, queryPackageSql,
850         queryCondition);
851     if (bundleActiveResult == nullptr) {
852         return nullptr;
853     }
854     int32_t tableRowNumber;
855     bundleActiveResult->GetRowCount(tableRowNumber);
856     map<string, shared_ptr<BundleActivePackageStats>> bundleStats;
857     int64_t relativeLastTimeUsed;
858     int64_t relativeLastTimeFrontServiceUsed;
859     for (int32_t i = 0; i < tableRowNumber; i++) {
860         shared_ptr<BundleActivePackageStats> usageStats = make_shared<BundleActivePackageStats>();
861         bundleActiveResult->GoToRow(i);
862         bundleActiveResult->GetInt(USER_ID_COLUMN_INDEX, intervalStats->userId_);
863         bundleActiveResult->GetString(BUNDLE_NAME_COLUMN_INDEX, usageStats->bundleName_);
864         bundleActiveResult->GetInt(BUNDLE_STARTED_COUNT_COLUMN_INDEX, usageStats->bundleStartedCount_);
865         bundleActiveResult->GetLong(LAST_TIME_COLUMN_INDEX, relativeLastTimeUsed);
866         usageStats->lastTimeUsed_ = relativeLastTimeUsed == -1 ? -1 :
867             relativeLastTimeUsed + currentPackageTime;
868         bundleActiveResult->GetLong(LAST_TIME_CONTINUOUS_TASK_COLUMN_INDEX, relativeLastTimeFrontServiceUsed);
869         usageStats->lastContiniousTaskUsed_ = relativeLastTimeFrontServiceUsed == -1 ? -1 :
870             relativeLastTimeFrontServiceUsed + currentPackageTime;
871         bundleActiveResult->GetLong(TOTAL_TIME_COLUMN_INDEX, usageStats->totalInFrontTime_);
872         bundleActiveResult->GetLong(TOTAL_TIME_CONTINUOUS_TASK_COLUMN_INDEX, usageStats->totalContiniousTaskUsedTime_);
873         bundleStats.insert(pair<string, shared_ptr<BundleActivePackageStats>>(usageStats->bundleName_,
874             usageStats));
875     }
876     intervalStats->bundleStats_ = bundleStats;
877     if (databaseType == DAILY_DATABASE_INDEX) {
878         // 加载event信息
879         eventBeginTime_ = currentPackageTime;
880     }
881     int64_t systemTime = GetSystemTimeMs();
882     intervalStats->lastTimeSaved_ = systemTime;
883     return intervalStats;
884 }
885 
FlushEventInfo(uint32_t databaseType,BundleActivePeriodStats & stats)886 void BundleActiveUsageDatabase::FlushEventInfo(uint32_t databaseType, BundleActivePeriodStats &stats)
887 {
888     shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(databaseType);
889     if (rdbStore == nullptr) {
890         BUNDLE_ACTIVE_LOGE("rdbStore is nullptr");
891         return;
892     }
893     if (eventTableName_ == UNKNOWN_TABLE_NAME) {
894         CreateEventLogTable(databaseType, stats.beginTime_);
895     }
896     int64_t eventTableTime = ParseStartTime(eventTableName_);
897     int64_t outRowId = BUNDLE_ACTIVE_FAIL;
898     NativeRdb::ValuesBucket valuesBucket;
899     for (int32_t i = 0; i < stats.events_.Size(); i++) {
900         valuesBucket.PutInt(BUNDLE_ACTIVE_DB_USER_ID, stats.userId_);
901         valuesBucket.PutString(BUNDLE_ACTIVE_DB_BUNDLE_NAME, stats.events_.events_.at(i).bundleName_);
902         valuesBucket.PutInt(BUNDLE_ACTIVE_DB_EVENT_ID, stats.events_.events_.at(i).eventId_);
903         valuesBucket.PutLong(BUNDLE_ACTIVE_DB_TIME_STAMP, stats.events_.events_.at(i).timeStamp_ - eventTableTime);
904         valuesBucket.PutString(BUNDLE_ACTIVE_DB_ABILITY_ID, stats.events_.events_.at(i).abilityId_);
905         rdbStore->Insert(outRowId, eventTableName_, valuesBucket);
906         valuesBucket.Clear();
907     }
908 }
909 
GetTableIndexSql(uint32_t databaseType,int64_t tableTime,bool createFlag,int32_t indexFlag)910 string BundleActiveUsageDatabase::GetTableIndexSql(uint32_t databaseType, int64_t tableTime, bool createFlag,
911     int32_t indexFlag)
912 {
913     string tableIndexSql;
914     if (databaseType >= 0 && databaseType < sortedTableArray_.size()) {
915         string packageTableIndex = PACKAGE_LOG_TABLE_INDEX_PREFIX + to_string(tableTime);
916         string PackageTableName = PACKAGE_LOG_TABLE + to_string(tableTime);
917         if (createFlag) {
918             tableIndexSql = "CREATE INDEX " + packageTableIndex + " ON "
919                 + PackageTableName + " (userId, lastTime, bundleName);";
920         } else {
921             tableIndexSql = "DROP INDEX " + packageTableIndex;
922         }
923     } else if (databaseType == EVENT_DATABASE_INDEX) {
924         string eventTableIndex = EVENT_LOG_TABLE_INDEX_PREFIX + to_string(tableTime);
925         string eventTableName = EVENT_LOG_TABLE + to_string(tableTime);
926         if (createFlag) {
927             tableIndexSql = "CREATE INDEX " + eventTableIndex + " ON " + eventTableName +
928                 " (timeStamp, userId, bundleName);";
929         } else {
930             tableIndexSql = "DROP INDEX " + eventTableIndex;
931         }
932     } else if (databaseType == APP_GROUP_DATABASE_INDEX) {
933         if (createFlag) {
934             if (indexFlag == BUNDLE_ACTIVE_DB_INDEX_NORMAL) {
935                 tableIndexSql = "CREATE INDEX " + BUNDLE_HISTORY_LOG_TABLE_INDEX_PREFIX
936                     + " ON " + BUNDLE_HISTORY_LOG_TABLE + " (userId, bundleName);";
937             } else if (indexFlag == BUNDLE_ACTIVE_DB_INDEX_MODULE) {
938                 tableIndexSql = "CREATE INDEX " + MODULE_RECORD_LOG_TABLE_INDEX_PREFIX
939                     + " ON " + MODULE_RECORD_LOG_TABLE + to_string(tableTime) + " (userId, bundleName, moduleName);";
940             } else if (indexFlag == BUNDLE_ACTIVE_DB_INDEX_FORM) {
941                 tableIndexSql = "CREATE INDEX " + FORM_RECORD_LOG_TABLE_INDEX_PREFIX
942                     + " ON " + FORM_RECORD_LOG_TABLE + to_string(tableTime) +
943                     " (userId, moduleName, formName, formDimension, formId);";
944             }
945         } else {
946             if (indexFlag == BUNDLE_ACTIVE_DB_INDEX_NORMAL) {
947                 tableIndexSql = "DROP INDEX " + BUNDLE_HISTORY_LOG_TABLE_INDEX_PREFIX;
948             } else if (indexFlag == BUNDLE_ACTIVE_DB_INDEX_MODULE) {
949                 tableIndexSql = "DROP INDEX " + MODULE_RECORD_LOG_TABLE_INDEX_PREFIX;
950             } else if (indexFlag == BUNDLE_ACTIVE_DB_INDEX_FORM) {
951                 tableIndexSql = "DROP INDEX " + FORM_RECORD_LOG_TABLE_INDEX_PREFIX;
952             }
953         }
954     } else {
955         BUNDLE_ACTIVE_LOGE("databaseType is invalid, databaseType = %{public}d", databaseType);
956     }
957     return tableIndexSql;
958 }
959 
SetNewIndexWhenTimeChanged(uint32_t databaseType,int64_t tableOldTime,int64_t tableNewTime,std::shared_ptr<NativeRdb::RdbStore> rdbStore)960 int32_t BundleActiveUsageDatabase::SetNewIndexWhenTimeChanged(uint32_t databaseType, int64_t tableOldTime,
961     int64_t tableNewTime, std::shared_ptr<NativeRdb::RdbStore> rdbStore)
962 {
963     if (rdbStore == nullptr) {
964         return BUNDLE_ACTIVE_FAIL;
965     }
966     if (databaseType == APP_GROUP_DATABASE_INDEX) {
967         string oldModuleTableIndex = GetTableIndexSql(databaseType, tableOldTime, false,
968             BUNDLE_ACTIVE_DB_INDEX_MODULE);
969         int32_t deleteResult = rdbStore->ExecuteSql(oldModuleTableIndex);
970         if (deleteResult != NativeRdb::E_OK) {
971             return BUNDLE_ACTIVE_FAIL;
972         }
973         string newModuleTableIndex = GetTableIndexSql(databaseType, tableNewTime, true,
974             BUNDLE_ACTIVE_DB_INDEX_MODULE);
975         int32_t createResult = rdbStore->ExecuteSql(newModuleTableIndex);
976         if (createResult != NativeRdb::E_OK) {
977             return BUNDLE_ACTIVE_FAIL;
978         }
979         string oldFormTableIndex = GetTableIndexSql(databaseType, tableOldTime, false,
980             BUNDLE_ACTIVE_DB_INDEX_FORM);
981         deleteResult = rdbStore->ExecuteSql(oldFormTableIndex);
982         if (deleteResult != NativeRdb::E_OK) {
983             return BUNDLE_ACTIVE_FAIL;
984         }
985         string newFormTableIndex = GetTableIndexSql(databaseType, tableNewTime, true,
986             BUNDLE_ACTIVE_DB_INDEX_FORM);
987         createResult = rdbStore->ExecuteSql(newFormTableIndex);
988         if (createResult != NativeRdb::E_OK) {
989             return BUNDLE_ACTIVE_FAIL;
990         }
991     } else {
992         string oldTableIndex = GetTableIndexSql(databaseType, tableOldTime, false);
993         int32_t deleteResult = rdbStore->ExecuteSql(oldTableIndex);
994         if (deleteResult != NativeRdb::E_OK) {
995             return BUNDLE_ACTIVE_FAIL;
996         }
997         string newTableIndex = GetTableIndexSql(databaseType, tableNewTime, true);
998         int32_t createResult = rdbStore->ExecuteSql(newTableIndex);
999         if (createResult != NativeRdb::E_OK) {
1000             return BUNDLE_ACTIVE_FAIL;
1001         }
1002     }
1003     return BUNDLE_ACTIVE_SUCCESS;
1004 }
1005 
RenameTableName(uint32_t databaseType,int64_t tableOldTime,int64_t tableNewTime)1006 int32_t BundleActiveUsageDatabase::RenameTableName(uint32_t databaseType, int64_t tableOldTime,
1007     int64_t tableNewTime)
1008 {
1009     shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(databaseType);
1010     if (rdbStore == nullptr) {
1011         return BUNDLE_ACTIVE_FAIL;
1012     }
1013     if (databaseType >= 0 && databaseType < sortedTableArray_.size()) {
1014         string oldPackageTableName = PACKAGE_LOG_TABLE + to_string(tableOldTime);
1015         string newPackageTableName = PACKAGE_LOG_TABLE + to_string(tableNewTime);
1016         string renamePackageTableNameSql = "alter table " + oldPackageTableName + " rename to " +
1017             newPackageTableName;
1018         int32_t renamePackageTableName = rdbStore->ExecuteSql(renamePackageTableNameSql);
1019         if (renamePackageTableName != NativeRdb::E_OK) {
1020             return BUNDLE_ACTIVE_FAIL;
1021         }
1022         int32_t setResult = SetNewIndexWhenTimeChanged(databaseType, tableOldTime, tableNewTime, rdbStore);
1023         if (setResult != BUNDLE_ACTIVE_SUCCESS) {
1024             return BUNDLE_ACTIVE_FAIL;
1025         }
1026     } else if (databaseType == EVENT_DATABASE_INDEX) {
1027         string oldEventTableName = EVENT_LOG_TABLE + to_string(tableOldTime);
1028         string newEventTableName = EVENT_LOG_TABLE + to_string(tableNewTime);
1029         string renameEventTableNameSql = "alter table " + oldEventTableName + " rename to " + newEventTableName;
1030         int32_t renameEventTableName = rdbStore->ExecuteSql(renameEventTableNameSql);
1031         if (renameEventTableName != NativeRdb::E_OK) {
1032             return BUNDLE_ACTIVE_FAIL;
1033         }
1034         int32_t setResult = SetNewIndexWhenTimeChanged(databaseType, tableOldTime, tableNewTime, rdbStore);
1035         if (setResult != BUNDLE_ACTIVE_SUCCESS) {
1036             return BUNDLE_ACTIVE_FAIL;
1037         }
1038     } else if (databaseType == APP_GROUP_DATABASE_INDEX) {
1039         string oldModuleTableName = MODULE_RECORD_LOG_TABLE + to_string(tableOldTime);
1040         string newModuleTableName = MODULE_RECORD_LOG_TABLE + to_string(tableNewTime);
1041         string renameModuleTableNameSql = "alter table " + oldModuleTableName + " rename to " + newModuleTableName;
1042         int32_t renameModuleTableName = rdbStore->ExecuteSql(renameModuleTableNameSql);
1043         if (renameModuleTableName != NativeRdb::E_OK) {
1044             return BUNDLE_ACTIVE_FAIL;
1045         }
1046         string oldFormTableName = FORM_RECORD_LOG_TABLE + to_string(tableOldTime);
1047         string newFormTableName = FORM_RECORD_LOG_TABLE + to_string(tableNewTime);
1048         string renameFormTableNameSql = "alter table " + oldFormTableName + " rename to " + newFormTableName;
1049         int32_t renameFormTableName = rdbStore->ExecuteSql(renameFormTableNameSql);
1050         if (renameFormTableName != NativeRdb::E_OK) {
1051             return BUNDLE_ACTIVE_FAIL;
1052         }
1053         int32_t setResult = SetNewIndexWhenTimeChanged(databaseType, tableOldTime, tableNewTime, rdbStore);
1054         if (setResult != BUNDLE_ACTIVE_SUCCESS) {
1055             return BUNDLE_ACTIVE_FAIL;
1056         }
1057     }
1058     return BUNDLE_ACTIVE_SUCCESS;
1059 }
1060 
GetOptimalIntervalType(int64_t beginTime,int64_t endTime)1061 int32_t BundleActiveUsageDatabase::GetOptimalIntervalType(int64_t beginTime, int64_t endTime)
1062 {
1063     lock_guard<mutex> lock(databaseMutex_);
1064     int32_t optimalIntervalType = -1;
1065     int64_t leastTimeDiff = numeric_limits<int64_t>::max();
1066     for (int32_t i = static_cast<int32_t>(sortedTableArray_.size() - 1); i >= 0; i--) {
1067         int32_t index = NearIndexOnOrBeforeCurrentTime(beginTime, sortedTableArray_.at(i));
1068         int32_t size = static_cast<int32_t>(sortedTableArray_.at(i).size());
1069         if (index >= 0 && index < size) {
1070             int64_t diff = abs(sortedTableArray_.at(i).at(index) - beginTime);
1071             if (diff < leastTimeDiff) {
1072                 leastTimeDiff = diff;
1073                 optimalIntervalType = i;
1074             }
1075         }
1076     }
1077     BUNDLE_ACTIVE_LOGI("optimalIntervalType is %{public}d", optimalIntervalType);
1078     return optimalIntervalType;
1079 }
1080 
RemoveOldData(int64_t currentTime)1081 void BundleActiveUsageDatabase::RemoveOldData(int64_t currentTime)
1082 {
1083     lock_guard<mutex> lock(databaseMutex_);
1084     calendar_->SetMilliseconds(currentTime);
1085     calendar_->IncreaseYears(-1 * MAX_FILES_EVERY_INTERVAL_TYPE[YEARLY_DATABASE_INDEX]);
1086     std::unique_ptr<std::vector<int64_t>> overdueYearsTableCreateTime = GetOverdueTableCreateTime(YEARLY_DATABASE_INDEX,
1087         calendar_->GetMilliseconds());
1088     if (overdueYearsTableCreateTime != nullptr) {
1089         for (uint32_t i = 0; i < overdueYearsTableCreateTime->size(); i++) {
1090             DeleteInvalidTable(YEARLY_DATABASE_INDEX, overdueYearsTableCreateTime->at(i));
1091         }
1092     }
1093     calendar_->SetMilliseconds(currentTime);
1094     calendar_->IncreaseMonths(-1 * MAX_FILES_EVERY_INTERVAL_TYPE[MONTHLY_DATABASE_INDEX]);
1095     std::unique_ptr<std::vector<int64_t>> overdueMonthsTableCreateTime
1096         = GetOverdueTableCreateTime(MONTHLY_DATABASE_INDEX, calendar_->GetMilliseconds());
1097     if (overdueMonthsTableCreateTime != nullptr) {
1098         for (uint32_t i = 0; i < overdueMonthsTableCreateTime->size(); i++) {
1099             DeleteInvalidTable(MONTHLY_DATABASE_INDEX, overdueMonthsTableCreateTime->at(i));
1100         }
1101     }
1102     calendar_->SetMilliseconds(currentTime);
1103     calendar_->IncreaseWeeks(-1 * MAX_FILES_EVERY_INTERVAL_TYPE[WEEKLY_DATABASE_INDEX]);
1104     std::unique_ptr<std::vector<int64_t>> overdueWeeksTableCreateTime = GetOverdueTableCreateTime(WEEKLY_DATABASE_INDEX,
1105         calendar_->GetMilliseconds());
1106     if (overdueWeeksTableCreateTime != nullptr) {
1107         for (uint32_t i = 0; i < overdueWeeksTableCreateTime->size(); i++) {
1108             DeleteInvalidTable(WEEKLY_DATABASE_INDEX, overdueWeeksTableCreateTime->at(i));
1109         }
1110     }
1111     calendar_->SetMilliseconds(currentTime);
1112     calendar_->IncreaseDays(-1 * MAX_FILES_EVERY_INTERVAL_TYPE[DAILY_DATABASE_INDEX]);
1113     std::unique_ptr<std::vector<int64_t>> overdueDaysTableCreateTime = GetOverdueTableCreateTime(DAILY_DATABASE_INDEX,
1114         calendar_->GetMilliseconds());
1115     if (overdueDaysTableCreateTime != nullptr) {
1116         for (uint32_t i = 0; i < overdueDaysTableCreateTime->size(); i++) {
1117             DeleteInvalidTable(DAILY_DATABASE_INDEX, overdueDaysTableCreateTime->at(i));
1118         }
1119     }
1120     for (uint32_t i = 0; i < sortedTableArray_.size(); i++) {
1121         HandleTableInfo(i);
1122         DeleteExcessiveTableData(i);
1123     }
1124 }
1125 
RenewTableTime(int64_t timeDiffMillis)1126 void BundleActiveUsageDatabase::RenewTableTime(int64_t timeDiffMillis)
1127 {
1128     lock_guard<mutex> lock(databaseMutex_);
1129     for (uint32_t i = 0; i < sortedTableArray_.size(); i++) {
1130         if (sortedTableArray_.at(i).empty()) {
1131             continue;
1132         }
1133         vector<int64_t> tableArray = sortedTableArray_.at(i);
1134         for (uint32_t j = 0; j < tableArray.size(); j++) {
1135             int64_t newTime = tableArray.at(j) + timeDiffMillis;
1136             BUNDLE_ACTIVE_LOGI("new table time is %{public}lld", (long long)newTime);
1137             if (newTime < 0) {
1138                 DeleteInvalidTable(i, tableArray.at(j));
1139             } else {
1140                 RenameTableName(i, tableArray.at(j), newTime);
1141             }
1142         }
1143         sortedTableArray_.at(i).clear();
1144         HandleTableInfo(i);
1145         DeleteExcessiveTableData(i);
1146     }
1147     if (eventTableName_ != UNKNOWN_TABLE_NAME) {
1148         int64_t oldTime = ParseStartTime(eventTableName_);
1149         int64_t newTime = oldTime + timeDiffMillis;
1150         if (newTime < 0) {
1151             int32_t deletedResult = DeleteInvalidTable(EVENT_DATABASE_INDEX, oldTime);
1152             if (deletedResult == BUNDLE_ACTIVE_SUCCESS) {
1153                 eventTableName_ = UNKNOWN_TABLE_NAME;
1154             }
1155         } else {
1156             int32_t renamedResult = RenameTableName(EVENT_DATABASE_INDEX, oldTime, newTime);
1157             if (renamedResult == BUNDLE_ACTIVE_SUCCESS) {
1158                 eventTableName_ = EVENT_LOG_TABLE + to_string(newTime);
1159             }
1160         }
1161     }
1162     if (formRecordsTableName_ != UNKNOWN_TABLE_NAME && moduleRecordsTableName_ != UNKNOWN_TABLE_NAME) {
1163         int64_t oldTime = ParseStartTime(moduleRecordsTableName_);
1164         int64_t newTime = oldTime + timeDiffMillis;
1165         int32_t renamedResult = RenameTableName(APP_GROUP_DATABASE_INDEX, oldTime, newTime);
1166         if (renamedResult == BUNDLE_ACTIVE_SUCCESS) {
1167             moduleRecordsTableName_ = MODULE_RECORD_LOG_TABLE + to_string(newTime);
1168             formRecordsTableName_ = FORM_RECORD_LOG_TABLE + to_string(newTime);
1169         }
1170     }
1171 }
1172 
UpdateEventData(int32_t databaseType,BundleActivePeriodStats & stats)1173 void BundleActiveUsageDatabase::UpdateEventData(int32_t databaseType, BundleActivePeriodStats &stats)
1174 {
1175     lock_guard<mutex> lock(databaseMutex_);
1176     CheckDatabaseFile(databaseType);
1177     if (databaseType != DAILY_DATABASE_INDEX) {
1178         return;
1179     }
1180     if (stats.events_.Size() != 0) {
1181         CheckDatabaseFile(EVENT_DATABASE_INDEX);
1182         FlushEventInfo(EVENT_DATABASE_INDEX, stats);
1183     }
1184 }
1185 
UpdateBundleUsageData(int32_t databaseType,BundleActivePeriodStats & stats)1186 void BundleActiveUsageDatabase::UpdateBundleUsageData(int32_t databaseType, BundleActivePeriodStats &stats)
1187 {
1188     lock_guard<mutex> lock(databaseMutex_);
1189     if (databaseType < 0 || databaseType >= EVENT_DATABASE_INDEX) {
1190         BUNDLE_ACTIVE_LOGE("databaseType is invalid : %{public}d", databaseType);
1191         return;
1192     }
1193     CheckDatabaseFile(databaseType);
1194     int32_t packageTableIndex = BundleActiveBinarySearch::GetInstance()->BinarySearch(
1195         sortedTableArray_.at(databaseType), stats.beginTime_);
1196     if (packageTableIndex < 0) {
1197         CreatePackageLogTable(databaseType, stats.beginTime_);
1198         if (databaseType == DAILY_DATABASE_INDEX) {
1199             eventBeginTime_ = stats.beginTime_;
1200             DeleteExcessiveTableData(EVENT_DATABASE_INDEX);
1201         }
1202         sortedTableArray_.at(databaseType).push_back(stats.beginTime_);
1203         sort(sortedTableArray_.at(databaseType).begin(), sortedTableArray_.at(databaseType).end());
1204         DeleteExcessiveTableData(databaseType);
1205     }
1206     FlushPackageInfo(databaseType, stats);
1207     int64_t systemTime = GetSystemTimeMs();
1208     stats.lastTimeSaved_ = systemTime;
1209 }
1210 
QueryDatabaseUsageStats(int32_t databaseType,int64_t beginTime,int64_t endTime,int32_t userId)1211 vector<BundleActivePackageStats> BundleActiveUsageDatabase::QueryDatabaseUsageStats(int32_t databaseType,
1212     int64_t beginTime, int64_t endTime, int32_t userId)
1213 {
1214     lock_guard<mutex> lock(databaseMutex_);
1215     vector<BundleActivePackageStats> databaseUsageStats;
1216     if (databaseType < 0 || databaseType >= static_cast<int32_t>(sortedTableArray_.size())) {
1217         BUNDLE_ACTIVE_LOGE("databaseType is invalid, databaseType = %{public}d", databaseType);
1218         return databaseUsageStats;
1219     }
1220     if (endTime <= beginTime) {
1221         BUNDLE_ACTIVE_LOGE("endTime(%{public}lld) <= beginTime(%{public}lld)",
1222             (long long)endTime, (long long)beginTime);
1223         return databaseUsageStats;
1224     }
1225     int32_t startIndex = NearIndexOnOrBeforeCurrentTime(beginTime, sortedTableArray_.at(databaseType));
1226     if (startIndex < 0) {
1227         startIndex = 0;
1228     }
1229     int32_t endIndex = NearIndexOnOrBeforeCurrentTime(endTime, sortedTableArray_.at(databaseType));
1230     if (endIndex < 0) {
1231         return databaseUsageStats;
1232     }
1233     if (sortedTableArray_.at(databaseType).at(endIndex) == endTime) {
1234         endIndex--;
1235         if (endIndex < 0) {
1236         return databaseUsageStats;
1237         }
1238     }
1239     for (int32_t i = startIndex; i <= endIndex; i++) {
1240         int64_t packageTableTime;
1241         string packageTableName;
1242         string queryPackageSql;
1243         vector<string> queryCondition;
1244         packageTableTime = sortedTableArray_.at(databaseType).at(i);
1245         packageTableName = PACKAGE_LOG_TABLE + to_string(packageTableTime);
1246         queryCondition.push_back(to_string(userId));
1247         if (startIndex == endIndex) {
1248             int64_t diff = beginTime - packageTableTime;
1249             if (diff >= 0) {
1250                 queryCondition.push_back(to_string(diff));
1251             } else {
1252                 queryCondition.push_back(to_string(LAST_TIME_IN_MILLIS_MIN));
1253             }
1254             queryCondition.push_back(to_string(endTime - packageTableTime));
1255             queryPackageSql = "select * from " + packageTableName +
1256                 " where userId = ? and lastTime >= ? and lastTime <= ?";
1257         } else {
1258             if (i == startIndex) {
1259                 int64_t diff = beginTime - packageTableTime;
1260                 if (diff >= 0) {
1261                     queryCondition.push_back(to_string(diff));
1262                 } else {
1263                     queryCondition.push_back(to_string(LAST_TIME_IN_MILLIS_MIN));
1264                 }
1265                 queryPackageSql = "select * from " + packageTableName + " where userId = ? and lastTime >= ?";
1266             } else if (i == endIndex) {
1267                 queryCondition.push_back(to_string(endTime - packageTableTime));
1268                 queryPackageSql = "select * from " + packageTableName + " where userId = ? and lastTime <= ?";
1269             } else {
1270                 queryPackageSql = "select * from " + packageTableName + " where userId = ?";
1271             }
1272         }
1273         unique_ptr<NativeRdb::ResultSet> bundleActiveResult = QueryStatsInfoByStep(databaseType, queryPackageSql,
1274             queryCondition);
1275         if (bundleActiveResult == nullptr) {
1276             return databaseUsageStats;
1277         }
1278         int32_t tableRowNumber;
1279         bundleActiveResult->GetRowCount(tableRowNumber);
1280         BundleActivePackageStats usageStats;
1281         int64_t relativeLastTimeUsed;
1282         int64_t relativeLastTimeFrontServiceUsed;
1283         for (int32_t j = 0; j < tableRowNumber; j++) {
1284             bundleActiveResult->GoToRow(j);
1285             bundleActiveResult->GetString(BUNDLE_NAME_COLUMN_INDEX, usageStats.bundleName_);
1286             bundleActiveResult->GetInt(BUNDLE_STARTED_COUNT_COLUMN_INDEX, usageStats.bundleStartedCount_);
1287             bundleActiveResult->GetLong(LAST_TIME_COLUMN_INDEX, usageStats.lastTimeUsed_);
1288             bundleActiveResult->GetLong(LAST_TIME_COLUMN_INDEX, relativeLastTimeUsed);
1289             usageStats.lastTimeUsed_ = relativeLastTimeUsed == -1 ? -1 :
1290                 relativeLastTimeUsed + packageTableTime;
1291             bundleActiveResult->GetLong(LAST_TIME_CONTINUOUS_TASK_COLUMN_INDEX, relativeLastTimeFrontServiceUsed);
1292             usageStats.lastContiniousTaskUsed_ = relativeLastTimeFrontServiceUsed == -1 ? -1 :
1293                 relativeLastTimeFrontServiceUsed + packageTableTime;
1294             bundleActiveResult->GetLong(TOTAL_TIME_COLUMN_INDEX, usageStats.totalInFrontTime_);
1295             bundleActiveResult->GetLong(TOTAL_TIME_CONTINUOUS_TASK_COLUMN_INDEX,
1296                 usageStats.totalContiniousTaskUsedTime_);
1297             databaseUsageStats.push_back(usageStats);
1298         }
1299         queryCondition.clear();
1300     }
1301     return databaseUsageStats;
1302 }
1303 
QueryDatabaseEvents(int64_t beginTime,int64_t endTime,int32_t userId,string bundleName)1304 vector<BundleActiveEvent> BundleActiveUsageDatabase::QueryDatabaseEvents(int64_t beginTime, int64_t endTime,
1305     int32_t userId, string bundleName)
1306 {
1307     lock_guard<mutex> lock(databaseMutex_);
1308     vector<BundleActiveEvent> databaseEvents;
1309     int64_t eventTableTime = ParseStartTime(eventTableName_);
1310     if (JudgeQueryCondition(beginTime, endTime, eventTableTime) == QUERY_CONDITION_INVALID) {
1311         return databaseEvents;
1312     }
1313     vector<string> queryCondition;
1314     int64_t diff = beginTime - eventTableTime;
1315     if (diff >= 0) {
1316         queryCondition.push_back(to_string(diff));
1317     } else {
1318         queryCondition.push_back(to_string(EVENT_TIME_IN_MILLIS_MIN));
1319     }
1320     queryCondition.push_back(to_string(endTime - eventTableTime));
1321     queryCondition.push_back(to_string(userId));
1322     string queryEventSql;
1323     if (bundleName.empty()) {
1324         queryEventSql = "select * from " + eventTableName_ + " where timeStamp >= ? and timeStamp <= ? and userId = ?";
1325     } else {
1326         queryCondition.push_back(bundleName);
1327         queryEventSql = "select * from " + eventTableName_ +
1328             " where timeStamp >= ? and timeStamp <= ? and userId = ? and bundleName = ?";
1329     }
1330     unique_ptr<NativeRdb::ResultSet> bundleActiveResult = QueryStatsInfoByStep(EVENT_DATABASE_INDEX,
1331         queryEventSql, queryCondition);
1332     if (bundleActiveResult == nullptr) {
1333         return databaseEvents;
1334     }
1335     int32_t tableRowNumber;
1336     bundleActiveResult->GetRowCount(tableRowNumber);
1337     BundleActiveEvent event;
1338     string relativeTimeStamp;
1339     for (int32_t i = 0; i < tableRowNumber; i++) {
1340         bundleActiveResult->GoToRow(i);
1341         bundleActiveResult->GetString(BUNDLE_NAME_COLUMN_INDEX, event.bundleName_);
1342         bundleActiveResult->GetInt(EVENT_ID_COLUMN_INDEX, event.eventId_);
1343         bundleActiveResult->GetString(TIME_STAMP_COLUMN_INDEX, relativeTimeStamp);
1344         event.timeStamp_ = atoll(relativeTimeStamp.c_str()) + eventTableTime;
1345         bundleActiveResult->GetString(ABILITY_ID_COLUMN_INDEX, event.abilityId_);
1346         databaseEvents.push_back(event);
1347     }
1348     return databaseEvents;
1349 }
1350 
OnPackageUninstalled(const int32_t userId,const string & bundleName)1351 void BundleActiveUsageDatabase::OnPackageUninstalled(const int32_t userId, const string& bundleName)
1352 {
1353     lock_guard<mutex> lock(databaseMutex_);
1354     for (uint32_t i = 0; i < sortedTableArray_.size(); i++) {
1355         if (sortedTableArray_.at(i).empty()) {
1356             continue;
1357         }
1358         for (uint32_t j = 0; j < sortedTableArray_.at(i).size(); j++) {
1359             string packageTableName = PACKAGE_LOG_TABLE + to_string(sortedTableArray_.at(i).at(j));
1360             DeleteUninstalledInfo(userId, bundleName, packageTableName, i);
1361         }
1362     }
1363     if (eventTableName_ != UNKNOWN_TABLE_NAME) {
1364         DeleteUninstalledInfo(userId, bundleName, eventTableName_, EVENT_DATABASE_INDEX);
1365     }
1366     if (bundleHistoryTableName_ != UNKNOWN_TABLE_NAME) {
1367         DeleteUninstalledInfo(userId, bundleName, bundleHistoryTableName_, APP_GROUP_DATABASE_INDEX);
1368     }
1369     if (moduleRecordsTableName_ != UNKNOWN_TABLE_NAME) {
1370         DeleteUninstalledInfo(userId, bundleName, moduleRecordsTableName_, APP_GROUP_DATABASE_INDEX);
1371     }
1372     if (formRecordsTableName_ != UNKNOWN_TABLE_NAME) {
1373         DeleteUninstalledInfo(userId, bundleName, formRecordsTableName_, APP_GROUP_DATABASE_INDEX);
1374     }
1375 }
1376 
DeleteUninstalledInfo(const int32_t userId,const string & bundleName,const string & tableName,uint32_t databaseType)1377 void BundleActiveUsageDatabase::DeleteUninstalledInfo(const int32_t userId, const string& bundleName,
1378     const string& tableName, uint32_t databaseType)
1379 {
1380     shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(databaseType);
1381     if (rdbStore == nullptr) {
1382         BUNDLE_ACTIVE_LOGE("rdbStore is nullptr");
1383         return;
1384     }
1385     int32_t deletedRows = BUNDLE_ACTIVE_FAIL;
1386     vector<string> queryCondition;
1387     queryCondition.push_back(to_string(userId));
1388     if (bundleName.empty()) {
1389         rdbStore->Delete(deletedRows, tableName, "userId = ?", queryCondition);
1390     } else {
1391         queryCondition.push_back(bundleName);
1392         rdbStore->Delete(deletedRows, tableName, "userId = ? and bundleName = ?", queryCondition);
1393     }
1394 }
1395 
GetSystemTimeMs()1396 int64_t BundleActiveUsageDatabase::GetSystemTimeMs()
1397 {
1398     time_t now;
1399     (void)time(&now);  // unit is seconds.
1400     if (static_cast<int64_t>(now) < 0) {
1401         BUNDLE_ACTIVE_LOGE("Get now time error");
1402         return 0;
1403     }
1404     auto tarEndTimePoint = std::chrono::system_clock::from_time_t(now);
1405     auto tarDuration = std::chrono::duration_cast<std::chrono::milliseconds>(tarEndTimePoint.time_since_epoch());
1406     int64_t tarDate = tarDuration.count();
1407     if (tarDate < 0) {
1408         BUNDLE_ACTIVE_LOGE("tarDuration is less than 0.");
1409         return -1;
1410     }
1411     return static_cast<int64_t>(tarDate);
1412 }
1413 
UpdateModuleData(const int32_t userId,std::map<std::string,std::shared_ptr<BundleActiveModuleRecord>> & moduleRecords,const int64_t timeStamp)1414 void BundleActiveUsageDatabase::UpdateModuleData(const int32_t userId,
1415     std::map<std::string, std::shared_ptr<BundleActiveModuleRecord>>& moduleRecords, const int64_t timeStamp)
1416 {
1417     lock_guard<mutex> lock(databaseMutex_);
1418     CheckDatabaseFile(APP_GROUP_DATABASE_INDEX);
1419     shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(APP_GROUP_DATABASE_INDEX);
1420     if (rdbStore == nullptr) {
1421         BUNDLE_ACTIVE_LOGE("rdbStore is nullptr");
1422         return;
1423     }
1424     if (moduleRecordsTableName_ == UNKNOWN_TABLE_NAME) {
1425         CreateModuleRecordTable(APP_GROUP_DATABASE_INDEX, timeStamp);
1426     }
1427     if (formRecordsTableName_ == UNKNOWN_TABLE_NAME) {
1428         CreateFormRecordTable(APP_GROUP_DATABASE_INDEX, timeStamp);
1429     }
1430     int64_t moduleTableTime = ParseStartTime(moduleRecordsTableName_);
1431     int32_t changeRow = BUNDLE_ACTIVE_FAIL;
1432     int64_t outRowId = BUNDLE_ACTIVE_FAIL;
1433     NativeRdb::ValuesBucket moduleValuesBucket;
1434     vector<string> queryCondition;
1435     for (const auto& oneModuleRecord : moduleRecords) {
1436         if (oneModuleRecord.second) {
1437             queryCondition.emplace_back(to_string(oneModuleRecord.second->userId_));
1438             queryCondition.emplace_back(oneModuleRecord.second->bundleName_);
1439             queryCondition.emplace_back(oneModuleRecord.second->moduleName_);
1440             moduleValuesBucket.PutInt(BUNDLE_ACTIVE_DB_MODULE_LAUNCHED_COUNT, oneModuleRecord.second->launchedCount_);
1441             int64_t adjustLastTime = oneModuleRecord.second->lastModuleUsedTime_ != -1 ?
1442                 oneModuleRecord.second->lastModuleUsedTime_ - moduleTableTime : -1;
1443             moduleValuesBucket.PutLong(BUNDLE_ACTIVE_DB_LAST_TIME, adjustLastTime);
1444             rdbStore->Update(changeRow, moduleRecordsTableName_, moduleValuesBucket,
1445                 "userId = ? and bundleName = ? and moduleName = ?", queryCondition);
1446             if (changeRow == NO_UPDATE_ROW) {
1447                 moduleValuesBucket.PutInt(BUNDLE_ACTIVE_DB_USER_ID, oneModuleRecord.second->userId_);
1448                 moduleValuesBucket.PutString(BUNDLE_ACTIVE_DB_BUNDLE_NAME, oneModuleRecord.second->bundleName_);
1449                 moduleValuesBucket.PutString(BUNDLE_ACTIVE_DB_MODULE_NAME, oneModuleRecord.second->moduleName_);
1450                 rdbStore->Insert(outRowId, moduleRecordsTableName_, moduleValuesBucket);
1451                 outRowId = BUNDLE_ACTIVE_FAIL;
1452                 changeRow = BUNDLE_ACTIVE_FAIL;
1453             } else {
1454                 changeRow = BUNDLE_ACTIVE_FAIL;
1455             }
1456             moduleValuesBucket.Clear();
1457             queryCondition.clear();
1458             for (const auto& oneFormRecord : oneModuleRecord.second->formRecords_) {
1459                 UpdateFormData(oneModuleRecord.second->userId_, oneModuleRecord.second->bundleName_,
1460                     oneModuleRecord.second->moduleName_, oneFormRecord, rdbStore);
1461             }
1462         }
1463     }
1464 }
1465 
UpdateFormData(const int32_t userId,const std::string bundleName,const string moduleName,const BundleActiveFormRecord & formRecord,std::shared_ptr<NativeRdb::RdbStore> rdbStore)1466 void BundleActiveUsageDatabase::UpdateFormData(const int32_t userId, const std::string bundleName,
1467     const string moduleName, const BundleActiveFormRecord& formRecord,
1468     std::shared_ptr<NativeRdb::RdbStore> rdbStore)
1469 {
1470     if (rdbStore == nullptr) {
1471         return;
1472     }
1473     int64_t formRecordsTableTime = ParseStartTime(formRecordsTableName_);
1474     NativeRdb::ValuesBucket formValueBucket;
1475     vector<string> queryCondition;
1476     int32_t changeRow = BUNDLE_ACTIVE_FAIL;
1477     int64_t outRowId = BUNDLE_ACTIVE_FAIL;
1478     queryCondition.emplace_back(to_string(userId));
1479     queryCondition.emplace_back(bundleName);
1480     queryCondition.emplace_back(moduleName);
1481     queryCondition.emplace_back(formRecord.formName_);
1482     queryCondition.emplace_back(to_string(formRecord.formDimension_));
1483     queryCondition.emplace_back(to_string(formRecord.formId_));
1484     formValueBucket.PutInt(BUNDLE_ACTIVE_DB_FORM_TOUCH_COUNT, formRecord.count_);
1485     int64_t adjustLastTime = formRecord.formLastUsedTime_ != -1 ? formRecord.formLastUsedTime_ -
1486         formRecordsTableTime : -1;
1487     formValueBucket.PutLong(BUNDLE_ACTIVE_DB_LAST_TIME, adjustLastTime);
1488     rdbStore->Update(changeRow, formRecordsTableName_, formValueBucket,
1489         "userId = ? and bundleName = ? and moduleName = ? and formName = ? and formDimension = ? "
1490         "and formId = ?",
1491         queryCondition);
1492     if (changeRow == NO_UPDATE_ROW) {
1493         formValueBucket.PutInt(BUNDLE_ACTIVE_DB_USER_ID, userId);
1494         formValueBucket.PutString(BUNDLE_ACTIVE_DB_BUNDLE_NAME, bundleName);
1495         formValueBucket.PutString(BUNDLE_ACTIVE_DB_MODULE_NAME, moduleName);
1496         formValueBucket.PutString(BUNDLE_ACTIVE_DB_FORM_NAME, formRecord.formName_);
1497         formValueBucket.PutInt(BUNDLE_ACTIVE_DB_FORM_DIMENSION, formRecord.formDimension_);
1498         formValueBucket.PutInt(BUNDLE_ACTIVE_DB_FORM_ID, formRecord.formId_);
1499         rdbStore->Insert(outRowId, formRecordsTableName_, formValueBucket);
1500     }
1501 }
1502 
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)1503 void BundleActiveUsageDatabase::RemoveFormData(const int32_t userId, const std::string bundleName,
1504     const std::string moduleName, const std::string formName, const int32_t formDimension,
1505     const int64_t formId)
1506 {
1507     lock_guard<mutex> lock(databaseMutex_);
1508     shared_ptr<NativeRdb::RdbStore> rdbStore = GetBundleActiveRdbStore(APP_GROUP_DATABASE_INDEX);
1509     if (rdbStore == nullptr) {
1510         BUNDLE_ACTIVE_LOGE("rdbStore is nullptr");
1511         return;
1512     }
1513     int32_t deletedRows = BUNDLE_ACTIVE_FAIL;
1514     if (formRecordsTableName_ != UNKNOWN_TABLE_NAME) {
1515         vector<string> queryCondition;
1516         queryCondition.emplace_back(to_string(userId));
1517         queryCondition.emplace_back(bundleName);
1518         queryCondition.emplace_back(moduleName);
1519         queryCondition.emplace_back(formName);
1520         queryCondition.emplace_back(to_string(formDimension));
1521         queryCondition.emplace_back(to_string(formId));
1522         int32_t ret = rdbStore->Delete(deletedRows, formRecordsTableName_,
1523             "userId = ? and bundleName = ? and moduleName = ? and formName = ? and formDimension = ? "
1524             "and formId = ?",
1525             queryCondition);
1526         if (ret != NativeRdb::E_OK) {
1527             BUNDLE_ACTIVE_LOGE("delete event data failed, rdb error number: %{public}d", ret);
1528         }
1529     }
1530 }
1531 
LoadModuleData(const int32_t userId,std::map<std::string,std::shared_ptr<BundleActiveModuleRecord>> & moduleRecords)1532 void BundleActiveUsageDatabase::LoadModuleData(const int32_t userId, std::map<std::string,
1533     std::shared_ptr<BundleActiveModuleRecord>>& moduleRecords)
1534 {
1535     lock_guard<mutex> lock(databaseMutex_);
1536     string queryModuleSql = "select * from " + moduleRecordsTableName_ + " where userId = ?";
1537     vector<string> queryCondition;
1538     queryCondition.emplace_back(to_string(userId));
1539     unique_ptr<NativeRdb::ResultSet> moduleRecordResult = QueryStatsInfoByStep(APP_GROUP_DATABASE_INDEX, queryModuleSql,
1540         queryCondition);
1541     if (!moduleRecordResult) {
1542         return;
1543     }
1544     int64_t baseTime = ParseStartTime(moduleRecordsTableName_);
1545     int32_t numOfModuleRecord = 0;
1546     moduleRecordResult->GetRowCount(numOfModuleRecord);
1547     for (int32_t i = 0; i < numOfModuleRecord; i++) {
1548         shared_ptr<BundleActiveModuleRecord> oneModuleRecord = make_shared<BundleActiveModuleRecord>();
1549         moduleRecordResult->GoToRow(i);
1550         moduleRecordResult->GetInt(USER_ID_COLUMN_INDEX, oneModuleRecord->userId_);
1551         moduleRecordResult->GetString(BUNDLE_NAME_COLUMN_INDEX, oneModuleRecord->bundleName_);
1552         moduleRecordResult->GetString(MODULE_NAME_COLUMN_INDEX, oneModuleRecord->moduleName_);
1553         moduleRecordResult->GetInt(MODULE_USED_COUNT_COLUMN_INDEX, oneModuleRecord->launchedCount_);
1554         int64_t relativeLastTime = 0;
1555         moduleRecordResult->GetLong(MODULE_LAST_TIME_COLUMN_INDEX, relativeLastTime);
1556         oneModuleRecord->lastModuleUsedTime_ =  relativeLastTime != -1 ? relativeLastTime + baseTime : -1;
1557         string combinedInfo = oneModuleRecord->bundleName_ + " " + oneModuleRecord->moduleName_;
1558         moduleRecords[combinedInfo] = oneModuleRecord;
1559     }
1560 }
1561 
LoadFormData(const int32_t userId,std::map<std::string,std::shared_ptr<BundleActiveModuleRecord>> & moduleRecords)1562 void BundleActiveUsageDatabase::LoadFormData(const int32_t userId, std::map<std::string,
1563     std::shared_ptr<BundleActiveModuleRecord>>& moduleRecords)
1564 {
1565     lock_guard<mutex> lock(databaseMutex_);
1566     string queryFormSql = "select * from " + formRecordsTableName_ + " where userId = ?";
1567     vector<string> queryCondition;
1568     queryCondition.emplace_back(to_string(userId));
1569     unique_ptr<NativeRdb::ResultSet> formRecordResult = QueryStatsInfoByStep(APP_GROUP_DATABASE_INDEX, queryFormSql,
1570         queryCondition);
1571     if (!formRecordResult) {
1572         return;
1573     }
1574     int32_t numOfFormRecord = 0;
1575     int64_t baseTime = ParseStartTime(formRecordsTableName_);
1576     formRecordResult->GetRowCount(numOfFormRecord);
1577     for (int32_t i = 0; i < numOfFormRecord; i++) {
1578         BundleActiveFormRecord oneFormRecord;
1579         string moduleName = "";
1580         string bundleName = "";
1581         formRecordResult->GoToRow(i);
1582         formRecordResult->GetInt(USER_ID_COLUMN_INDEX, oneFormRecord.userId_);
1583         formRecordResult->GetString(BUNDLE_NAME_COLUMN_INDEX, bundleName);
1584         formRecordResult->GetString(MODULE_NAME_COLUMN_INDEX, moduleName);
1585         formRecordResult->GetString(FORM_NAME_COLUMN_INDEX, oneFormRecord.formName_);
1586         formRecordResult->GetInt(FORM_DIMENSION_COLUMN_INDEX, oneFormRecord.formDimension_);
1587         formRecordResult->GetLong(FORM_ID_COLUMN_INDEX, oneFormRecord.formId_);
1588         formRecordResult->GetInt(FORM_COUNT_COLUMN_INDEX, oneFormRecord.count_);
1589         int64_t relativeLastTime = 0;
1590         formRecordResult->GetLong(FORM_LAST_TIME_COLUMN_INDEX, relativeLastTime);
1591         oneFormRecord.formLastUsedTime_ = relativeLastTime != -1 ? relativeLastTime + baseTime : -1;
1592         auto it = moduleRecords.find(bundleName + " " + moduleName);
1593         if (it != moduleRecords.end() && it->second) {
1594             it->second->formRecords_.emplace_back(oneFormRecord);
1595         }
1596     }
1597 }
1598 
QueryDeviceEventStats(int32_t eventId,int64_t beginTime,int64_t endTime,std::map<std::string,BundleActiveEventStats> & eventStats,int32_t userId)1599 void BundleActiveUsageDatabase::QueryDeviceEventStats(int32_t eventId, int64_t beginTime,
1600     int64_t endTime, std::map<std::string, BundleActiveEventStats>& eventStats, int32_t userId)
1601 {
1602     lock_guard<mutex> lock(databaseMutex_);
1603     int64_t eventTableTime = ParseStartTime(eventTableName_);
1604     if (JudgeQueryCondition(beginTime, endTime, eventTableTime) == QUERY_CONDITION_INVALID) {
1605         return;
1606     }
1607     vector<string> queryCondition;
1608     int64_t diff = beginTime - eventTableTime;
1609     if (diff >= 0) {
1610         queryCondition.push_back(to_string(diff));
1611     } else {
1612         queryCondition.push_back(to_string(EVENT_TIME_IN_MILLIS_MIN));
1613     }
1614     queryCondition.push_back(to_string(endTime - eventTableTime));
1615     queryCondition.push_back(to_string(userId));
1616     queryCondition.push_back(to_string(eventId));
1617     string queryEventSql = "select * from " + eventTableName_ +
1618             " where timeStamp >= ? and timeStamp <= ? and userId = ? and eventId = ?";
1619     unique_ptr<NativeRdb::ResultSet> bundleActiveResult = QueryStatsInfoByStep(EVENT_DATABASE_INDEX,
1620         queryEventSql, queryCondition);
1621     if (bundleActiveResult == nullptr) {
1622         return;
1623     }
1624     int32_t tableRowNumber;
1625     bundleActiveResult->GetRowCount(tableRowNumber);
1626     if (tableRowNumber == 0) {
1627         return;
1628     }
1629     BundleActiveEventStats event;
1630     event.name_= GetSystemEventName(eventId);
1631     event.count_ = tableRowNumber;
1632     event.eventId_ = eventId;
1633     eventStats.insert(std::pair<std::string, BundleActiveEventStats>(event.name_, event));
1634 }
1635 
GetSystemEventName(const int32_t userId)1636 std::string BundleActiveUsageDatabase::GetSystemEventName(const int32_t userId)
1637 {
1638     std::string systemEventName = "";
1639     switch (userId) {
1640         case BundleActiveEvent::SYSTEM_LOCK:
1641             systemEventName = OPERATION_SYSTEM_LOCK;
1642             break;
1643         case BundleActiveEvent::SYSTEM_UNLOCK:
1644             systemEventName = OPERATION_SYSTEM_UNLOCK;
1645             break;
1646         case BundleActiveEvent::SYSTEM_SLEEP:
1647             systemEventName = OPERATION_SYSTEM_SLEEP;
1648             break;
1649         case BundleActiveEvent::SYSTEM_WAKEUP:
1650             systemEventName = OPERATION_SYSTEM_WAKEUP;
1651             break;
1652         default:
1653             break;
1654     }
1655     return systemEventName;
1656 }
1657 
QueryNotificationEventStats(int32_t eventId,int64_t beginTime,int64_t endTime,std::map<std::string,BundleActiveEventStats> & notificationEventStats,int32_t userId)1658 void BundleActiveUsageDatabase::QueryNotificationEventStats(int32_t eventId, int64_t beginTime,
1659     int64_t endTime, std::map<std::string, BundleActiveEventStats>& notificationEventStats, int32_t userId)
1660 {
1661     lock_guard<mutex> lock(databaseMutex_);
1662     int64_t eventTableTime = ParseStartTime(eventTableName_);
1663     if (JudgeQueryCondition(beginTime, endTime, eventTableTime) == QUERY_CONDITION_INVALID) {
1664         return;
1665     }
1666     vector<string> queryCondition;
1667     int64_t diff = beginTime - eventTableTime;
1668     if (diff >= 0) {
1669         queryCondition.push_back(to_string(diff));
1670     } else {
1671         queryCondition.push_back(to_string(EVENT_TIME_IN_MILLIS_MIN));
1672     }
1673     queryCondition.push_back(to_string(endTime - eventTableTime));
1674     queryCondition.push_back(to_string(userId));
1675     queryCondition.push_back(to_string(eventId));
1676     string queryEventSql = "select * from " + eventTableName_ +
1677             " where timeStamp >= ? and timeStamp <= ? and userId = ? and eventId = ?";
1678     unique_ptr<NativeRdb::ResultSet> bundleActiveResult = QueryStatsInfoByStep(EVENT_DATABASE_INDEX,
1679         queryEventSql, queryCondition);
1680     if (bundleActiveResult == nullptr) {
1681         return;
1682     }
1683     int32_t tableRowNumber;
1684     bundleActiveResult->GetRowCount(tableRowNumber);
1685     if (tableRowNumber == 0) {
1686         return;
1687     }
1688     BundleActiveEventStats event;
1689     std::map<std::string, BundleActiveEventStats>::iterator iter;
1690     for (int32_t i = 0; i < tableRowNumber; i++) {
1691         bundleActiveResult->GoToRow(i);
1692         bundleActiveResult->GetString(BUNDLE_NAME_COLUMN_INDEX, event.name_);
1693         bundleActiveResult->GetInt(EVENT_ID_COLUMN_INDEX, event.eventId_);
1694         iter = notificationEventStats.find(event.name_);
1695         if (iter != notificationEventStats.end()) {
1696             iter->second.count_++;
1697         } else {
1698             event.count_ = 1;
1699             notificationEventStats.insert(std::pair<std::string, BundleActiveEventStats>(event.name_, event));
1700         }
1701     }
1702 }
1703 
JudgeQueryCondition(const int64_t beginTime,const int64_t endTime,const int64_t eventTableTime)1704 int32_t BundleActiveUsageDatabase::JudgeQueryCondition(const int64_t beginTime,
1705     const int64_t endTime, const int64_t eventTableTime)
1706 {
1707     if (eventTableName_ == UNKNOWN_TABLE_NAME) {
1708         BUNDLE_ACTIVE_LOGE("eventTable does not exist");
1709         return QUERY_CONDITION_INVALID;
1710     }
1711     if (endTime <= beginTime) {
1712         BUNDLE_ACTIVE_LOGE("endTime(%{public}lld) <= beginTime(%{public}lld)",
1713             (long long)endTime, (long long)beginTime);
1714         return QUERY_CONDITION_INVALID;
1715     }
1716     if (endTime < eventTableTime) {
1717         BUNDLE_ACTIVE_LOGE("endTime(%{public}lld) <= eventTableTime(%{public}lld)",
1718             (long long)endTime, (long long)eventTableTime);
1719         return QUERY_CONDITION_INVALID;
1720     }
1721     return QUERY_CONDITION_VALID;
1722 }
1723 }  // namespace DeviceUsageStats
1724 }  // namespace OHOS
1725 
1726