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