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 #include "usage_event_report_service.h"
16
17 #include <algorithm>
18 #include <getopt.h>
19
20 #include "app_usage_event_factory.h"
21 #include "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 const std::string DEFAULT_WORK_PATH = "/data/log/hiview";
34 const std::string SYS_USAGE_KEYS[] = { KEY_OF_POWER, KEY_OF_RUNNING, KEY_OF_SCREEN };
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 for (size_t i = 0; i < events.size(); ++i) {
66 events[i]->Report();
67 HIVIEW_LOGI("report app usage event=%{public}s", events[i]->ToJsonString().c_str());
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_COLL);
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_COLL);
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