• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022-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 #include "usage_event_report_service.h"
16 
17 #include <algorithm>
18 #include <getopt.h>
19 
20 #include "app_usage_event_factory.h"
21 #include "hiview_logger.h"
22 #include "sys_usage_event_factory.h"
23 #include "time_util.h"
24 #include "usage_event_common.h"
25 
26 namespace OHOS {
27 namespace HiviewDFX {
28 DEFINE_LOG_TAG("HiView-UsageEventReportService");
29 using namespace SysUsageEventSpace;
30 using namespace SysUsageDbSpace;
31 namespace {
32 constexpr char ARG_SELECTION[] = "p:t:T:sSA";
33 constexpr char DEFAULT_WORK_PATH[] = "/data/log/hiview";
34 const std::string SYS_USAGE_KEYS[] = { KEY_OF_POWER, KEY_OF_RUNNING };
35 }
36 
UsageEventReportService()37 UsageEventReportService::UsageEventReportService() : workPath_(DEFAULT_WORK_PATH), lastReportTime_(0),
38     lastSysReportTime_(0)
39 {}
40 
InitWorkPath(const char * path)41 void UsageEventReportService::InitWorkPath(const char* path)
42 {
43     if (path == nullptr) {
44         HIVIEW_LOGE("invalid path, path is nullptr");
45         return;
46     }
47     char realPath[PATH_MAX] = { 0x00 };
48     if (strlen(path) >= PATH_MAX || realpath(path, realPath) == nullptr) {
49         HIVIEW_LOGE("invalid path, path does not exist");
50         return;
51     }
52     if (std::string realPathStr = realPath; realPathStr.rfind(DEFAULT_WORK_PATH, 0) != 0) {
53         HIVIEW_LOGE("invalid path, path should be in the hiview dir");
54         return;
55     }
56     workPath_ = realPath;
57 }
58 
ReportAppUsage()59 void UsageEventReportService::ReportAppUsage()
60 {
61     HIVIEW_LOGI("start to report app usage event");
62     auto factory = std::make_unique<AppUsageEventFactory>();
63     std::vector<std::unique_ptr<LoggerEvent>> events;
64     factory->Create(events);
65     HIVIEW_LOGI("report app usage event num: %{public}zu", events.size());
66     for (size_t i = 0; i < events.size(); ++i) {
67         events[i]->Report();
68     }
69 }
70 
ReportSysUsage()71 void UsageEventReportService::ReportSysUsage()
72 {
73     HIVIEW_LOGI("start to report sys usage event");
74     UsageEventCacher cacher(workPath_);
75     auto cacheUsage = cacher.GetSysUsageEvent();
76     if (cacheUsage == nullptr) {
77         HIVIEW_LOGE("failed to report sys usage event, cache is null");
78         return;
79     }
80     cacheUsage->Report();
81 
82     // after reporting, update cache_usage event to the db
83     cacheUsage->Update(KEY_OF_START, cacheUsage->GetValue(KEY_OF_END).GetUint64());
84     for (auto key : SYS_USAGE_KEYS) {
85         cacheUsage->Update(key, DEFAULT_UINT64);
86     }
87     cacher.SaveSysUsageEventToDb(cacheUsage);
88 }
89 
UpdateCacheSysUsage(std::shared_ptr<LoggerEvent> & cacheUsage,const UsageEventCacher & cacher)90 void UsageEventReportService::UpdateCacheSysUsage(std::shared_ptr<LoggerEvent>& cacheUsage,
91     const UsageEventCacher& cacher)
92 {
93     std::shared_ptr<LoggerEvent> nowUsage = std::make_unique<SysUsageEventFactory>()->Create();
94     auto lastUsage = cacher.GetSysUsageEvent(LAST_SYS_USAGE_TABLE);
95     for (auto key : SYS_USAGE_KEYS) {
96         uint64_t nowUsageTime = nowUsage->GetValue(key).GetUint64();
97         uint64_t lastUsageTime = lastUsage == nullptr ?  0 : lastUsage->GetValue(key).GetUint64();
98         uint64_t curUsageTime = nowUsageTime > lastUsageTime ? (nowUsageTime - lastUsageTime) : nowUsageTime;
99         cacheUsage->Update(key, curUsageTime + cacheUsage->GetValue(key).GetUint64());
100     }
101     cacheUsage->Update(KEY_OF_END, nowUsage->GetValue(KEY_OF_END).GetUint64());
102     UpdateLastSysUsage(nowUsage, cacher);
103 }
104 
UpdateLastSysUsage(std::shared_ptr<LoggerEvent> & nowUsage,const UsageEventCacher & cacher)105 void UsageEventReportService::UpdateLastSysUsage(std::shared_ptr<LoggerEvent>& nowUsage,
106     const UsageEventCacher& cacher)
107 {
108     nowUsage->Update(KEY_OF_START, lastReportTime_); // save the last report time for app_usage
109     cacher.SaveSysUsageEventToDb(nowUsage, LAST_SYS_USAGE_TABLE);
110 }
111 
SaveSysUsage()112 void UsageEventReportService::SaveSysUsage()
113 {
114     HIVIEW_LOGI("start to save sys usage event to db");
115     UsageEventCacher cacher(workPath_);
116     auto cacheUsage = cacher.GetSysUsageEvent();
117     if (cacheUsage == nullptr) {
118         // if it is the first save, set the current usage to the cache_usage
119         cacheUsage = std::make_unique<SysUsageEventFactory>()->Create();
120         UpdateLastSysUsage(cacheUsage, cacher);
121         cacheUsage->Update(KEY_OF_START, lastSysReportTime_);
122     } else {
123         // add the current usage to the cache_usage since the last save
124         UpdateCacheSysUsage(cacheUsage, cacher);
125     }
126     cacher.SaveSysUsageEventToDb(cacheUsage);
127 }
128 
ProcessArgsRequest(int argc,char * argv[])129 bool UsageEventReportService::ProcessArgsRequest(int argc, char* argv[])
130 {
131     if (argv == nullptr) {
132         return false;
133     }
134     int opt = 0;
135     while ((opt = getopt(argc, argv, ARG_SELECTION)) != -1) {
136         switch (opt) {
137             case 'p':
138                 InitWorkPath(optarg);
139                 break;
140             case 's':
141                 SaveSysUsage();
142                 break;
143             case 'A':
144                 ReportAppUsage();
145                 break;
146             case 'S':
147                 ReportSysUsage();
148                 break;
149             case 't':
150                 lastReportTime_ = strtoull(optarg, nullptr, 0);
151                 break;
152             case 'T':
153                 lastSysReportTime_ = strtoull(optarg, nullptr, 0);
154                 break;
155             default:
156                 break;
157         }
158     }
159     return true;
160 }
161 }  // namespace HiviewDFX
162 }  // namespace OHOS
163