1 /*
2 * Copyright (c) 2024 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 "fold_app_usage_db_helper.h"
17
18 #include "event_db_helper.h"
19 #include "file_util.h"
20 #include "hiview_logger.h"
21 #include "rdb_helper.h"
22 #include "rdb_predicates.h"
23 #include "sql_util.h"
24 #include "usage_event_common.h"
25
26 namespace OHOS {
27 namespace HiviewDFX {
28 DEFINE_LOG_TAG("FoldAppUsage");
29 namespace {
30 const std::string LOG_DB_PATH = "sys_event_logger/";
31 const std::string LOG_DB_NAME = "log.db";
32 const std::string LOG_DB_TABLE_NAME = "app_events";
33 constexpr int DB_VERSION = 1;
34
35 const std::string SQL_TYPE_INTEGER_NOT_NULL = "INTEGER NOT NULL";
36 const std::string SQL_TYPE_INTEGER = "INTEGER";
37 const std::string SQL_TYPE_REAL = "REAL";
38 const std::string SQL_TYPE_TEXT_NOT_NULL = "TEXT NOT NULL";
39 const std::string SQL_TYPE_TEXT = "TEXT";
40
41 constexpr int DB_SUCC = 0;
42 constexpr int DB_FAILED = -1;
43
UpdateScreenStatInfo(FoldAppUsageInfo & info,uint32_t time,int screenStatus)44 void UpdateScreenStatInfo(FoldAppUsageInfo &info, uint32_t time, int screenStatus)
45 {
46 switch (screenStatus) {
47 case ScreenFoldStatus::EXPAND_PORTRAIT_STATUS:
48 info.expdHor += static_cast<int32_t>(time);
49 break;
50 case ScreenFoldStatus::EXPAND_LANDSCAPE_STATUS:
51 info.expdVer += static_cast<int32_t>(time);
52 break;
53 case ScreenFoldStatus::FOLD_PORTRAIT_STATUS:
54 info.foldHor += static_cast<int32_t>(time);
55 break;
56 case ScreenFoldStatus::FOLD_LANDSCAPE_STATUS:
57 info.foldVer += static_cast<int32_t>(time);
58 break;
59 default:
60 return;
61 }
62 }
63
GetStringFromResultSet(std::shared_ptr<NativeRdb::AbsSharedResultSet> resultSet,const std::string & colName,std::string & value)64 bool GetStringFromResultSet(std::shared_ptr<NativeRdb::AbsSharedResultSet> resultSet,
65 const std::string& colName, std::string &value)
66 {
67 int colIndex = 0;
68 if (resultSet->GetColumnIndex(colName, colIndex) != NativeRdb::E_OK) {
69 HIVIEW_LOGE("failed to get column index, column = %{public}s", colName.c_str());
70 return false;
71 }
72 if (resultSet->GetString(colIndex, value) != NativeRdb::E_OK) {
73 HIVIEW_LOGE("failed to get string value, column = %{public}s", colName.c_str());
74 return false;
75 }
76 return true;
77 }
78
GetIntFromResultSet(std::shared_ptr<NativeRdb::AbsSharedResultSet> resultSet,const std::string & colName,int & value)79 bool GetIntFromResultSet(std::shared_ptr<NativeRdb::AbsSharedResultSet> resultSet,
80 const std::string& colName, int &value)
81 {
82 int colIndex = 0;
83 if (resultSet->GetColumnIndex(colName, colIndex) != NativeRdb::E_OK) {
84 HIVIEW_LOGE("failed to get column index, column = %{public}s", colName.c_str());
85 return false;
86 }
87 if (resultSet->GetInt(colIndex, value) != NativeRdb::E_OK) {
88 HIVIEW_LOGE("failed to get int value, column = %{public}s", colName.c_str());
89 return false;
90 }
91 return true;
92 }
93
GetLongFromResultSet(std::shared_ptr<NativeRdb::AbsSharedResultSet> resultSet,const std::string & colName,int64_t & value)94 bool GetLongFromResultSet(std::shared_ptr<NativeRdb::AbsSharedResultSet> resultSet,
95 const std::string& colName, int64_t &value)
96 {
97 int colIndex = 0;
98 if (resultSet->GetColumnIndex(colName, colIndex) != NativeRdb::E_OK) {
99 HIVIEW_LOGE("failed to get column index, column = %{public}s", colName.c_str());
100 return false;
101 }
102 if (resultSet->GetLong(colIndex, value) != NativeRdb::E_OK) {
103 HIVIEW_LOGE("failed to get long value, column = %{public}s", colName.c_str());
104 return false;
105 }
106 return true;
107 }
108 }
109
110 class FoldDbStoreCallback : public NativeRdb::RdbOpenCallback {
111 public:
112 int OnCreate(NativeRdb::RdbStore& rdbStore) override;
113 int OnUpgrade(NativeRdb::RdbStore& rdbStore, int oldVersion, int newVersion) override;
114 };
115
OnCreate(NativeRdb::RdbStore & rdbStore)116 int FoldDbStoreCallback::OnCreate(NativeRdb::RdbStore& rdbStore)
117 {
118 HIVIEW_LOGD("create dbStore");
119 return NativeRdb::E_OK;
120 }
121
OnUpgrade(NativeRdb::RdbStore & rdbStore,int oldVersion,int newVersion)122 int FoldDbStoreCallback::OnUpgrade(NativeRdb::RdbStore& rdbStore, int oldVersion, int newVersion)
123 {
124 HIVIEW_LOGD("oldVersion = %{public}d, newVersion = %{public}d", oldVersion, newVersion);
125 return NativeRdb::E_OK;
126 }
127
FoldAppUsageDbHelper(const std::string & workPath)128 FoldAppUsageDbHelper::FoldAppUsageDbHelper(const std::string& workPath)
129 {
130 dbPath_ = workPath;
131 if (workPath.back() != '/') {
132 dbPath_ = workPath + "/";
133 }
134 dbPath_ += LOG_DB_PATH;
135 CreateDbStore(dbPath_, LOG_DB_NAME);
136 if (int ret = CreateAppEventsTable(LOG_DB_TABLE_NAME); ret != DB_SUCC) {
137 HIVIEW_LOGI("failed to create table");
138 }
139 }
140
~FoldAppUsageDbHelper()141 FoldAppUsageDbHelper::~FoldAppUsageDbHelper()
142 {}
143
CreateDbStore(const std::string & dbPath,const std::string & dbName)144 void FoldAppUsageDbHelper::CreateDbStore(const std::string& dbPath, const std::string& dbName)
145 {
146 std::string dbFile = dbPath + dbName;
147 if (!FileUtil::FileExists(dbPath) && FileUtil::ForceCreateDirectory(dbPath, FileUtil::FILE_PERM_770)) {
148 HIVIEW_LOGI("failed to create db path, use default path");
149 return;
150 }
151 NativeRdb::RdbStoreConfig config(dbFile);
152 config.SetSecurityLevel(NativeRdb::SecurityLevel::S1);
153 FoldDbStoreCallback callback;
154 int ret = NativeRdb::E_OK;
155 rdbStore_ = NativeRdb::RdbHelper::GetRdbStore(config, DB_VERSION, callback, ret);
156 if (ret != NativeRdb::E_OK || rdbStore_ == nullptr) {
157 HIVIEW_LOGI("failed to create db store, dbFile = %{public}s, ret = %{public}d", dbFile.c_str(), ret);
158 }
159 }
160
CreateAppEventsTable(const std::string & table)161 int FoldAppUsageDbHelper::CreateAppEventsTable(const std::string& table)
162 {
163 std::lock_guard<std::mutex> lockGuard(dbMutex_);
164 if (rdbStore_ == nullptr) {
165 HIVIEW_LOGI("dbstore is nullptr");
166 return DB_FAILED;
167 }
168 std::vector<std::pair<std::string, std::string>> fields = {
169 {FoldEventTable::FIELD_UID, SQL_TYPE_INTEGER_NOT_NULL},
170 {FoldEventTable::FIELD_EVENT_ID, SQL_TYPE_INTEGER_NOT_NULL},
171 {FoldEventTable::FIELD_TS, SQL_TYPE_INTEGER_NOT_NULL},
172 {FoldEventTable::FIELD_FOLD_STATUS, SQL_TYPE_INTEGER},
173 {FoldEventTable::FIELD_PRE_FOLD_STATUS, SQL_TYPE_INTEGER},
174 {FoldEventTable::FIELD_VERSION_NAME, SQL_TYPE_TEXT},
175 {FoldEventTable::FIELD_HAPPEN_TIME, SQL_TYPE_INTEGER},
176 {FoldEventTable::FIELD_FOLD_PORTRAIT_DURATION, SQL_TYPE_INTEGER},
177 {FoldEventTable::FIELD_FOLD_LANDSCAPE_DURATION, SQL_TYPE_INTEGER},
178 {FoldEventTable::FIELD_EXPAND_PORTRAIT_DURATION, SQL_TYPE_INTEGER},
179 {FoldEventTable::FIELD_EXPAND_LANDSCAPE_DURATION, SQL_TYPE_INTEGER},
180 {FoldEventTable::FIELD_BUNDLE_NAME, SQL_TYPE_TEXT_NOT_NULL}
181 };
182 std::string sql = SqlUtil::GenerateCreateSql(table, fields);
183 if (rdbStore_->ExecuteSql(sql) != NativeRdb::E_OK) {
184 return DB_FAILED;
185 }
186 return DB_SUCC;
187 }
188
AddAppEvent(const AppEventRecord & appEventRecord)189 int FoldAppUsageDbHelper::AddAppEvent(const AppEventRecord& appEventRecord)
190 {
191 std::lock_guard<std::mutex> lockGuard(dbMutex_);
192 if (rdbStore_ == nullptr) {
193 HIVIEW_LOGE("dbStore is nullptr");
194 return DB_FAILED;
195 }
196 NativeRdb::ValuesBucket valuesBucket;
197 valuesBucket.PutInt(FoldEventTable::FIELD_UID, -1);
198 valuesBucket.PutInt(FoldEventTable::FIELD_EVENT_ID, appEventRecord.rawid);
199 valuesBucket.PutLong(FoldEventTable::FIELD_TS, appEventRecord.ts);
200 valuesBucket.PutInt(FoldEventTable::FIELD_FOLD_STATUS, appEventRecord.foldStatus);
201 valuesBucket.PutInt(FoldEventTable::FIELD_PRE_FOLD_STATUS, appEventRecord.preFoldStatus);
202 valuesBucket.PutString(FoldEventTable::FIELD_VERSION_NAME, appEventRecord.versionName);
203 valuesBucket.PutLong(FoldEventTable::FIELD_HAPPEN_TIME, appEventRecord.happenTime);
204 valuesBucket.PutLong(FoldEventTable::FIELD_FOLD_PORTRAIT_DURATION, appEventRecord.foldPortraitTime);
205 valuesBucket.PutLong(FoldEventTable::FIELD_FOLD_LANDSCAPE_DURATION, appEventRecord.foldLandscapeTime);
206 valuesBucket.PutLong(FoldEventTable::FIELD_EXPAND_PORTRAIT_DURATION, appEventRecord.expandPortraitTime);
207 valuesBucket.PutLong(FoldEventTable::FIELD_EXPAND_LANDSCAPE_DURATION, appEventRecord.expandLandscapeTime);
208 valuesBucket.PutString(FoldEventTable::FIELD_BUNDLE_NAME, appEventRecord.bundleName);
209 int64_t seq = 0;
210 if (int ret = rdbStore_->Insert(seq, LOG_DB_TABLE_NAME, valuesBucket); ret != NativeRdb::E_OK) {
211 HIVIEW_LOGI("failed to add app event");
212 return DB_FAILED;
213 }
214 return DB_SUCC;
215 }
216
QueryRawEventIndex(const std::string & bundleName,int rawId)217 int FoldAppUsageDbHelper::QueryRawEventIndex(const std::string& bundleName, int rawId)
218 {
219 std::lock_guard<std::mutex> lockGuard(dbMutex_);
220 if (rdbStore_ == nullptr) {
221 HIVIEW_LOGE("dbStore is nullptr");
222 return 0;
223 }
224 NativeRdb::RdbPredicates predicates(LOG_DB_TABLE_NAME);
225 predicates.EqualTo(FoldEventTable::FIELD_BUNDLE_NAME, bundleName);
226 predicates.EqualTo(FoldEventTable::FIELD_EVENT_ID, rawId);
227 predicates.OrderByDesc(FoldEventTable::FIELD_ID);
228 predicates.Limit(1); // query the nearest one event
229 auto resultSet = rdbStore_->Query(predicates, {FoldEventTable::FIELD_ID});
230 int index = 0;
231 if (resultSet == nullptr) {
232 HIVIEW_LOGI("failed to query raw event index");
233 return index;
234 }
235 if (resultSet->GoToNextRow() == NativeRdb::E_OK) {
236 GetIntFromResultSet(resultSet, FoldEventTable::FIELD_ID, index);
237 }
238 resultSet->Close();
239 return index;
240 }
241
QueryAppEventRecords(int startIndex,int64_t dayStartTime,const std::string & bundleName,std::vector<AppEventRecord> & records)242 void FoldAppUsageDbHelper::QueryAppEventRecords(int startIndex, int64_t dayStartTime, const std::string& bundleName,
243 std::vector<AppEventRecord>& records)
244 {
245 std::lock_guard<std::mutex> lockGuard(dbMutex_);
246 if (rdbStore_ == nullptr) {
247 HIVIEW_LOGE("dbStore is nullptr");
248 return;
249 }
250 NativeRdb::RdbPredicates predicates(LOG_DB_TABLE_NAME);
251 predicates.EqualTo(FoldEventTable::FIELD_BUNDLE_NAME, bundleName);
252 predicates.GreaterThanOrEqualTo(FoldEventTable::FIELD_ID, startIndex);
253 predicates.GreaterThanOrEqualTo(FoldEventTable::FIELD_HAPPEN_TIME, dayStartTime);
254 predicates.OrderByAsc(FoldEventTable::FIELD_ID);
255
256 std::vector<std::string> columns;
257 columns.emplace_back(FoldEventTable::FIELD_EVENT_ID);
258 columns.emplace_back(FoldEventTable::FIELD_TS);
259 columns.emplace_back(FoldEventTable::FIELD_FOLD_STATUS);
260 columns.emplace_back(FoldEventTable::FIELD_PRE_FOLD_STATUS);
261 columns.emplace_back(FoldEventTable::FIELD_VERSION_NAME);
262 columns.emplace_back(FoldEventTable::FIELD_HAPPEN_TIME);
263 columns.emplace_back(FoldEventTable::FIELD_FOLD_PORTRAIT_DURATION);
264 columns.emplace_back(FoldEventTable::FIELD_FOLD_LANDSCAPE_DURATION);
265 columns.emplace_back(FoldEventTable::FIELD_EXPAND_PORTRAIT_DURATION);
266 columns.emplace_back(FoldEventTable::FIELD_EXPAND_LANDSCAPE_DURATION);
267 columns.emplace_back(FoldEventTable::FIELD_BUNDLE_NAME);
268 auto resultSet = rdbStore_->Query(predicates, columns);
269 if (resultSet == nullptr) {
270 HIVIEW_LOGI("failed to query event event");
271 return;
272 }
273 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
274 NativeRdb::RowEntity entity;
275 if (resultSet->GetRow(entity) != NativeRdb::E_OK) {
276 HIVIEW_LOGI("failed to read row entity from result set");
277 resultSet->Close();
278 return;
279 }
280 AppEventRecord record;
281 ParseEntity(entity, record);
282 if (record.rawid == FoldEventId::EVENT_COUNT_DURATION) {
283 records.clear();
284 continue;
285 }
286 records.emplace_back(record);
287 }
288 resultSet->Close();
289 }
290
ParseEntity(NativeRdb::RowEntity & entity,AppEventRecord & record)291 void FoldAppUsageDbHelper::ParseEntity(NativeRdb::RowEntity& entity, AppEventRecord& record)
292 {
293 entity.Get(FoldEventTable::FIELD_EVENT_ID).GetInt(record.rawid);
294 entity.Get(FoldEventTable::FIELD_TS).GetLong(record.ts);
295 entity.Get(FoldEventTable::FIELD_FOLD_STATUS).GetInt(record.foldStatus);
296 entity.Get(FoldEventTable::FIELD_PRE_FOLD_STATUS).GetInt(record.preFoldStatus);
297 entity.Get(FoldEventTable::FIELD_VERSION_NAME).GetString(record.versionName);
298 entity.Get(FoldEventTable::FIELD_HAPPEN_TIME).GetLong(record.happenTime);
299 entity.Get(FoldEventTable::FIELD_FOLD_PORTRAIT_DURATION).GetLong(record.foldPortraitTime);
300 entity.Get(FoldEventTable::FIELD_FOLD_LANDSCAPE_DURATION).GetLong(record.foldLandscapeTime);
301 entity.Get(FoldEventTable::FIELD_EXPAND_PORTRAIT_DURATION).GetLong(record.expandPortraitTime);
302 entity.Get(FoldEventTable::FIELD_EXPAND_LANDSCAPE_DURATION).GetLong(record.expandLandscapeTime);
303 entity.Get(FoldEventTable::FIELD_BUNDLE_NAME).GetString(record.bundleName);
304 }
305
QueryFinalScreenStatus(uint64_t endTime)306 int FoldAppUsageDbHelper::QueryFinalScreenStatus(uint64_t endTime)
307 {
308 std::lock_guard<std::mutex> lockGuard(dbMutex_);
309 if (rdbStore_ == nullptr) {
310 HIVIEW_LOGE("db is nullptr");
311 return 0;
312 }
313 NativeRdb::AbsRdbPredicates predicates(LOG_DB_TABLE_NAME);
314 predicates.Between(FoldEventTable::FIELD_HAPPEN_TIME, 0, static_cast<int64_t>(endTime));
315 predicates.OrderByDesc(FoldEventTable::FIELD_ID);
316 predicates.Limit(1);
317 auto resultSet = rdbStore_->Query(predicates, {FoldEventTable::FIELD_ID, FoldEventTable::FIELD_FOLD_STATUS});
318 if (resultSet == nullptr) {
319 HIVIEW_LOGE("resultSet is nullptr");
320 return 0;
321 }
322 int id = 0;
323 int status = 0;
324 if (resultSet->GoToNextRow() == NativeRdb::E_OK &&
325 GetIntFromResultSet(resultSet, FoldEventTable::FIELD_ID, id) &&
326 GetIntFromResultSet(resultSet, FoldEventTable::FIELD_FOLD_STATUS, status) == NativeRdb::E_OK) {
327 HIVIEW_LOGI("get handle seq: %{public}d, screen stat: %{public}d", id, status);
328 } else {
329 HIVIEW_LOGE("get handle seq and screen stat failed");
330 }
331 return status;
332 }
333
QueryStatisticEventsInPeriod(uint64_t startTime,uint64_t endTime,std::unordered_map<std::string,FoldAppUsageInfo> & infos)334 void FoldAppUsageDbHelper::QueryStatisticEventsInPeriod(uint64_t startTime, uint64_t endTime,
335 std::unordered_map<std::string, FoldAppUsageInfo> &infos)
336 {
337 std::lock_guard<std::mutex> lockGuard(dbMutex_);
338 if (rdbStore_ == nullptr) {
339 HIVIEW_LOGE("db is nullptr");
340 return;
341 }
342 std::string sqlCmd = "SELECT " + FoldEventTable::FIELD_BUNDLE_NAME + ", " + FoldEventTable::FIELD_VERSION_NAME +
343 ", SUM(" + FoldEventTable::FIELD_FOLD_PORTRAIT_DURATION + ") AS " +
344 FoldEventTable::FIELD_FOLD_PORTRAIT_DURATION +
345 ", SUM(" + FoldEventTable::FIELD_FOLD_LANDSCAPE_DURATION + ") AS " +
346 FoldEventTable::FIELD_FOLD_LANDSCAPE_DURATION +
347 ", SUM(" + FoldEventTable::FIELD_EXPAND_PORTRAIT_DURATION + ") AS " +
348 FoldEventTable::FIELD_EXPAND_PORTRAIT_DURATION +
349 ", SUM(" + FoldEventTable::FIELD_EXPAND_LANDSCAPE_DURATION + ") AS " +
350 FoldEventTable::FIELD_EXPAND_LANDSCAPE_DURATION +
351 ", COUNT(*) AS start_num FROM " + LOG_DB_TABLE_NAME + " WHERE " + FoldEventTable::FIELD_EVENT_ID + "=" +
352 std::to_string(FoldEventId::EVENT_COUNT_DURATION) + " AND " + FoldEventTable::FIELD_HAPPEN_TIME + " BETWEEN " +
353 std::to_string(startTime) + " AND " + std::to_string(endTime) +
354 " GROUP BY " + FoldEventTable::FIELD_BUNDLE_NAME + ", " + FoldEventTable::FIELD_VERSION_NAME;
355 auto resultSet = rdbStore_->QuerySql(sqlCmd);
356 if (resultSet == nullptr) {
357 HIVIEW_LOGE("resultSet is nullptr");
358 return;
359 }
360 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
361 FoldAppUsageInfo usageInfo;
362 if (GetStringFromResultSet(resultSet, FoldEventTable::FIELD_BUNDLE_NAME, usageInfo.package) &&
363 GetStringFromResultSet(resultSet, FoldEventTable::FIELD_VERSION_NAME, usageInfo.version) &&
364 GetIntFromResultSet(resultSet, FoldEventTable::FIELD_FOLD_PORTRAIT_DURATION, usageInfo.foldVer) &&
365 GetIntFromResultSet(resultSet, FoldEventTable::FIELD_FOLD_LANDSCAPE_DURATION, usageInfo.foldHor) &&
366 GetIntFromResultSet(resultSet, FoldEventTable::FIELD_EXPAND_PORTRAIT_DURATION, usageInfo.expdVer) &&
367 GetIntFromResultSet(resultSet, FoldEventTable::FIELD_EXPAND_LANDSCAPE_DURATION, usageInfo.expdHor) &&
368 GetIntFromResultSet(resultSet, "start_num", usageInfo.startNum)) {
369 infos[usageInfo.package + usageInfo.version] = usageInfo;
370 } else {
371 HIVIEW_LOGE("fail to get appusage info!");
372 }
373 }
374 }
375
QueryForegroundAppsInfo(uint64_t startTime,uint64_t endTime,int screenStatus,FoldAppUsageInfo & info)376 void FoldAppUsageDbHelper::QueryForegroundAppsInfo(uint64_t startTime, uint64_t endTime, int screenStatus,
377 FoldAppUsageInfo &info)
378 {
379 std::lock_guard<std::mutex> lockGuard(dbMutex_);
380 if (rdbStore_ == nullptr) {
381 HIVIEW_LOGE("db is nullptr");
382 return;
383 }
384 NativeRdb::AbsRdbPredicates predicates(LOG_DB_TABLE_NAME);
385 predicates.EqualTo(FoldEventTable::FIELD_BUNDLE_NAME, info.package);
386 predicates.Between(FoldEventTable::FIELD_HAPPEN_TIME, static_cast<int64_t>(startTime),
387 static_cast<int64_t>(endTime));
388 predicates.OrderByDesc(FoldEventTable::FIELD_ID);
389 auto resultSet = rdbStore_->Query(predicates, {FoldEventTable::FIELD_ID, FoldEventTable::FIELD_EVENT_ID,
390 FoldEventTable::FIELD_BUNDLE_NAME, FoldEventTable::FIELD_VERSION_NAME, FoldEventTable::FIELD_HAPPEN_TIME,
391 FoldEventTable::FIELD_FOLD_STATUS, FoldEventTable::FIELD_PRE_FOLD_STATUS, FoldEventTable::FIELD_TS});
392 if (resultSet == nullptr) {
393 HIVIEW_LOGE("resultSet is nullptr");
394 return;
395 }
396 std::vector<FoldAppUsageRawEvent> events;
397 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
398 FoldAppUsageRawEvent event;
399 if (!GetLongFromResultSet(resultSet, FoldEventTable::FIELD_ID, event.id) ||
400 !GetIntFromResultSet(resultSet, FoldEventTable::FIELD_EVENT_ID, event.rawId) ||
401 !GetStringFromResultSet(resultSet, FoldEventTable::FIELD_BUNDLE_NAME, event.package) ||
402 !GetStringFromResultSet(resultSet, FoldEventTable::FIELD_VERSION_NAME, event.version) ||
403 !GetLongFromResultSet(resultSet, FoldEventTable::FIELD_HAPPEN_TIME, event.happenTime) ||
404 !GetIntFromResultSet(resultSet, FoldEventTable::FIELD_FOLD_STATUS, event.screenStatusAfter) ||
405 !GetIntFromResultSet(resultSet, FoldEventTable::FIELD_PRE_FOLD_STATUS, event.screenStatusBefore) ||
406 !GetLongFromResultSet(resultSet, FoldEventTable::FIELD_TS, event.ts)) {
407 HIVIEW_LOGE("fail to get db event!");
408 return;
409 }
410 if (event.rawId != FoldEventId::EVENT_APP_START && event.rawId != FoldEventId::EVENT_SCREEN_STATUS_CHANGED) {
411 HIVIEW_LOGE("can not find foreground event, latest raw id: %{public}d", event.rawId);
412 return;
413 }
414 events.emplace_back(event);
415 if (event.rawId == FoldEventId::EVENT_APP_START) {
416 break;
417 }
418 }
419 info = CaculateForegroundAppUsage(events, startTime, endTime, info.package, screenStatus);
420 }
421
DeleteEventsByTime(uint64_t clearDataTime)422 int FoldAppUsageDbHelper::DeleteEventsByTime(uint64_t clearDataTime)
423 {
424 std::lock_guard<std::mutex> lockGuard(dbMutex_);
425 if (rdbStore_ == nullptr) {
426 HIVIEW_LOGE("db is nullptr");
427 return 0;
428 }
429 NativeRdb::AbsRdbPredicates predicates(LOG_DB_TABLE_NAME);
430 predicates.Between(FoldEventTable::FIELD_HAPPEN_TIME, 0, static_cast<int64_t>(clearDataTime));
431 int seq = 0;
432 int ret = rdbStore_->Delete(seq, predicates);
433 HIVIEW_LOGI("rows are deleted: %{public}d, ret: %{public}d", seq, ret);
434 return seq;
435 }
436
CaculateForegroundAppUsage(const std::vector<FoldAppUsageRawEvent> & events,uint64_t startTime,uint64_t endTime,const std::string & appName,int screenStatus)437 FoldAppUsageInfo FoldAppUsageDbHelper::CaculateForegroundAppUsage(const std::vector<FoldAppUsageRawEvent> &events,
438 uint64_t startTime, uint64_t endTime, const std::string &appName, int screenStatus)
439 {
440 FoldAppUsageInfo info;
441 info.package = appName;
442 // no event means: app is foreground for whole day.
443 if (events.size() == 0) {
444 UpdateScreenStatInfo(info, static_cast<uint32_t>(endTime - startTime), screenStatus);
445 return info;
446 }
447 uint32_t size = events.size();
448 // first event is screen changed, means app is started befor statistic period.
449 if (events[size - 1].rawId == FoldEventId::EVENT_SCREEN_STATUS_CHANGED) {
450 UpdateScreenStatInfo(info, static_cast<uint32_t>(events[size - 1].happenTime - startTime),
451 events[size - 1].screenStatusBefore);
452 }
453 // caculate all period between screen status changed events, till endTime.
454 for (uint32_t i = size - 1; i > 0; --i) {
455 if (events[i - 1].ts > events[i].ts) {
456 UpdateScreenStatInfo(info, static_cast<uint32_t>(events[i - 1].ts - events[i].ts),
457 events[i].screenStatusAfter);
458 }
459 }
460 UpdateScreenStatInfo(info, static_cast<uint32_t>(endTime - events[0].happenTime), events[0].screenStatusAfter);
461 return info;
462 }
463
QueryEventAfterEndTime(uint64_t endTime,uint64_t nowTime)464 std::vector<std::pair<int, std::string>> FoldAppUsageDbHelper::QueryEventAfterEndTime(
465 uint64_t endTime, uint64_t nowTime)
466 {
467 std::vector<std::pair<int, std::string>> retEvents = {};
468 std::lock_guard<std::mutex> lockGuard(dbMutex_);
469 if (rdbStore_ == nullptr) {
470 HIVIEW_LOGE("db is nullptr");
471 return retEvents;
472 }
473 NativeRdb::AbsRdbPredicates predicates(LOG_DB_TABLE_NAME);
474 predicates.Between(FoldEventTable::FIELD_HAPPEN_TIME, static_cast<int64_t>(endTime),
475 static_cast<int64_t>(nowTime))->BeginWrap()->
476 EqualTo(FoldEventTable::FIELD_EVENT_ID, FoldEventId::EVENT_APP_START)->Or()->
477 EqualTo(FoldEventTable::FIELD_EVENT_ID, FoldEventId::EVENT_APP_EXIT)->EndWrap();
478 predicates.OrderByDesc(FoldEventTable::FIELD_ID);
479 auto resultSet = rdbStore_->Query(predicates, { FoldEventTable::FIELD_EVENT_ID,
480 FoldEventTable::FIELD_BUNDLE_NAME});
481 if (resultSet == nullptr) {
482 HIVIEW_LOGE("resultSet is nullptr");
483 return retEvents;
484 }
485 while (resultSet->GoToNextRow() == NativeRdb::E_OK) {
486 std::pair<int, std::string> appSwitchEvent;
487 if (!GetIntFromResultSet(resultSet, FoldEventTable::FIELD_EVENT_ID, appSwitchEvent.first) ||
488 !GetStringFromResultSet(resultSet, FoldEventTable::FIELD_BUNDLE_NAME, appSwitchEvent.second)) {
489 continue;
490 }
491 retEvents.emplace_back(appSwitchEvent);
492 }
493 return retEvents;
494 }
495 } // namespace HiviewDFX
496 } // namespace OHOS