1 /*
2 * Copyright (C) 2021 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 <iostream>
16 #include <fstream>
17 #include <sstream>
18 #include <algorithm>
19 #include <unistd.h>
20 #include <dirent.h>
21 #include <cstdio>
22 #include <cstdlib>
23 #include <climits>
24 #include "sys/time.h"
25 #include "securec.h"
26 #include "include/sp_utils.h"
27 #define LARGE_BUFF_MAX_LEN (256)
28 namespace OHOS {
29 namespace SmartPerf {
FileAccess(const std::string & fileName)30 bool SPUtils::FileAccess(const std::string &fileName)
31 {
32 return (access(fileName.c_str(), F_OK) == 0);
33 }
34
LoadFile(const std::string & filePath,std::string & content)35 bool SPUtils::LoadFile(const std::string &filePath, std::string &content)
36 {
37 char realPath[PATH_MAX] = {0x00};
38 if (realpath(filePath.c_str(), realPath) == nullptr) {
39 std::cout << "" << std::endl;
40 }
41 std::ifstream file(realPath);
42 if (!file.is_open()) {
43 return false;
44 }
45
46 file.seekg(0, std::ios::end);
47 file.tellg();
48
49 content.clear();
50 file.seekg(0, std::ios::beg);
51 copy(std::istreambuf_iterator<char>(file), std::istreambuf_iterator<char>(), std::back_inserter(content));
52 // remove '' \n\r
53 ReplaceString(content);
54 return true;
55 }
56
LoadCmd(const std::string & cmd,std::string & result)57 bool SPUtils::LoadCmd(const std::string &cmd, std::string &result)
58 {
59 std::string cmdExc = cmd;
60 FILE *fd = popen(cmdExc.c_str(), "r");
61 if (fd == nullptr) {
62 return false;
63 }
64 char buf[1024] = {'\0'};
65 int ret = fread(buf, sizeof(buf), 1, fd);
66 if (ret >= 0) {
67 result = buf;
68 }
69 if (pclose(fd) == -1) {
70 std::cout << "" << std::endl;
71 }
72 // remove '' \n\r
73 ReplaceString(result);
74 return ret >= 0 ? true : false;
75 }
76
IncludePathDelimiter(const std::string & path)77 std::string SPUtils::IncludePathDelimiter(const std::string &path)
78 {
79 if (path.rfind("/") != path.size() - 1) {
80 return path + "/";
81 }
82
83 return path;
84 }
85
ForDirFiles(const std::string & path,std::vector<std::string> & files)86 void SPUtils::ForDirFiles(const std::string &path, std::vector<std::string> &files)
87 {
88 std::string pathStringWithDelimiter;
89 DIR *dir = opendir(path.c_str());
90 if (dir == nullptr) {
91 return;
92 }
93
94 while (true) {
95 struct dirent *ptr = readdir(dir);
96 if (ptr == nullptr) {
97 break;
98 }
99
100 // current dir OR parent dir
101 if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0)) {
102 continue;
103 } else if (ptr->d_type == DT_DIR) {
104 pathStringWithDelimiter = IncludePathDelimiter(path) + std::string(ptr->d_name);
105 ForDirFiles(pathStringWithDelimiter, files);
106 } else {
107 files.push_back(IncludePathDelimiter(path) + std::string(ptr->d_name));
108 }
109 }
110 closedir(dir);
111 }
112
IsSubString(const std::string & str,const std::string & sub)113 bool SPUtils::IsSubString(const std::string &str, const std::string &sub)
114 {
115 if (sub.empty() || str.empty()) {
116 return false;
117 }
118
119 return str.find(sub) != std::string::npos;
120 }
121
StrSplit(const std::string & content,const std::string & sp,std::vector<std::string> & out)122 void SPUtils::StrSplit(const std::string &content, const std::string &sp, std::vector<std::string> &out)
123 {
124 size_t index = 0;
125 while (index != std::string::npos) {
126 size_t tEnd = content.find_first_of(sp, index);
127 std::string tmp = content.substr(index, tEnd - index);
128 if (tmp != "" && tmp != " ") {
129 out.push_back(tmp);
130 }
131 if (tEnd == std::string::npos) {
132 break;
133 }
134 index = tEnd + 1;
135 }
136 }
137
ExtractNumber(const std::string & str)138 std::string SPUtils::ExtractNumber(const std::string &str)
139 {
140 int cntInt = 0;
141 const int shift = 10;
142 for (int i = 0; str[i] != '\0'; ++i) {
143 if (str[i] >= '0' && str[i] <= '9') {
144 cntInt *= shift;
145 cntInt += str[i] - '0';
146 }
147 }
148 return std::to_string(cntInt);
149 }
150
ReplaceString(std::string & res)151 void SPUtils::ReplaceString(std::string &res)
152 {
153 std::string flagOne = "\r";
154 std::string flagTwo = "\n";
155 std::string::size_type ret = res.find(flagOne);
156 while (ret != res.npos) {
157 res.replace(ret, 1, "");
158 ret = res.find(flagOne);
159 }
160 ret = res.find(flagTwo);
161 while (ret != res.npos) {
162 res.replace(ret, 1, "");
163 ret = res.find(flagTwo);
164 }
165 }
166
GetCurTime()167 long long SPUtils::GetCurTime()
168 {
169 struct timeval tv;
170 gettimeofday(&tv, nullptr);
171 long long timestamp = tv.tv_sec * 1000 + tv.tv_usec / 1000;
172 return timestamp;
173 }
174
GetTopPkgName()175 std::string SPUtils::GetTopPkgName()
176 {
177 std::string cmd = "hidumper -s AbilityManagerService -a '-a' | grep 'bundle name' | head -n 1";
178 std::string curTopPkgStr = "";
179 LoadCmd(cmd, curTopPkgStr);
180 uint64_t left = curTopPkgStr.find_first_of("[");
181 uint64_t right = curTopPkgStr.find_first_of("]");
182 std::string topPkg = curTopPkgStr.substr(left + 1, right - left - 1);
183 return topPkg;
184 }
185
GetSplitOne(std::string cmd)186 static std::string GetSplitOne(std::string cmd)
187 {
188 std::string result;
189 SPUtils::LoadCmd(cmd, result);
190 std::vector<std::string> splitStrings;
191 SPUtils::StrSplit(result, "=", splitStrings);
192 return splitStrings[1];
193 }
194
GetDeviceInfo()195 std::map<std::string, std::string> SPUtils::GetDeviceInfo()
196 {
197 std::map<std::string, std::string> resultMap;
198 std::string sn = GetSplitOne("param get |grep ohos.boot.sn");
199 std::string deviceTypeName = GetSplitOne("param get |grep ohos.boot.hardware");
200 std::string brand = GetSplitOne("param get |grep const.product.brand");
201 std::string version = GetSplitOne("param get |grep const.product.software.version");
202 resultMap["sn"] = sn;
203 resultMap["deviceTypeName"] = deviceTypeName;
204 resultMap["brand"] = brand;
205 resultMap["board"] = "hw";
206 resultMap["version"] = version;
207 return resultMap;
208 }
GetCpuInfo()209 std::map<std::string, std::string> SPUtils::GetCpuInfo()
210 {
211 std::vector<std::string> policyFiles;
212 std::map<std::string, std::string> resultMap;
213 std::string basePath = "/sys/devices/system/cpu/cpufreq/";
214 std::cout << "policyFiles size:" << policyFiles.size() << std::endl;
215 DIR *dir = opendir(basePath.c_str());
216 if (dir == nullptr) {
217 return resultMap;
218 }
219 while (true) {
220 struct dirent *ptr = readdir(dir);
221 if (ptr == nullptr) {
222 break;
223 }
224 if ((strcmp(ptr->d_name, ".") == 0) || (strcmp(ptr->d_name, "..") == 0)) {
225 continue;
226 }
227 policyFiles.push_back(IncludePathDelimiter(basePath) + std::string(ptr->d_name));
228 }
229 for (size_t i = 0; i < policyFiles.size(); i++) {
230 std::string cpus;
231 LoadFile(policyFiles[i] + "/affected_cpus", cpus);
232 std::string max;
233 LoadFile(policyFiles[i] + "/cpuinfo_max_freq", max);
234 std::string min;
235 LoadFile(policyFiles[i] + "/cpuinfo_min_freq", min);
236 std::string nameBase = "cpu-c" + std::to_string(i + 1) + "-";
237 resultMap[nameBase + "cluster"] = cpus;
238 resultMap[nameBase + "max"] = max;
239 resultMap[nameBase + "min"] = min;
240 }
241 return resultMap;
242 }
GetGpuInfo()243 std::map<std::string, std::string> SPUtils::GetGpuInfo()
244 {
245 const std::vector<std::string> gpuCurFreqPaths = {
246 "/sys/class/devfreq/fde60000.gpu/",
247 "/sys/class/devfreq/gpufreq/",
248 };
249 std::map<std::string, std::string> resultMap;
250 for (auto path : gpuCurFreqPaths) {
251 if (FileAccess(path)) {
252 std::string max;
253 SPUtils::LoadFile(path + "/max_freq", max);
254 std::string min;
255 SPUtils::LoadFile(path + "/min_freq", min);
256 resultMap["gpu_max_freq"] = max;
257 resultMap["gpu_min_freq"] = min;
258 }
259 }
260 return resultMap;
261 }
GetNetwork()262 std::map<std::string, std::string> SPUtils::GetNetwork()
263 {
264 std::cout << "GetNetwork is called" << std::endl;
265 std::map<std::string, std::string> result;
266 long long allTx = 0;
267 long long allRx = 0;
268 long long curTx = 0;
269 long long curRx = 0;
270 char buff[LARGE_BUFF_MAX_LEN];
271 FILE *fp = fopen("/proc/net/dev", "r");
272 if (fp == nullptr) {
273 std::cout << "net work node is not accessed" << std::endl;
274 return result;
275 } else {
276 std::cout << "net work node is accessed" << std::endl;
277 }
278 while (fgets(buff, LARGE_BUFF_MAX_LEN, fp)) {
279 if (strstr(buff, "rmnet") || strstr(buff, "eth") || strstr(buff, "wlan")) {
280 if (sscanf_s(buff, "%*s%llu%*llu%*llu%*llu%*llu%*llu%*llu%*llu%llu%*llu%*llu%*llu%*llu%*llu%*llu%*llu",
281 &curRx, &curTx) < 0) {
282 return result;
283 }
284 allTx += curTx;
285 allRx += curRx;
286 }
287 }
288 fclose(fp);
289 result["networkUp"] = std::to_string(allTx);
290 result["networkDown"] = std::to_string(allRx);
291 return result;
292 }
293 }
294 }
295