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